@istar-ts/core 0.10.1 → 0.12.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/README.md CHANGED
@@ -251,6 +251,68 @@ rather than writing a type that can't be read back.
251
251
 
252
252
  See [docs/metamodel-extensions.md](../../docs/metamodel-extensions.md) for the design.
253
253
 
254
+ ## A model's own metamodel
255
+
256
+ A file can declare the constructs it adds to iStar in a top-level `"metamodel"` block, so they
257
+ travel with the model. piStar-ext's "Add new" keeps them only in the browser's localStorage. The
258
+ block has the shape `extendMetamodel` takes, as JSON: no `check` predicates, and presentation hints
259
+ (`shape`, `textBox`, `line`), which `@istar-ts/react` draws.
260
+
261
+ ```json
262
+ "metamodel": {
263
+ "name": "iStar4RationalAgents",
264
+ "elements": [
265
+ { "kind": "ra4.Planning", "behavesLike": "istar.Task", "pistarType": "istar.Planning",
266
+ "shape": { "path": "M 0 0 L 80 0 L 100 20 L 80 40 L 0 40 L 14 20 Z" } },
267
+ { "kind": "ra4.Plan", "category": "node" }
268
+ ],
269
+ "links": [
270
+ { "kind": "ra4.GeneratesLink", "label": "Generates",
271
+ "rules": { "sources": ["ra4.Planning"], "targets": ["ra4.Plan"] }, "line": { "dash": "1,3" } }
272
+ ]
273
+ }
274
+ ```
275
+
276
+ ```ts
277
+ import { fileMetamodelOf, parsePistar, toPistar, withFileMetamodel } from '@istar-ts/core';
278
+
279
+ // Read: the file's constructs extend `metamodel` (iStar 2.0 by default) before parsing.
280
+ const model = parsePistar(text, { fileMetamodel: true, metamodel: hostMetamodel });
281
+
282
+ fileMetamodelOf(model); // the block (only the file's constructs, never the host's)
283
+
284
+ // "Add new": constructs added at run time join the file and are written with it.
285
+ const extended = withFileMetamodel(model, { ...fileMetamodelOf(model)!, elements: [...] });
286
+ toPistar(extended); // writes the "metamodel" block
287
+ ```
288
+
289
+ - **Opt-in.** Without `fileMetamodel: true`, the block is kept as an unknown key and not applied, as
290
+ before, so no existing caller changes.
291
+ - **Collisions throw `MetamodelError`, naming the kind:**
292
+ - a kind or `pistarType` the base or host metamodel already has;
293
+ - the reserved `istar.` prefix;
294
+ - a kind declared twice in the block.
295
+
296
+ `validateFileMetamodel(block)` reports malformed blocks with their path
297
+ (`metamodel.elements[1].kind must be a string`).
298
+
299
+ - **Round trip.** The block is written back exactly as read, including keys this library doesn't
300
+ know (hosts keep dialect data, such as stereotypes or groupers, beside it). A model without one
301
+ writes none.
302
+ - **`withFileMetamodel(model, block | null)`** replaces the file's constructs (or removes them with
303
+ `null`). It keeps the host's, and refuses to drop a kind the model still uses. Load the result
304
+ into a store (`store.load` or `store.replace`) to keep editing.
305
+ - `pistarType` works as for any extension, so `istar.<Name>` types on disk still read.
306
+
307
+ ## Diagnostics
308
+
309
+ `GoalDiagnostic` (`{ elementId, key?, severity, message, source?, range?, code?, data? }`) is the
310
+ data shape for findings about elements and links. Analysers publish them per source to a
311
+ `createDiagnosticsStore()`; `getAll()` returns the union of every source, deduplicated by
312
+ `(elementId, key, message)`. `fromLspDiagnostics` and `fromNodeIdDiagnostics` adapt LSP and MutRoSe
313
+ diagnostics. Diagnostics are never part of the model and never serialized. `@istar-ts/react`
314
+ shows them as badges and in the inspector (see its README).
315
+
254
316
  ## Credits
255
317
 
256
318
  The metamodel, link constraints, element shapes, and file format are derived from