@istar-ts/core 0.6.0 → 0.8.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 +77 -0
- package/dist/index.cjs +548 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -95
- package/dist/index.d.ts +329 -95
- package/dist/index.js +534 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -68,6 +68,212 @@ export declare function isContributionLabel(value: string): value is Contributio
|
|
|
68
68
|
/** `'istar.Goal'` → `'Goal'` */
|
|
69
69
|
export declare function shortKindName(kind: ElementKind | LinkKind): string;
|
|
70
70
|
//#endregion
|
|
71
|
+
//#region src/constraints.d.ts
|
|
72
|
+
export type ConstraintCode = "unknown-element" | "unknown-link-kind" | "invalid-source" | "invalid-target" | "actor-types-differ" | "self-link" | "duplicate-link" | "dependum-endpoint" | "same-actor" | "different-actors" | "refined-depender" | "contributed-depender" | "depender-target" | "mixed-refinement" | "contribution-and-qualification";
|
|
73
|
+
export type LinkCheck = {
|
|
74
|
+
ok: true;
|
|
75
|
+
} | {
|
|
76
|
+
ok: false;
|
|
77
|
+
reason: string;
|
|
78
|
+
code: ConstraintCode;
|
|
79
|
+
};
|
|
80
|
+
export interface CanLinkOptions<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
81
|
+
/** Default: the model's metamodel, or iStar 2.0. */
|
|
82
|
+
readonly metamodel?: Metamodel<EK, LK>;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Checks whether a link of `kind` may be added from `source` to `target` in `model`.
|
|
86
|
+
*
|
|
87
|
+
* For dependency links, `source` is the depender and `target` the dependee (an actor or one of
|
|
88
|
+
* its inner elements); the dependum sits between them and is not part of the check.
|
|
89
|
+
*
|
|
90
|
+
* Extended kinds (see `extendMetamodel`) are checked with the rules of the kind they behave
|
|
91
|
+
* like, or with their declarative rules, then with their extra predicate.
|
|
92
|
+
*/
|
|
93
|
+
export declare function canLink<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, source: string | IstarElement<EK>, target: string | IstarElement<EK>, kind: LK, options?: CanLinkOptions<EK, LK>): LinkCheck;
|
|
94
|
+
/**
|
|
95
|
+
* What an extension's `check` predicate receives: the model, the endpoints, and the graph
|
|
96
|
+
* queries the iStar 2.0 rules use.
|
|
97
|
+
*/
|
|
98
|
+
export interface LinkRuleContext {
|
|
99
|
+
readonly model: AnyIstarModel;
|
|
100
|
+
readonly metamodel: AnyMetamodel;
|
|
101
|
+
/** The link kind being added. */
|
|
102
|
+
readonly kind: string;
|
|
103
|
+
readonly source: IstarElement<string>;
|
|
104
|
+
readonly target: IstarElement<string>;
|
|
105
|
+
/** A link (optionally of `kind`, or a kind behaving like it) joins `a` and `b`, either way. */
|
|
106
|
+
isThereLinkBetween(a: IstarElement<string>, b: IstarElement<string>, kind?: string): boolean;
|
|
107
|
+
/** `element` is the source of a link of `kind` (or a kind behaving like it). */
|
|
108
|
+
isSourceOfType(element: IstarElement<string>, kind: string): boolean;
|
|
109
|
+
/** `element` is the target of a link of `kind` (or a kind behaving like it). */
|
|
110
|
+
isTargetOfType(element: IstarElement<string>, kind: string): boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface ModelIssue<LK extends string = LinkKind> {
|
|
113
|
+
readonly linkId: string;
|
|
114
|
+
readonly kind: LK;
|
|
115
|
+
readonly source: string;
|
|
116
|
+
readonly target: string;
|
|
117
|
+
readonly code: ConstraintCode;
|
|
118
|
+
readonly message: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Re-validates every link of a model, the way piStar does when loading a file: dependencies
|
|
122
|
+
* first (each checked before its own links are added), then the remaining links in file
|
|
123
|
+
* order, each against the graph built so far. Invalid links are reported, not removed.
|
|
124
|
+
*/
|
|
125
|
+
export declare function validateModel<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, options?: CanLinkOptions<EK, LK>): ModelIssue<LK>[];
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/metamodels.d.ts
|
|
128
|
+
export type ElementCategory = "actor" | "node";
|
|
129
|
+
export type LinkCategory = "actor" | "node" | "dependency";
|
|
130
|
+
/** A resolved element kind of a metamodel. */
|
|
131
|
+
export interface ElementKindDefinition<K extends string = string> {
|
|
132
|
+
readonly kind: K;
|
|
133
|
+
readonly category: ElementCategory;
|
|
134
|
+
/** Human-readable name, e.g. "Goal" or "Planning". */
|
|
135
|
+
readonly label: string;
|
|
136
|
+
/** Default size; for actors the initial boundary size. */
|
|
137
|
+
readonly size: Size;
|
|
138
|
+
/** Containment rules (nodes only; actors have none). */
|
|
139
|
+
readonly info?: NodeKindInfo;
|
|
140
|
+
/** The kind whose link rules this kind follows (built-in kinds have none). */
|
|
141
|
+
readonly behavesLike?: string;
|
|
142
|
+
/** The `type` written in piStar files. Equal to `kind` unless declared otherwise. */
|
|
143
|
+
readonly pistarType: string;
|
|
144
|
+
/** Name of the extension that declared it; absent for iStar 2.0 kinds. */
|
|
145
|
+
readonly extension?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Declarative link rules, as piStar-ext's "Create a new Construct" dialog collects them:
|
|
149
|
+
* which kinds may be the source and target. Entries are kind names (`istar.Goal`,
|
|
150
|
+
* `rationalAgents.Plan`) or categories (`node`, `actor`, `*`). A kind name also matches kinds
|
|
151
|
+
* that behave like it, so `istar.Task` accepts a Planning that behaves like a Task.
|
|
152
|
+
*/
|
|
153
|
+
export interface LinkRules {
|
|
154
|
+
readonly sources: readonly string[];
|
|
155
|
+
readonly targets: readonly string[];
|
|
156
|
+
/**
|
|
157
|
+
* Source and target must belong to the same actor (iStar 2.0 Guide, page 14). Default true
|
|
158
|
+
* for node links, ignored for actor links.
|
|
159
|
+
*/
|
|
160
|
+
readonly sameActor?: boolean;
|
|
161
|
+
/** Allow a dependum as source or target. Default false. */
|
|
162
|
+
readonly allowDependum?: boolean;
|
|
163
|
+
/** Allow a link from an element onto itself. Default false. */
|
|
164
|
+
readonly allowSelf?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* At most one link `'kind'` of this kind, or `'any'` link at all, between the same two
|
|
167
|
+
* elements (in either direction); `false` for no limit. Default `'kind'`.
|
|
168
|
+
*/
|
|
169
|
+
readonly unique?: "kind" | "any" | false;
|
|
170
|
+
}
|
|
171
|
+
/** A resolved link kind of a metamodel. */
|
|
172
|
+
export interface LinkKindDefinition<K extends string = string> {
|
|
173
|
+
readonly kind: K;
|
|
174
|
+
readonly category: LinkCategory;
|
|
175
|
+
readonly label: string;
|
|
176
|
+
readonly info: LinkKindInfo;
|
|
177
|
+
/** The link kind whose rules (and meaning, for other rules) this kind takes on. */
|
|
178
|
+
readonly behavesLike?: string;
|
|
179
|
+
/** Declarative rules, for link kinds that don't behave like another kind. */
|
|
180
|
+
readonly rules?: LinkRules;
|
|
181
|
+
/** An extra predicate, checked after the inherited or declarative rules pass. */
|
|
182
|
+
readonly check?: (context: LinkRuleContext) => LinkCheck;
|
|
183
|
+
readonly pistarType: string;
|
|
184
|
+
readonly extension?: string;
|
|
185
|
+
}
|
|
186
|
+
/** A metamodel: the element and link kinds a model may use, and their rules. */
|
|
187
|
+
export interface Metamodel<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
188
|
+
/** `istar-2.0`, followed by the names of the extensions applied, e.g. `istar-2.0+rationalAgents`. */
|
|
189
|
+
readonly name: string;
|
|
190
|
+
readonly extensions: readonly string[];
|
|
191
|
+
/** In declaration order: iStar 2.0 kinds first, then each extension's. */
|
|
192
|
+
readonly elements: ReadonlyMap<EK, ElementKindDefinition<EK>>;
|
|
193
|
+
readonly links: ReadonlyMap<LK, LinkKindDefinition<LK>>;
|
|
194
|
+
/** `type` in piStar files → kind. */
|
|
195
|
+
readonly elementsByPistarType: ReadonlyMap<string, EK>;
|
|
196
|
+
readonly linksByPistarType: ReadonlyMap<string, LK>;
|
|
197
|
+
}
|
|
198
|
+
/** The kinds of a metamodel, as type-level unions. */
|
|
199
|
+
export type ElementKindOf<M> = M extends Metamodel<infer EK, string> ? EK : never;
|
|
200
|
+
export type LinkKindOf<M> = M extends Metamodel<string, infer LK> ? LK : never;
|
|
201
|
+
/** A metamodel of any dialect, for code that handles every kind generically. */
|
|
202
|
+
export type AnyMetamodel = Metamodel<string, string>;
|
|
203
|
+
/** iStar 2.0, as the piStar tool implements it. The default metamodel everywhere. */
|
|
204
|
+
export declare const ISTAR_2_0: Metamodel;
|
|
205
|
+
export interface ElementKindDeclaration<K extends string = string> {
|
|
206
|
+
/** Namespaced kind name, e.g. `rationalAgents.Planning`. */
|
|
207
|
+
readonly kind: K;
|
|
208
|
+
/** Default: the part after the namespace ("Planning"). */
|
|
209
|
+
readonly label?: string;
|
|
210
|
+
/** Required unless `behavesLike` is given (then it is the same category). */
|
|
211
|
+
readonly category?: ElementCategory;
|
|
212
|
+
/** An existing element kind whose link rules this kind follows, e.g. `istar.Task`. */
|
|
213
|
+
readonly behavesLike?: string;
|
|
214
|
+
/** Containment rules for nodes. Default: those of `behavesLike`, else piStar-ext's (inner, dependum). */
|
|
215
|
+
readonly info?: Partial<NodeKindInfo>;
|
|
216
|
+
/** Default: that of `behavesLike`, else piStar-ext's 90×55 for nodes and 200×120 for actors. */
|
|
217
|
+
readonly size?: Size;
|
|
218
|
+
/**
|
|
219
|
+
* The `type` used in piStar files, when it differs from `kind`. piStar-ext saves its new
|
|
220
|
+
* constructs as `istar.<Name>`, so `pistarType: 'istar.Planning'` reads its files.
|
|
221
|
+
*/
|
|
222
|
+
readonly pistarType?: string;
|
|
223
|
+
}
|
|
224
|
+
export interface LinkKindDeclaration<K extends string = string> {
|
|
225
|
+
readonly kind: K;
|
|
226
|
+
readonly label?: string;
|
|
227
|
+
/** Default: that of `behavesLike`, else `node`. */
|
|
228
|
+
readonly category?: LinkCategory;
|
|
229
|
+
/** An existing link kind whose rules this kind takes on, e.g. `istar.OrRefinementLink`. */
|
|
230
|
+
readonly behavesLike?: string;
|
|
231
|
+
/** Declarative rules; give these or `behavesLike`, not both. */
|
|
232
|
+
readonly rules?: LinkRules;
|
|
233
|
+
/** An extra predicate, checked after the other rules pass. */
|
|
234
|
+
readonly check?: (context: LinkRuleContext) => LinkCheck;
|
|
235
|
+
/** Default: that of `behavesLike`, else none (no fixed label, no changeable value). */
|
|
236
|
+
readonly info?: LinkKindInfo;
|
|
237
|
+
readonly pistarType?: string;
|
|
238
|
+
}
|
|
239
|
+
/** A named set of new kinds, applied to a metamodel with `extendMetamodel`. */
|
|
240
|
+
export interface MetamodelExtension<NEK extends string = string, NLK extends string = string> {
|
|
241
|
+
/** Identifies the extension, e.g. `rationalAgents`. */
|
|
242
|
+
readonly name: string;
|
|
243
|
+
readonly elements?: readonly ElementKindDeclaration<NEK>[];
|
|
244
|
+
readonly links?: readonly LinkKindDeclaration<NLK>[];
|
|
245
|
+
}
|
|
246
|
+
export declare class MetamodelError extends Error {
|
|
247
|
+
override name: string;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Declares an extension, keeping its kind names as literal types (so `extendMetamodel` can
|
|
251
|
+
* type the result). Identity at runtime.
|
|
252
|
+
*/
|
|
253
|
+
export declare function defineMetamodelExtension<const NEK extends string = never, const NLK extends string = never>(extension: MetamodelExtension<NEK, NLK>): MetamodelExtension<NEK, NLK>;
|
|
254
|
+
/**
|
|
255
|
+
* Returns a new metamodel with the extension's kinds added. `base` is not modified.
|
|
256
|
+
*
|
|
257
|
+
* Throws `MetamodelError` when a kind name isn't namespaced, uses the reserved `istar.`
|
|
258
|
+
* prefix, collides with an existing kind or piStar type, or refers to an unknown kind.
|
|
259
|
+
*/
|
|
260
|
+
export declare function extendMetamodel<EK extends string, LK extends string, const NEK extends string = never, const NLK extends string = never>(base: Metamodel<EK, LK>, extension: MetamodelExtension<NEK, NLK>): Metamodel<EK | NEK, LK | NLK>;
|
|
261
|
+
export declare function elementKindDefinition(metamodel: AnyMetamodel, kind: string): ElementKindDefinition | undefined;
|
|
262
|
+
export declare function linkKindDefinition(metamodel: AnyMetamodel, kind: string): LinkKindDefinition | undefined;
|
|
263
|
+
/** True for actor-category kinds (Actor, Agent, Role and extensions behaving like them). */
|
|
264
|
+
export declare function isActorKindIn(metamodel: AnyMetamodel, kind: string): boolean;
|
|
265
|
+
/** True for node-category kinds (intentional elements, built-in or extended). */
|
|
266
|
+
export declare function isNodeKindIn(metamodel: AnyMetamodel, kind: string): boolean;
|
|
267
|
+
/**
|
|
268
|
+
* The built-in (or rule-carrying) kind an element kind ultimately behaves like: `istar.Task`
|
|
269
|
+
* for a Planning that behaves like a Task; the kind itself when it behaves like nothing.
|
|
270
|
+
*/
|
|
271
|
+
export declare function effectiveElementKind(metamodel: AnyMetamodel, kind: string): string;
|
|
272
|
+
/** Like `effectiveElementKind`, for link kinds. */
|
|
273
|
+
export declare function effectiveLinkKind(metamodel: AnyMetamodel, kind: string): string;
|
|
274
|
+
/** True when `kind` is `ancestor` or (transitively) behaves like it. */
|
|
275
|
+
export declare function elementBehavesLike(metamodel: AnyMetamodel, kind: string, ancestor: string): boolean;
|
|
276
|
+
//#endregion
|
|
71
277
|
//#region src/model.d.ts
|
|
72
278
|
/**
|
|
73
279
|
* piStar stores every custom property value as a string (e.g. `"initialValue": "false"`).
|
|
@@ -94,7 +300,11 @@ export interface LinkDisplay {
|
|
|
94
300
|
readonly vertices?: readonly Point[];
|
|
95
301
|
readonly [key: string]: unknown;
|
|
96
302
|
}
|
|
97
|
-
|
|
303
|
+
/**
|
|
304
|
+
* An element of the model. `K` is the kind union: iStar 2.0's by default, wider for models of an
|
|
305
|
+
* extended metamodel (see `extendMetamodel`).
|
|
306
|
+
*/
|
|
307
|
+
export interface IstarElement<K extends string = ElementKind> {
|
|
98
308
|
readonly id: string;
|
|
99
309
|
readonly kind: K;
|
|
100
310
|
/** The element's label; `text` in the save file. */
|
|
@@ -120,7 +330,7 @@ export interface IstarElement<K extends ElementKind = ElementKind> {
|
|
|
120
330
|
}
|
|
121
331
|
export type IstarActor = IstarElement<ActorKind>;
|
|
122
332
|
export type IstarNode = IstarElement<NodeKind>;
|
|
123
|
-
export interface IstarLink<K extends
|
|
333
|
+
export interface IstarLink<K extends string = LinkKind> {
|
|
124
334
|
readonly id: string;
|
|
125
335
|
readonly kind: K;
|
|
126
336
|
readonly source: string;
|
|
@@ -142,10 +352,12 @@ export interface Diagram {
|
|
|
142
352
|
/**
|
|
143
353
|
* An immutable iStar model. Maps preserve insertion order, which is the order elements and
|
|
144
354
|
* links are written back to disk.
|
|
355
|
+
*
|
|
356
|
+
* `EK`/`LK` are the element and link kind unions; they default to iStar 2.0's.
|
|
145
357
|
*/
|
|
146
|
-
export interface IstarModel {
|
|
147
|
-
readonly elements: ReadonlyMap<string, IstarElement
|
|
148
|
-
readonly links: ReadonlyMap<string, IstarLink
|
|
358
|
+
export interface IstarModel<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
359
|
+
readonly elements: ReadonlyMap<string, IstarElement<EK>>;
|
|
360
|
+
readonly links: ReadonlyMap<string, IstarLink<LK>>;
|
|
149
361
|
readonly diagram?: Diagram;
|
|
150
362
|
readonly tool?: string;
|
|
151
363
|
readonly istar?: string;
|
|
@@ -159,51 +371,39 @@ export interface IstarModel {
|
|
|
159
371
|
export declare const PISTAR_TOOL = "pistar.2.1.0";
|
|
160
372
|
export declare const ISTAR_VERSION = "2.0";
|
|
161
373
|
export declare const DEFAULT_DIAGRAM: Diagram;
|
|
374
|
+
/** A model of any dialect, for code that handles every kind generically. */
|
|
375
|
+
export type AnyIstarModel = IstarModel<string, string>;
|
|
376
|
+
/**
|
|
377
|
+
* Associates `metamodel` with `model` and returns the same model, typed for it. Use when a
|
|
378
|
+
* model was built without the library's operations (e.g. with an object spread), which loses
|
|
379
|
+
* the association.
|
|
380
|
+
*/
|
|
381
|
+
export declare function withMetamodel<EK extends string, LK extends string>(model: IstarModel<string, string>, metamodel: Metamodel<EK, LK>): IstarModel<EK, LK>;
|
|
382
|
+
/** Gives `to` the metamodel of `from` (used for every model an operation derives). */
|
|
383
|
+
export declare function inheritMetamodel<M extends IstarModel<string, string>>(from: IstarModel<string, string>, to: M): M;
|
|
384
|
+
export declare function createEmptyModel<EK extends string, LK extends string>(diagram: Diagram | undefined, options: {
|
|
385
|
+
metamodel: Metamodel<EK, LK>;
|
|
386
|
+
}): IstarModel<EK, LK>;
|
|
162
387
|
export declare function createEmptyModel(diagram?: Diagram): IstarModel;
|
|
163
|
-
|
|
164
|
-
|
|
388
|
+
/**
|
|
389
|
+
* The metamodel a model was read or created with (see `parsePistar`, `createEmptyModel`), or
|
|
390
|
+
* iStar 2.0. Constraints, operations and serialization use it unless given another one.
|
|
391
|
+
*/
|
|
392
|
+
export declare function metamodelOf<EK extends string, LK extends string>(model: IstarModel<EK, LK>): Metamodel<EK, LK>;
|
|
393
|
+
/** True for actor-category elements; pass the metamodel for extended actor kinds. */
|
|
394
|
+
export declare function isActor(element: IstarElement<string> | undefined, metamodel?: AnyMetamodel): element is IstarActor;
|
|
395
|
+
/** True for node-category elements; pass the metamodel for extended node kinds. */
|
|
396
|
+
export declare function isNode(element: IstarElement<string> | undefined, metamodel?: AnyMetamodel): element is IstarNode;
|
|
165
397
|
/** Inner elements of an actor, in model order. */
|
|
166
|
-
export declare function childrenOf(model: IstarModel, actorId: string): IstarElement[];
|
|
398
|
+
export declare function childrenOf<EK extends string, LK extends string>(model: IstarModel<EK, LK>, actorId: string): IstarElement<EK>[];
|
|
167
399
|
/** Links that have the element as source or target. */
|
|
168
|
-
export declare function linksOf(model: IstarModel, elementId: string): IstarLink[];
|
|
400
|
+
export declare function linksOf<EK extends string, LK extends string>(model: IstarModel<EK, LK>, elementId: string): IstarLink<LK>[];
|
|
169
401
|
/** For a dependum, the two halves of its dependency: depender → dependum → dependee. */
|
|
170
|
-
export declare function dependencyLinksOf(model: IstarModel, dependumId: string): {
|
|
171
|
-
inbound?: IstarLink
|
|
172
|
-
outbound?: IstarLink
|
|
402
|
+
export declare function dependencyLinksOf<EK extends string, LK extends string>(model: IstarModel<EK, LK>, dependumId: string): {
|
|
403
|
+
inbound?: IstarLink<LK>;
|
|
404
|
+
outbound?: IstarLink<LK>;
|
|
173
405
|
};
|
|
174
406
|
//#endregion
|
|
175
|
-
//#region src/constraints.d.ts
|
|
176
|
-
export type ConstraintCode = "unknown-element" | "unknown-link-kind" | "invalid-source" | "invalid-target" | "actor-types-differ" | "self-link" | "duplicate-link" | "dependum-endpoint" | "same-actor" | "different-actors" | "refined-depender" | "contributed-depender" | "depender-target" | "mixed-refinement" | "contribution-and-qualification";
|
|
177
|
-
export type LinkCheck = {
|
|
178
|
-
ok: true;
|
|
179
|
-
} | {
|
|
180
|
-
ok: false;
|
|
181
|
-
reason: string;
|
|
182
|
-
code: ConstraintCode;
|
|
183
|
-
};
|
|
184
|
-
type ElementRef = string | IstarElement;
|
|
185
|
-
/**
|
|
186
|
-
* Checks whether a link of `kind` may be added from `source` to `target` in `model`.
|
|
187
|
-
*
|
|
188
|
-
* For `istar.DependencyLink`, `source` is the depender and `target` the dependee (an actor or
|
|
189
|
-
* one of its inner elements); the dependum sits between them and is not part of the check.
|
|
190
|
-
*/
|
|
191
|
-
export declare function canLink(model: IstarModel, source: ElementRef, target: ElementRef, kind: LinkKind): LinkCheck;
|
|
192
|
-
export interface ModelIssue {
|
|
193
|
-
readonly linkId: string;
|
|
194
|
-
readonly kind: LinkKind;
|
|
195
|
-
readonly source: string;
|
|
196
|
-
readonly target: string;
|
|
197
|
-
readonly code: ConstraintCode;
|
|
198
|
-
readonly message: string;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Re-validates every link of a model, the way piStar does when loading a file: dependencies
|
|
202
|
-
* first (each checked before its own links are added), then the remaining links in file
|
|
203
|
-
* order, each against the graph built so far. Invalid links are reported, not removed.
|
|
204
|
-
*/
|
|
205
|
-
export declare function validateModel(model: IstarModel): ModelIssue[];
|
|
206
|
-
//#endregion
|
|
207
407
|
//#region src/serialization.d.ts
|
|
208
408
|
export interface PistarElementJson {
|
|
209
409
|
id: string;
|
|
@@ -254,6 +454,10 @@ export interface PistarFile {
|
|
|
254
454
|
export declare class PistarParseError extends Error {
|
|
255
455
|
override name: string;
|
|
256
456
|
}
|
|
457
|
+
/** Thrown by `toPistar` for a kind its metamodel doesn't know (rather than writing it wrong). */
|
|
458
|
+
export declare class PistarWriteError extends Error {
|
|
459
|
+
override name: string;
|
|
460
|
+
}
|
|
257
461
|
/**
|
|
258
462
|
* Parse-time bookkeeping that lets `toPistar` reproduce the original key order. It has no
|
|
259
463
|
* meaning for the model itself and may be dropped.
|
|
@@ -265,20 +469,33 @@ export interface SourceLayout {
|
|
|
265
469
|
readonly display: readonly string[];
|
|
266
470
|
}
|
|
267
471
|
/** The key order recorded when `model` was parsed, if it came from `parsePistar`. */
|
|
268
|
-
export declare function getSourceLayout(model: IstarModel): SourceLayout | undefined;
|
|
472
|
+
export declare function getSourceLayout<EK extends string, LK extends string>(model: IstarModel<EK, LK>): SourceLayout | undefined;
|
|
269
473
|
/**
|
|
270
474
|
* Carries the recorded key order over to a model derived from `from` (the store does this for
|
|
271
475
|
* every edit, so saving an edited file keeps a stable diff).
|
|
272
476
|
*/
|
|
273
|
-
export declare function inheritSourceLayout<M extends IstarModel
|
|
477
|
+
export declare function inheritSourceLayout<M extends IstarModel<string, string>>(from: IstarModel<string, string>, to: M): M;
|
|
274
478
|
/**
|
|
275
479
|
* Parses a piStar save file (JSON text or an already-parsed object). The input is not mutated.
|
|
276
480
|
*
|
|
277
481
|
* Unlike the piStar tool, elements with `x` or `y` equal to 0 are kept: upstream's
|
|
278
482
|
* `if (element.x && element.y)` silently drops them, which looks unintended.
|
|
279
483
|
*/
|
|
484
|
+
export interface ParsePistarOptions<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
485
|
+
/**
|
|
486
|
+
* The metamodel whose kinds the file may use. Default iStar 2.0: any other `type` throws,
|
|
487
|
+
* as in the piStar tool. The parsed model remembers it (see `metamodelOf`).
|
|
488
|
+
*/
|
|
489
|
+
readonly metamodel?: Metamodel<EK, LK>;
|
|
490
|
+
}
|
|
491
|
+
export declare function parsePistar<EK extends string, LK extends string>(input: string | PistarFile | Record<string, unknown>, options: ParsePistarOptions<EK, LK> & {
|
|
492
|
+
readonly metamodel: Metamodel<EK, LK>;
|
|
493
|
+
}): IstarModel<EK, LK>;
|
|
494
|
+
export declare function parsePistar(input: string | PistarFile | Record<string, unknown>, options: ParsePistarOptions): IstarModel;
|
|
280
495
|
export declare function parsePistar(input: string | PistarFile | Record<string, unknown>): IstarModel;
|
|
281
496
|
export interface ToPistarOptions {
|
|
497
|
+
/** Default: the model's metamodel, or iStar 2.0. Decides each kind's `type` and category. */
|
|
498
|
+
metamodel?: AnyMetamodel;
|
|
282
499
|
/**
|
|
283
500
|
* Value for `saveDate`. Defaults to the model's own `saveDate` (so a load/save round trip is
|
|
284
501
|
* lossless), or the current time for models that never had one. Pass `new Date()` when
|
|
@@ -287,9 +504,9 @@ export interface ToPistarOptions {
|
|
|
287
504
|
saveDate?: string | Date;
|
|
288
505
|
}
|
|
289
506
|
/** Builds the save-file object for a model. `toPistar` is this plus `JSON.stringify`. */
|
|
290
|
-
export declare function toPistarObject(
|
|
507
|
+
export declare function toPistarObject<EK extends string, LK extends string>(input: IstarModel<EK, LK>, options?: ToPistarOptions): PistarFile;
|
|
291
508
|
/** Serializes a model to piStar's JSON text (2-space indentation, no trailing newline). */
|
|
292
|
-
export declare function toPistar(model: IstarModel, options?: ToPistarOptions): string;
|
|
509
|
+
export declare function toPistar<EK extends string, LK extends string>(model: IstarModel<EK, LK>, options?: ToPistarOptions): string;
|
|
293
510
|
declare namespace operations_d_exports {
|
|
294
511
|
export { AddDependencyResult, ConnectOptions, ConnectResult, ElementPatch, IdGenerator, LinkPatch, ModelOperationError, NewDependency, NewElement, NewLink, OperationContext, addDependency, addElement, connect, defaultIdGenerator, dependencyEnds, disconnect, moveElement, nestElement, removeElement, removeElements, updateDiagram, updateElement, updateLink };
|
|
295
512
|
}
|
|
@@ -302,21 +519,21 @@ export declare const defaultIdGenerator: IdGenerator;
|
|
|
302
519
|
export interface OperationContext {
|
|
303
520
|
readonly createId?: IdGenerator;
|
|
304
521
|
}
|
|
305
|
-
export interface NewElement {
|
|
306
|
-
readonly kind:
|
|
522
|
+
export interface NewElement<K extends string = ElementKind> {
|
|
523
|
+
readonly kind: K;
|
|
307
524
|
readonly x: number;
|
|
308
525
|
readonly y: number;
|
|
309
526
|
readonly id?: string;
|
|
310
|
-
/** Defaults to the kind's
|
|
527
|
+
/** Defaults to the kind's label ("Goal"), like piStar. */
|
|
311
528
|
readonly name?: string;
|
|
312
529
|
/** Actor to place the element in. Required in practice for iStar nodes (see NodeKindInfo). */
|
|
313
530
|
readonly parent?: string;
|
|
314
531
|
readonly customProperties?: CustomProperties;
|
|
315
532
|
readonly display?: ElementDisplay;
|
|
316
533
|
}
|
|
317
|
-
export declare function addElement(model: IstarModel, input: NewElement
|
|
318
|
-
model: IstarModel
|
|
319
|
-
element: IstarElement
|
|
534
|
+
export declare function addElement<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, input: NewElement<EK>, ctx?: OperationContext): {
|
|
535
|
+
model: IstarModel<EK, LK>;
|
|
536
|
+
element: IstarElement<EK>;
|
|
320
537
|
};
|
|
321
538
|
export interface ElementPatch {
|
|
322
539
|
readonly name?: string;
|
|
@@ -327,26 +544,27 @@ export interface ElementPatch {
|
|
|
327
544
|
readonly [key: string]: unknown;
|
|
328
545
|
} | null;
|
|
329
546
|
}
|
|
330
|
-
export declare function updateElement(model: IstarModel, id: string, patch: ElementPatch): IstarModel
|
|
547
|
+
export declare function updateElement<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string, patch: ElementPatch): IstarModel<EK, LK>;
|
|
331
548
|
/**
|
|
332
549
|
* Moves an element to an absolute position. Moving an actor shifts its inner elements by the
|
|
333
550
|
* same offset.
|
|
334
551
|
*/
|
|
335
|
-
export declare function moveElement(model: IstarModel, id: string, x: number, y: number): IstarModel
|
|
552
|
+
export declare function moveElement<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string, x: number, y: number): IstarModel<EK, LK>;
|
|
336
553
|
/**
|
|
337
554
|
* Moves an inner element into another actor (or out of any actor with `null`). The element
|
|
338
555
|
* becomes the actor's last child. Links that become invalid are kept; `validateModel` reports
|
|
339
556
|
* them.
|
|
340
557
|
*/
|
|
341
|
-
export declare function nestElement(model: IstarModel, id: string, parent: string | null): IstarModel
|
|
558
|
+
export declare function nestElement<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string, parent: string | null): IstarModel<EK, LK>;
|
|
342
559
|
/**
|
|
343
560
|
* Removes elements and everything that depends on them: inner elements of removed actors,
|
|
344
561
|
* links touching removed elements, and the rest of any dependency that loses a part.
|
|
345
562
|
*/
|
|
346
|
-
export declare function removeElements(model: IstarModel, ids: Iterable<string>): IstarModel
|
|
347
|
-
export declare function removeElement(model: IstarModel, id: string): IstarModel
|
|
348
|
-
export interface NewLink {
|
|
349
|
-
|
|
563
|
+
export declare function removeElements<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, ids: Iterable<string>): IstarModel<EK, LK>;
|
|
564
|
+
export declare function removeElement<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string): IstarModel<EK, LK>;
|
|
565
|
+
export interface NewLink<K extends string = LinkKind> {
|
|
566
|
+
/** Any link kind except dependency kinds (use `addDependency` for those). */
|
|
567
|
+
readonly kind: Exclude<K, DependencyLinkKind>;
|
|
350
568
|
readonly source: string;
|
|
351
569
|
readonly target: string;
|
|
352
570
|
readonly id?: string;
|
|
@@ -364,23 +582,24 @@ export interface ConnectOptions extends OperationContext {
|
|
|
364
582
|
*/
|
|
365
583
|
readonly tryReversed?: boolean;
|
|
366
584
|
}
|
|
367
|
-
export type ConnectResult = {
|
|
585
|
+
export type ConnectResult<EK extends string = ElementKind, LK extends string = LinkKind> = {
|
|
368
586
|
ok: true;
|
|
369
|
-
model: IstarModel
|
|
370
|
-
link: IstarLink
|
|
587
|
+
model: IstarModel<EK, LK>;
|
|
588
|
+
link: IstarLink<LK>;
|
|
371
589
|
reversed: boolean;
|
|
372
590
|
} | Extract<LinkCheck, {
|
|
373
591
|
ok: false;
|
|
374
592
|
}>;
|
|
375
593
|
/** Adds a link between two elements if the iStar constraints allow it. */
|
|
376
|
-
export declare function connect(model: IstarModel, input: NewLink
|
|
377
|
-
export interface NewDependency {
|
|
594
|
+
export declare function connect<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, input: NewLink<LK>, options?: ConnectOptions): ConnectResult<EK, LK>;
|
|
595
|
+
export interface NewDependency<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
378
596
|
/** The depender: an actor or one of its inner elements. */
|
|
379
597
|
readonly depender: string;
|
|
380
598
|
/** The dependee: an actor or one of its inner elements. */
|
|
381
599
|
readonly dependee: string;
|
|
382
600
|
readonly dependum: {
|
|
383
|
-
|
|
601
|
+
/** A node kind (built-in or extended) that can be a dependum. */
|
|
602
|
+
readonly kind: Exclude<EK, ActorKind>;
|
|
384
603
|
readonly name?: string;
|
|
385
604
|
readonly id?: string;
|
|
386
605
|
/** Defaults to the midpoint between depender and dependee, as in piStar. */
|
|
@@ -388,20 +607,22 @@ export interface NewDependency {
|
|
|
388
607
|
readonly y?: number;
|
|
389
608
|
readonly customProperties?: CustomProperties;
|
|
390
609
|
};
|
|
610
|
+
/** A dependency link kind. Default `istar.DependencyLink`. */
|
|
611
|
+
readonly linkKind?: LK;
|
|
391
612
|
readonly linkIds?: readonly [string, string];
|
|
392
613
|
}
|
|
393
|
-
export type AddDependencyResult = {
|
|
614
|
+
export type AddDependencyResult<EK extends string = ElementKind, LK extends string = LinkKind> = {
|
|
394
615
|
ok: true;
|
|
395
|
-
model: IstarModel
|
|
396
|
-
dependum: IstarElement
|
|
397
|
-
links: readonly [IstarLink
|
|
616
|
+
model: IstarModel<EK, LK>;
|
|
617
|
+
dependum: IstarElement<EK>;
|
|
618
|
+
links: readonly [IstarLink<LK>, IstarLink<LK>];
|
|
398
619
|
} | Extract<LinkCheck, {
|
|
399
620
|
ok: false;
|
|
400
621
|
}>;
|
|
401
622
|
/** Adds depender → dependum → dependee. */
|
|
402
|
-
export declare function addDependency(model: IstarModel, input: NewDependency, options?: Omit<ConnectOptions, "tryReversed">): AddDependencyResult
|
|
623
|
+
export declare function addDependency<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, input: NewDependency<EK, LK>, options?: Omit<ConnectOptions, "tryReversed">): AddDependencyResult<EK, LK>;
|
|
403
624
|
/** Removes a link. Removing either half of a dependency removes the whole dependency. */
|
|
404
|
-
export declare function disconnect(model: IstarModel, id: string): IstarModel
|
|
625
|
+
export declare function disconnect<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string): IstarModel<EK, LK>;
|
|
405
626
|
export interface LinkPatch {
|
|
406
627
|
/** `null` removes it. */
|
|
407
628
|
readonly label?: string | null;
|
|
@@ -411,10 +632,10 @@ export interface LinkPatch {
|
|
|
411
632
|
readonly [key: string]: unknown;
|
|
412
633
|
} | null;
|
|
413
634
|
}
|
|
414
|
-
export declare function updateLink(model: IstarModel, id: string, patch: LinkPatch): IstarModel
|
|
415
|
-
export declare function updateDiagram(model: IstarModel, patch: Partial<Diagram>): IstarModel
|
|
635
|
+
export declare function updateLink<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, id: string, patch: LinkPatch): IstarModel<EK, LK>;
|
|
636
|
+
export declare function updateDiagram<EK extends string = ElementKind, LK extends string = LinkKind>(model: IstarModel<EK, LK>, patch: Partial<Diagram>): IstarModel<EK, LK>;
|
|
416
637
|
/** Where dependency depender/dependee currently point (see `dependencyLinksOf`). */
|
|
417
|
-
export declare function dependencyEnds(model: IstarModel, dependumId: string): {
|
|
638
|
+
export declare function dependencyEnds<EK extends string, LK extends string>(model: IstarModel<EK, LK>, dependumId: string): {
|
|
418
639
|
depender?: string;
|
|
419
640
|
dependee?: string;
|
|
420
641
|
};
|
|
@@ -460,40 +681,45 @@ export type ModelChange = {
|
|
|
460
681
|
} | {
|
|
461
682
|
type: "replace";
|
|
462
683
|
};
|
|
463
|
-
export interface ModelChangeEvent {
|
|
464
|
-
readonly model: IstarModel
|
|
465
|
-
readonly previous: IstarModel
|
|
684
|
+
export interface ModelChangeEvent<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
685
|
+
readonly model: IstarModel<EK, LK>;
|
|
686
|
+
readonly previous: IstarModel<EK, LK>;
|
|
466
687
|
/** `undo`/`redo`/`load` carry no changes; a transaction carries all of its changes. */
|
|
467
688
|
readonly changes: readonly ModelChange[];
|
|
468
689
|
readonly source: "edit" | "undo" | "redo" | "load";
|
|
469
690
|
}
|
|
470
|
-
export type ModelListener = (event: ModelChangeEvent) => void;
|
|
471
|
-
export interface ModelStoreOptions {
|
|
691
|
+
export type ModelListener<EK extends string = ElementKind, LK extends string = LinkKind> = (event: ModelChangeEvent<EK, LK>) => void;
|
|
692
|
+
export interface ModelStoreOptions<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
693
|
+
/**
|
|
694
|
+
* Metamodel for the default empty model, when no initial model is given. A given initial
|
|
695
|
+
* model keeps its own (see `metamodelOf`).
|
|
696
|
+
*/
|
|
697
|
+
readonly metamodel?: Metamodel<EK, LK>;
|
|
472
698
|
readonly createId?: IdGenerator;
|
|
473
699
|
/** Maximum number of undo steps kept. Default 100. */
|
|
474
700
|
readonly historyLimit?: number;
|
|
475
701
|
}
|
|
476
|
-
export interface ModelStore {
|
|
477
|
-
getModel(): IstarModel
|
|
702
|
+
export interface ModelStore<EK extends string = ElementKind, LK extends string = LinkKind> {
|
|
703
|
+
getModel(): IstarModel<EK, LK>;
|
|
478
704
|
/** Returns an unsubscribe function. */
|
|
479
|
-
subscribe(listener: ModelListener): () => void;
|
|
480
|
-
canLink(source: string | IstarElement
|
|
481
|
-
addElement(input: NewElement): IstarElement
|
|
705
|
+
subscribe(listener: ModelListener<EK, LK>): () => void;
|
|
706
|
+
canLink(source: string | IstarElement<EK>, target: string | IstarElement<EK>, kind: LK): LinkCheck;
|
|
707
|
+
addElement(input: NewElement<EK>): IstarElement<EK>;
|
|
482
708
|
updateElement(id: string, patch: ElementPatch): void;
|
|
483
709
|
moveElement(id: string, x: number, y: number): void;
|
|
484
710
|
nestElement(id: string, parent: string | null): void;
|
|
485
711
|
removeElement(id: string): void;
|
|
486
712
|
removeElements(ids: Iterable<string>): void;
|
|
487
713
|
setCollapsed(actorId: string, collapsed: boolean): void;
|
|
488
|
-
connect(input: NewLink
|
|
489
|
-
addDependency(input: NewDependency, options?: Omit<ConnectOptions, "createId" | "tryReversed">): AddDependencyResult
|
|
714
|
+
connect(input: NewLink<LK>, options?: Omit<ConnectOptions, "createId">): ConnectResult<EK, LK>;
|
|
715
|
+
addDependency(input: NewDependency<EK, LK>, options?: Omit<ConnectOptions, "createId" | "tryReversed">): AddDependencyResult<EK, LK>;
|
|
490
716
|
updateLink(id: string, patch: LinkPatch): void;
|
|
491
717
|
disconnect(id: string): void;
|
|
492
718
|
updateDiagram(patch: Partial<Diagram>): void;
|
|
493
719
|
/** Replaces the model as one undoable edit. */
|
|
494
|
-
replace(model: IstarModel): void;
|
|
720
|
+
replace(model: IstarModel<EK, LK>): void;
|
|
495
721
|
/** Replaces the model and clears history (like opening a file in piStar). */
|
|
496
|
-
load(model: IstarModel): void;
|
|
722
|
+
load(model: IstarModel<EK, LK>): void;
|
|
497
723
|
/**
|
|
498
724
|
* Groups several edits into one undo step and one change event. Nested calls join the
|
|
499
725
|
* outermost transaction. If `fn` throws, the model is rolled back.
|
|
@@ -505,6 +731,10 @@ export interface ModelStore {
|
|
|
505
731
|
canRedo(): boolean;
|
|
506
732
|
clearHistory(): void;
|
|
507
733
|
}
|
|
734
|
+
export declare function createModelStore<EK extends string, LK extends string>(initial: IstarModel<EK, LK>, options?: ModelStoreOptions<EK, LK>): ModelStore<EK, LK>;
|
|
735
|
+
export declare function createModelStore<EK extends string, LK extends string>(initial: undefined, options: ModelStoreOptions<EK, LK> & {
|
|
736
|
+
readonly metamodel: Metamodel<EK, LK>;
|
|
737
|
+
}): ModelStore<EK, LK>;
|
|
508
738
|
export declare function createModelStore(initial?: IstarModel, options?: ModelStoreOptions): ModelStore;
|
|
509
739
|
//#endregion
|
|
510
740
|
//#region src/properties.d.ts
|
|
@@ -551,8 +781,12 @@ export interface PropertyIssue {
|
|
|
551
781
|
key: string;
|
|
552
782
|
message: string;
|
|
553
783
|
}
|
|
554
|
-
|
|
555
|
-
|
|
784
|
+
/**
|
|
785
|
+
* Typed custom properties of one element or link kind. `K` is the kind: iStar 2.0's kinds by
|
|
786
|
+
* default; any extension kind (see `extendMetamodel`) is accepted too.
|
|
787
|
+
*/
|
|
788
|
+
export interface PropertySchema<S extends PropertyShape = PropertyShape, K extends string = ElementKind | LinkKind> {
|
|
789
|
+
readonly kind: K;
|
|
556
790
|
readonly shape: S;
|
|
557
791
|
read(source: CustomProperties | undefined | PropertyOwner): {
|
|
558
792
|
values: Partial<InferProperties<S>>;
|
|
@@ -570,9 +804,9 @@ export interface PropertyOwner {
|
|
|
570
804
|
export interface ModelPropertyIssue extends PropertyIssue {
|
|
571
805
|
id: string;
|
|
572
806
|
}
|
|
573
|
-
export declare function defineProperties<const S extends PropertyShape
|
|
807
|
+
export declare function defineProperties<const S extends PropertyShape, const Kind extends string = ElementKind | LinkKind>(kind: Kind, shape: S, options?: {
|
|
574
808
|
validate?: (values: Partial<InferProperties<S>>) => PropertyIssue[];
|
|
575
|
-
}): PropertySchema<S>;
|
|
576
|
-
export declare function validateModelProperties(model: IstarModel, schemas: readonly PropertySchema[]): ModelPropertyIssue[];
|
|
809
|
+
}): PropertySchema<S, Kind>;
|
|
810
|
+
export declare function validateModelProperties<EK extends string, LK extends string>(model: IstarModel<EK, LK>, schemas: readonly PropertySchema<PropertyShape, string>[]): ModelPropertyIssue[];
|
|
577
811
|
//#endregion
|
|
578
812
|
//# sourceMappingURL=index.d.ts.map
|