@istar-ts/core 0.2.0 → 0.3.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/dist/index.cjs +1486 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +578 -0
- package/package.json +12 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["ops.defaultIdGenerator","ops.addElement","ops.updateElement","ops.moveElement","ops.nestElement","ops.removeElement","ops.removeElements","ops.connect","ops.addDependency","ops.updateLink","ops.disconnect","ops.updateDiagram","ops.ModelOperationError"],"sources":["../src/metamodel.ts","../src/model.ts","../src/constraints.ts","../src/serialization.ts","../src/operations.ts","../src/store.ts","../src/properties.ts"],"sourcesContent":["/**\n * The iStar 2.0 metamodel, ported from piStar's `tool/language/metamodel.js`.\n *\n * Kind names carry the `istar.` prefix exactly as they appear in piStar save files.\n */\n\nexport const ISTAR_PREFIX = 'istar';\nexport const METAMODEL_VERSION = '0.2';\n\n/** Containers: elements that hold inner elements (piStar `metamodel.containers`). */\nexport const ACTOR_KINDS = ['istar.Actor', 'istar.Agent', 'istar.Role'] as const;\nexport type ActorKind = (typeof ACTOR_KINDS)[number];\n\n/** Intentional elements (piStar `metamodel.nodes`). */\nexport const NODE_KINDS = ['istar.Goal', 'istar.Quality', 'istar.Resource', 'istar.Task'] as const;\nexport type NodeKind = (typeof NODE_KINDS)[number];\n\nexport type ElementKind = ActorKind | NodeKind;\nexport const ELEMENT_KINDS: readonly ElementKind[] = [...ACTOR_KINDS, ...NODE_KINDS];\n\n/** Links between two containers (piStar `metamodel.containerLinks`). */\nexport const ACTOR_LINK_KINDS = ['istar.IsALink', 'istar.ParticipatesInLink'] as const;\nexport type ActorLinkKind = (typeof ACTOR_LINK_KINDS)[number];\n\n/** Links that connect two containers through a dependum (piStar `metamodel.dependencyLinks`). */\nexport const DEPENDENCY_LINK_KINDS = ['istar.DependencyLink'] as const;\nexport type DependencyLinkKind = (typeof DEPENDENCY_LINK_KINDS)[number];\n\n/** Links between two intentional elements (piStar `metamodel.nodeLinks`). */\nexport const NODE_LINK_KINDS = [\n 'istar.AndRefinementLink',\n 'istar.OrRefinementLink',\n 'istar.NeededByLink',\n 'istar.QualificationLink',\n 'istar.ContributionLink',\n] as const;\nexport type NodeLinkKind = (typeof NODE_LINK_KINDS)[number];\n\nexport type LinkKind = ActorLinkKind | DependencyLinkKind | NodeLinkKind;\nexport const LINK_KINDS: readonly LinkKind[] = [\n ...ACTOR_LINK_KINDS,\n ...DEPENDENCY_LINK_KINDS,\n ...NODE_LINK_KINDS,\n];\n\n/** Possible values of a Contribution link's `label`. */\nexport const CONTRIBUTION_LABELS = ['make', 'help', 'hurt', 'break'] as const;\nexport type ContributionLabel = (typeof CONTRIBUTION_LABELS)[number];\n\nexport interface NodeKindInfo {\n /** Can be added inside an actor. */\n readonly canBeInnerElement: boolean;\n /** Can be the dependum of a dependency. */\n readonly canBeDependum: boolean;\n /** Can be placed directly on the diagram, outside any actor. */\n readonly canBeOnPaper: boolean;\n}\n\nexport interface LinkKindInfo {\n /** Fixed text drawn on the link (e.g. \"is-a\"). */\n readonly label?: string;\n /** piStar retries with source and target swapped when the first attempt is invalid. */\n readonly tryReversedWhenAdding?: boolean;\n /** The link carries a user-selectable label, stored as `label` in the save file. */\n readonly changeableLabel?: boolean;\n readonly possibleLabels?: readonly string[];\n}\n\nconst innerNode: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: false,\n};\n\nexport const NODE_KIND_INFO: Readonly<Record<NodeKind, NodeKindInfo>> = {\n 'istar.Goal': innerNode,\n 'istar.Quality': innerNode,\n 'istar.Resource': innerNode,\n 'istar.Task': innerNode,\n};\n\nexport const LINK_KIND_INFO: Readonly<Record<LinkKind, LinkKindInfo>> = {\n 'istar.IsALink': { label: 'is-a' },\n 'istar.ParticipatesInLink': { label: 'participates-in' },\n 'istar.DependencyLink': {},\n 'istar.AndRefinementLink': {},\n 'istar.OrRefinementLink': {},\n 'istar.NeededByLink': { tryReversedWhenAdding: true },\n 'istar.QualificationLink': { tryReversedWhenAdding: true },\n 'istar.ContributionLink': { changeableLabel: true, possibleLabels: CONTRIBUTION_LABELS },\n};\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Default sizes of each element kind, from piStar's `shapes.js`. For actors this is the\n * initial boundary size; the collapsed actor symbol is a circle of radius 40.\n */\nexport const DEFAULT_ELEMENT_SIZE: Readonly<Record<ElementKind, Size>> = {\n 'istar.Actor': { width: 200, height: 120 },\n 'istar.Agent': { width: 200, height: 120 },\n 'istar.Role': { width: 200, height: 120 },\n 'istar.Goal': { width: 90, height: 35 },\n 'istar.Quality': { width: 90, height: 55 },\n 'istar.Resource': { width: 90, height: 35 },\n 'istar.Task': { width: 95, height: 36 },\n};\n\nconst actorKinds: ReadonlySet<string> = new Set(ACTOR_KINDS);\nconst nodeKinds: ReadonlySet<string> = new Set(NODE_KINDS);\nconst elementKinds: ReadonlySet<string> = new Set(ELEMENT_KINDS);\nconst linkKinds: ReadonlySet<string> = new Set(LINK_KINDS);\nconst actorLinkKinds: ReadonlySet<string> = new Set(ACTOR_LINK_KINDS);\nconst nodeLinkKinds: ReadonlySet<string> = new Set(NODE_LINK_KINDS);\n\nexport function isActorKind(kind: string): kind is ActorKind {\n return actorKinds.has(kind);\n}\nexport function isNodeKind(kind: string): kind is NodeKind {\n return nodeKinds.has(kind);\n}\nexport function isElementKind(kind: string): kind is ElementKind {\n return elementKinds.has(kind);\n}\nexport function isLinkKind(kind: string): kind is LinkKind {\n return linkKinds.has(kind);\n}\nexport function isActorLinkKind(kind: string): kind is ActorLinkKind {\n return actorLinkKinds.has(kind);\n}\nexport function isNodeLinkKind(kind: string): kind is NodeLinkKind {\n return nodeLinkKinds.has(kind);\n}\nexport function isDependencyLinkKind(kind: string): kind is DependencyLinkKind {\n return kind === 'istar.DependencyLink';\n}\nexport function isContributionLabel(value: string): value is ContributionLabel {\n return (CONTRIBUTION_LABELS as readonly string[]).includes(value);\n}\n\n/** `'istar.Goal'` → `'Goal'` */\nexport function shortKindName(kind: ElementKind | LinkKind): string {\n return kind.slice(ISTAR_PREFIX.length + 1);\n}\n","import type { ActorKind, ElementKind, LinkKind, NodeKind } from './metamodel';\nimport { isActorKind } from './metamodel';\n\n/**\n * piStar stores every custom property value as a string (e.g. `\"initialValue\": \"false\"`).\n * Typed access is layered on top with property schemas (see `properties.ts`).\n */\nexport type CustomProperties = Readonly<Record<string, string>>;\n\n/** Arbitrary JSON keys the library does not interpret; kept so they survive a round trip. */\nexport type Extra = Readonly<Record<string, unknown>>;\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** Per-element entry of the save file's `display` section. */\nexport interface ElementDisplay {\n readonly backgroundColor?: string;\n readonly width?: number;\n readonly height?: number;\n /** Actors only. */\n readonly collapsed?: boolean;\n readonly [key: string]: unknown;\n}\n\n/** Per-link entry of the save file's `display` section. */\nexport interface LinkDisplay {\n readonly vertices?: readonly Point[];\n readonly [key: string]: unknown;\n}\n\nexport interface IstarElement<K extends ElementKind = ElementKind> {\n readonly id: string;\n readonly kind: K;\n /** The element's label; `text` in the save file. */\n readonly name: string;\n /** Absolute diagram coordinates, as in the save file (children are not relative to actors). */\n readonly x: number;\n readonly y: number;\n /** Id of the containing actor, for inner elements. */\n readonly parent?: string;\n /** True when the element is the dependum of a dependency (lives in `dependencies`). */\n readonly isDependum?: boolean;\n /**\n * Depender/dependee recorded in the save file for a dependum. The dependency links are the\n * source of truth; this is only a fallback used when those links are missing.\n */\n readonly dependency?: { readonly source: string; readonly target: string };\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n readonly extra?: Extra;\n}\n\nexport type IstarActor = IstarElement<ActorKind>;\nexport type IstarNode = IstarElement<NodeKind>;\n\nexport interface IstarLink<K extends LinkKind = LinkKind> {\n readonly id: string;\n readonly kind: K;\n readonly source: string;\n readonly target: string;\n /** Contribution value (`make`/`help`/`hurt`/`break`), stored as `label` in the save file. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: LinkDisplay;\n readonly extra?: Extra;\n}\n\nexport interface Diagram {\n readonly width?: number;\n readonly height?: number;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly extra?: Extra;\n}\n\n/**\n * An immutable iStar model. Maps preserve insertion order, which is the order elements and\n * links are written back to disk.\n */\nexport interface IstarModel {\n readonly elements: ReadonlyMap<string, IstarElement>;\n readonly links: ReadonlyMap<string, IstarLink>;\n readonly diagram?: Diagram;\n readonly tool?: string;\n readonly istar?: string;\n readonly saveDate?: string;\n /** `display` entries whose id matches no element or link. */\n readonly extraDisplay?: Extra;\n /** Unknown top-level keys (e.g. `metamodelVersion`). */\n readonly extra?: Extra;\n}\n\n/** Tool identifier written by piStar 2.1.0, whose file format this library emulates. */\nexport const PISTAR_TOOL = 'pistar.2.1.0';\nexport const ISTAR_VERSION = '2.0';\n\nexport const DEFAULT_DIAGRAM: Diagram = { width: 2000, height: 1300 };\n\nexport function createEmptyModel(diagram: Diagram = DEFAULT_DIAGRAM): IstarModel {\n return {\n elements: new Map(),\n links: new Map(),\n diagram,\n tool: PISTAR_TOOL,\n istar: ISTAR_VERSION,\n };\n}\n\nexport function isActor(element: IstarElement | undefined): element is IstarActor {\n return element !== undefined && isActorKind(element.kind);\n}\n\nexport function isNode(element: IstarElement | undefined): element is IstarNode {\n return element !== undefined && !isActorKind(element.kind);\n}\n\n/** Inner elements of an actor, in model order. */\nexport function childrenOf(model: IstarModel, actorId: string): IstarElement[] {\n const result: IstarElement[] = [];\n for (const element of model.elements.values()) {\n if (element.parent === actorId) result.push(element);\n }\n return result;\n}\n\n/** Links that have the element as source or target. */\nexport function linksOf(model: IstarModel, elementId: string): IstarLink[] {\n const result: IstarLink[] = [];\n for (const link of model.links.values()) {\n if (link.source === elementId || link.target === elementId) result.push(link);\n }\n return result;\n}\n\n/** For a dependum, the two halves of its dependency: depender → dependum → dependee. */\nexport function dependencyLinksOf(\n model: IstarModel,\n dependumId: string,\n): { inbound?: IstarLink; outbound?: IstarLink } {\n let inbound: IstarLink | undefined;\n let outbound: IstarLink | undefined;\n for (const link of model.links.values()) {\n if (link.kind !== 'istar.DependencyLink') continue;\n if (link.target === dependumId && !inbound) inbound = link;\n if (link.source === dependumId && !outbound) outbound = link;\n }\n return { inbound, outbound };\n}\n","/**\n * iStar 2.0 link constraints, ported from piStar's `tool/language/constraints.js`.\n *\n * Each check runs in the same order as upstream so the reported reason is the one piStar\n * would show. Upstream messages embed HTML and illustrative images; here they are plain text.\n */\nimport type { LinkKind } from './metamodel';\nimport { isActorKind } from './metamodel';\nimport type { IstarElement, IstarLink, IstarModel } from './model';\n\nexport type ConstraintCode =\n | 'unknown-element'\n | 'unknown-link-kind'\n | 'invalid-source'\n | 'invalid-target'\n | 'actor-types-differ'\n | 'self-link'\n | 'duplicate-link'\n | 'dependum-endpoint'\n | 'same-actor'\n | 'different-actors'\n | 'refined-depender'\n | 'contributed-depender'\n | 'depender-target'\n | 'mixed-refinement'\n | 'contribution-and-qualification';\n\nexport type LinkCheck = { ok: true } | { ok: false; reason: string; code: ConstraintCode };\n\nconst OK: LinkCheck = { ok: true };\n\nfunction fail(code: ConstraintCode, reason: string): LinkCheck {\n return { ok: false, code, reason };\n}\n\ntype ElementRef = string | IstarElement;\n\n/**\n * Checks whether a link of `kind` may be added from `source` to `target` in `model`.\n *\n * For `istar.DependencyLink`, `source` is the depender and `target` the dependee (an actor or\n * one of its inner elements); the dependum sits between them and is not part of the check.\n */\nexport function canLink(\n model: IstarModel,\n source: ElementRef,\n target: ElementRef,\n kind: LinkKind,\n): LinkCheck {\n const s = resolve(model, source);\n const t = resolve(model, target);\n if (!s) return fail('unknown-element', `unknown source element \"${refId(source)}\"`);\n if (!t) return fail('unknown-element', `unknown target element \"${refId(target)}\"`);\n const check = CHECKS[kind];\n if (!check) return fail('unknown-link-kind', `unknown link kind \"${String(kind)}\"`);\n return check(new Graph(model), s, t);\n}\n\nfunction refId(ref: ElementRef): string {\n return typeof ref === 'string' ? ref : ref.id;\n}\n\nfunction resolve(model: IstarModel, ref: ElementRef): IstarElement | undefined {\n // Always look the element up so a stale object can't be checked against a newer model.\n return model.elements.get(refId(ref));\n}\n\n/** The graph queries used by upstream constraints (`istar.isThereLinkBetween`, etc.). */\nclass Graph {\n constructor(readonly model: IstarModel) {}\n\n /**\n * True when a link (optionally of `kind`) already connects the two elements, in either\n * direction. Mirrors `istar.isThereLinkBetween`.\n */\n isThereLinkBetween(a: IstarElement, b: IstarElement, kind?: LinkKind): boolean {\n for (const link of this.model.links.values()) {\n if (kind && link.kind !== kind) continue;\n if (\n (link.source === a.id && link.target === b.id) ||\n (link.source === b.id && link.target === a.id)\n ) {\n return true;\n }\n }\n return false;\n }\n\n isSourceOfType(element: IstarElement, kind: LinkKind): boolean {\n for (const link of this.model.links.values()) {\n if (link.kind === kind && link.source === element.id) return true;\n }\n return false;\n }\n\n isTargetOfType(element: IstarElement, kind: LinkKind): boolean {\n for (const link of this.model.links.values()) {\n if (link.kind === kind && link.target === element.id) return true;\n }\n return false;\n }\n}\n\ntype Check = (graph: Graph, source: IstarElement, target: IstarElement) => LinkCheck;\n\nconst is = (element: IstarElement, ...shortNames: string[]): boolean =>\n shortNames.some((name) => element.kind === `istar.${name}`);\n\nconst isKindOfActor = (element: IstarElement): boolean => isActorKind(element.kind);\nconst isDependum = (element: IstarElement): boolean => element.isDependum === true;\n\nconst isALink: Check = (graph, source, target) => {\n // Upstream evaluates the source-kind check after the type-equality check without guarding\n // on the previous result, so its message wins when both fail. Reproduced here.\n if (!is(source, 'Actor', 'Role')) {\n return fail(\n 'invalid-source',\n 'the source of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n );\n }\n if (source.kind !== target.kind) {\n return fail(\n 'actor-types-differ',\n 'the source and target of Is-A links must be of the same type - Actor and Actor, or Role and Role (iStar 2.0 Guide, Page 6).',\n );\n }\n if (!is(target, 'Actor', 'Role')) {\n return fail(\n 'invalid-target',\n 'the target of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make Is-A links from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\nconst participatesInLink: Check = (graph, source, target) => {\n if (!isKindOfActor(source)) {\n return fail(\n 'invalid-source',\n 'the source of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n );\n }\n if (!isKindOfActor(target)) {\n return fail(\n 'invalid-target',\n 'the target of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Participates-In link from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\n/** The actor an element belongs to: itself for actors, its parent for inner elements. */\nfunction owningActorId(element: IstarElement): string | undefined {\n return isKindOfActor(element) ? element.id : element.parent;\n}\n\nconst dependencyLink: Check = (graph, source, target) => {\n if (source.id === target.id) {\n return fail('self-link', 'a Dependency link cannot link an element onto itself');\n }\n if (isDependum(source)) {\n return fail('dependum-endpoint', 'a Dependency link cannot start from a dependum');\n }\n if (isDependum(target)) {\n return fail('dependum-endpoint', 'a Dependency link cannot end in a dependum');\n }\n if (owningActorId(source) === owningActorId(target)) {\n return fail(\n 'same-actor',\n 'a Dependency link must involve two different actors (iStar 2.0 Guide, Page 14)',\n );\n }\n if (\n graph.isTargetOfType(source, 'istar.OrRefinementLink') ||\n graph.isTargetOfType(source, 'istar.AndRefinementLink')\n ) {\n return fail(\n 'refined-depender',\n 'a refined element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n );\n }\n if (graph.isTargetOfType(source, 'istar.ContributionLink')) {\n return fail(\n 'contributed-depender',\n 'a contributed element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n );\n }\n return OK;\n};\n\nfunction refinementLink(label: 'AND' | 'OR'): Check {\n const other = label === 'AND' ? 'istar.OrRefinementLink' : 'istar.AndRefinementLink';\n return (graph, source, target) => {\n if (!is(source, 'Task', 'Goal')) {\n return fail(\n 'invalid-source',\n `the source of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n );\n }\n if (!is(target, 'Task', 'Goal')) {\n return fail(\n 'invalid-target',\n `the target of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n `you cannot make an ${label}-refinement link from an element onto itself`,\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n `you cannot make an ${label}-refinement link with a dependum (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n `the source and target of an ${label}-refinement link must pertain to the same actor (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one refinement link between the same two elements',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot refine a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-element.',\n );\n }\n if (graph.isTargetOfType(target, other)) {\n const mix =\n label === 'AND'\n ? 'you cannot mix AND-refinements with OR-refinements targeting the same element (iStar 2.0 Guide, Page 10).'\n : 'you cannot mix OR-refinements with AND-refinements targeting the same element (iStar 2.0 Guide, Page 10).';\n return fail('mixed-refinement', mix);\n }\n return OK;\n };\n}\n\nconst neededByLink: Check = (graph, source, target) => {\n if (!is(source, 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Needed-By link must be a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(target, 'Task')) {\n return fail(\n 'invalid-target',\n 'the target of a Needed-By link must be a Task (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Needed-By link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Needed-By link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Needed-By link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Needed-By link between the same two elements',\n );\n }\n return OK;\n};\n\nconst contributionLink: Check = (graph, source, target) => {\n if (!is(source, 'Goal', 'Quality', 'Task', 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Contribution link must be a Goal, a Quality, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(target, 'Quality')) {\n return fail(\n 'invalid-target',\n 'the target of a Contribution link must be a Quality (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n 'you cannot make a Contribution link from an element onto itself (iStar 2.0 Guide, Page 15)',\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Contribution link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Contribution link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Contribution link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Contribution and Qualification links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot contribute to a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-quality.',\n );\n }\n return OK;\n};\n\nconst qualificationLink: Check = (graph, source, target) => {\n if (!is(source, 'Quality')) {\n return fail(\n 'invalid-source',\n 'the source of a Qualification link must be a Quality (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(target, 'Goal', 'Task', 'Resource')) {\n return fail(\n 'invalid-target',\n 'the target of a Qualification link must be a Goal, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Qualification link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Qualification link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Qualification link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Qualification link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Qualification and Contribution links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n return OK;\n};\n\nconst CHECKS: Readonly<Record<LinkKind, Check>> = {\n 'istar.IsALink': isALink,\n 'istar.ParticipatesInLink': participatesInLink,\n 'istar.DependencyLink': dependencyLink,\n 'istar.AndRefinementLink': refinementLink('AND'),\n 'istar.OrRefinementLink': refinementLink('OR'),\n 'istar.NeededByLink': neededByLink,\n 'istar.ContributionLink': contributionLink,\n 'istar.QualificationLink': qualificationLink,\n};\n\nexport interface ModelIssue {\n readonly linkId: string;\n readonly kind: LinkKind;\n readonly source: string;\n readonly target: string;\n readonly code: ConstraintCode;\n readonly message: string;\n}\n\n/**\n * Re-validates every link of a model, the way piStar does when loading a file: dependencies\n * first (each checked before its own links are added), then the remaining links in file\n * order, each against the graph built so far. Invalid links are reported, not removed.\n */\nexport function validateModel(model: IstarModel): ModelIssue[] {\n const issues: ModelIssue[] = [];\n const accepted = new Map<string, IstarLink>();\n const view = (): IstarModel => ({ ...model, links: accepted });\n\n const report = (\n linkId: string,\n kind: LinkKind,\n source: string,\n target: string,\n check: LinkCheck,\n ): void => {\n if (!check.ok) {\n issues.push({ linkId, kind, source, target, code: check.code, message: check.reason });\n }\n };\n\n const dependencyLinks = [...model.links.values()].filter(\n (l) => l.kind === 'istar.DependencyLink',\n );\n for (const dependum of model.elements.values()) {\n if (!dependum.isDependum) continue;\n const inbound = dependencyLinks.find((l) => l.target === dependum.id);\n const outbound = dependencyLinks.find((l) => l.source === dependum.id);\n const depender = inbound?.source ?? dependum.dependency?.source;\n const dependee = outbound?.target ?? dependum.dependency?.target;\n if (depender !== undefined && dependee !== undefined) {\n report(\n inbound?.id ?? dependum.id,\n 'istar.DependencyLink',\n depender,\n dependee,\n canLink(view(), depender, dependee, 'istar.DependencyLink'),\n );\n }\n if (inbound) accepted.set(inbound.id, inbound);\n if (outbound) accepted.set(outbound.id, outbound);\n }\n\n for (const link of model.links.values()) {\n if (link.kind === 'istar.DependencyLink') continue;\n if (model.elements.has(link.source) && model.elements.has(link.target)) {\n report(\n link.id,\n link.kind,\n link.source,\n link.target,\n canLink(view(), link.source, link.target, link.kind),\n );\n } else {\n report(link.id, link.kind, link.source, link.target, {\n ok: false,\n code: 'unknown-element',\n reason: 'the link refers to an element that does not exist',\n });\n }\n accepted.set(link.id, link);\n }\n return issues;\n}\n","/**\n * Reading and writing piStar save files, ported from `tool/app/istarcore/fileManager.js`.\n *\n * Output is produced with the same key order and `JSON.stringify(_, null, 2)` formatting as the\n * piStar web tool, so a file saved by piStar round-trips byte for byte. Keys this library does\n * not interpret are kept and written back.\n */\nimport type { ElementKind, LinkKind } from './metamodel';\nimport { isActorKind, isElementKind, isLinkKind } from './metamodel';\nimport type {\n CustomProperties,\n Diagram,\n ElementDisplay,\n Extra,\n IstarElement,\n IstarLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport { dependencyLinksOf } from './model';\n\n// ---------------------------------------------------------------------------------------------\n// File format types\n\nexport interface PistarElementJson {\n id: string;\n text: string;\n type: string;\n x: number;\n y: number;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface PistarActorJson extends PistarElementJson {\n nodes: PistarElementJson[];\n}\n\nexport interface PistarDependencyJson extends PistarElementJson {\n source: string;\n target: string;\n}\n\nexport interface PistarLinkJson {\n id: string;\n type: string;\n source: string;\n target: string;\n name?: string;\n customProperties?: Record<string, string>;\n label?: string;\n [key: string]: unknown;\n}\n\nexport interface PistarDiagramJson {\n width?: number;\n height?: number;\n name?: string;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/** A piStar save file. Older piStar versions may omit some sections (e.g. `orphans`). */\nexport interface PistarFile {\n actors: PistarActorJson[];\n orphans?: PistarElementJson[];\n dependencies?: PistarDependencyJson[];\n links?: PistarLinkJson[];\n display?: Record<string, Record<string, unknown>>;\n tool?: string;\n istar?: string;\n saveDate?: string;\n diagram?: PistarDiagramJson;\n [key: string]: unknown;\n}\n\nexport class PistarParseError extends Error {\n override name = 'PistarParseError';\n}\n\n/**\n * Parse-time bookkeeping that lets `toPistar` reproduce the original key order. It has no\n * meaning for the model itself and may be dropped.\n */\nexport interface SourceLayout {\n /** Top-level keys in file order. */\n readonly keys: readonly string[];\n /** `display` ids in file order. */\n readonly display: readonly string[];\n}\n\nconst layouts = new WeakMap<IstarModel, SourceLayout>();\n\n/** The key order recorded when `model` was parsed, if it came from `parsePistar`. */\nexport function getSourceLayout(model: IstarModel): SourceLayout | undefined {\n return layouts.get(model);\n}\n\n/**\n * Carries the recorded key order over to a model derived from `from` (the store does this for\n * every edit, so saving an edited file keeps a stable diff).\n */\nexport function inheritSourceLayout<M extends IstarModel>(from: IstarModel, to: M): M {\n const layout = layouts.get(from);\n if (layout && from !== to) layouts.set(to, layout);\n return to;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Parsing\n\nconst ELEMENT_KEYS = new Set(['id', 'text', 'type', 'x', 'y', 'customProperties']);\nconst ACTOR_KEYS = new Set([...ELEMENT_KEYS, 'nodes']);\nconst DEPENDENCY_KEYS = new Set([...ELEMENT_KEYS, 'source', 'target']);\nconst LINK_KEYS = new Set(['id', 'type', 'source', 'target', 'name', 'customProperties', 'label']);\nconst DIAGRAM_KEYS = new Set(['width', 'height', 'name', 'customProperties']);\nconst TOP_LEVEL_KEYS = [\n 'actors',\n 'orphans',\n 'dependencies',\n 'links',\n 'display',\n 'tool',\n 'istar',\n 'saveDate',\n 'diagram',\n] as const;\nconst TOP_LEVEL_KEY_SET: ReadonlySet<string> = new Set(TOP_LEVEL_KEYS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction extraOf(json: Record<string, unknown>, known: ReadonlySet<string>): Extra | undefined {\n let extra: Record<string, unknown> | undefined;\n for (const key of Object.keys(json)) {\n if (!known.has(key)) (extra ??= {})[key] = json[key];\n }\n return extra;\n}\n\nfunction asArray(value: unknown, where: string): unknown[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) throw new PistarParseError(`\"${where}\" must be an array`);\n return value;\n}\n\n/**\n * Parses a piStar save file (JSON text or an already-parsed object). The input is not mutated.\n *\n * Unlike the piStar tool, elements with `x` or `y` equal to 0 are kept: upstream's\n * `if (element.x && element.y)` silently drops them, which looks unintended.\n */\nexport function parsePistar(input: string | PistarFile | Record<string, unknown>): IstarModel {\n let json: unknown;\n if (typeof input === 'string') {\n try {\n json = JSON.parse(input);\n } catch (error) {\n throw new PistarParseError(`invalid JSON: ${(error as Error).message}`, { cause: error });\n }\n } else {\n json = structuredClone(input);\n }\n if (!isRecord(json)) throw new PistarParseError('a piStar model must be a JSON object');\n\n const display = isRecord(json.display) ? json.display : {};\n const usedDisplay = new Set<string>();\n const elements = new Map<string, IstarElement>();\n const links = new Map<string, IstarLink>();\n\n const displayFor = (id: string): Record<string, unknown> | undefined => {\n const entry = display[id];\n if (!isRecord(entry)) return undefined;\n usedDisplay.add(id);\n return entry;\n };\n\n const readElement = (\n raw: unknown,\n where: string,\n known: ReadonlySet<string>,\n extras: Partial<IstarElement>,\n ): IstarElement => {\n if (!isRecord(raw)) throw new PistarParseError(`${where}: expected an object`);\n const { id, type } = raw;\n if (typeof id !== 'string' || id === '') {\n throw new PistarParseError(`${where}: missing \"id\"`);\n }\n if (typeof type !== 'string' || !isElementKind(type)) {\n throw new PistarParseError(`${where} (${id}): unknown element type ${JSON.stringify(type)}`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`${where}: duplicated id \"${id}\"`);\n }\n const element: IstarElement = {\n id,\n kind: type as ElementKind,\n name: typeof raw.text === 'string' ? raw.text : '',\n x: typeof raw.x === 'number' ? raw.x : 0,\n y: typeof raw.y === 'number' ? raw.y : 0,\n ...extras,\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('display', displayFor(id) as ElementDisplay | undefined),\n ...optional('extra', extraOf(raw, known)),\n };\n elements.set(id, element);\n return element;\n };\n\n asArray(json.actors, 'actors').forEach((raw, i) => {\n const actor = readElement(raw, `actors[${i}]`, ACTOR_KEYS, {});\n if (!isActorKind(actor.kind)) {\n throw new PistarParseError(`actors[${i}] (${actor.id}): ${actor.kind} is not an actor kind`);\n }\n asArray((raw as Record<string, unknown>).nodes, `actors[${i}].nodes`).forEach((node, j) => {\n const child = readElement(node, `actors[${i}].nodes[${j}]`, ELEMENT_KEYS, {\n parent: actor.id,\n });\n if (isActorKind(child.kind)) {\n throw new PistarParseError(`actors[${i}].nodes[${j}]: actors cannot be nested`);\n }\n });\n });\n\n asArray(json.orphans, 'orphans').forEach((raw, i) => {\n readElement(raw, `orphans[${i}]`, ELEMENT_KEYS, {});\n });\n\n asArray(json.dependencies, 'dependencies').forEach((raw, i) => {\n const r = raw as Record<string, unknown>;\n const dependency =\n typeof r.source === 'string' && typeof r.target === 'string'\n ? { dependency: { source: r.source, target: r.target } }\n : {};\n readElement(raw, `dependencies[${i}]`, DEPENDENCY_KEYS, { isDependum: true, ...dependency });\n });\n\n asArray(json.links, 'links').forEach((raw, i) => {\n if (!isRecord(raw)) throw new PistarParseError(`links[${i}]: expected an object`);\n const { id, type, source, target } = raw;\n if (typeof id !== 'string' || id === '')\n throw new PistarParseError(`links[${i}]: missing \"id\"`);\n if (typeof type !== 'string' || !isLinkKind(type)) {\n throw new PistarParseError(`links[${i}] (${id}): unknown link type ${JSON.stringify(type)}`);\n }\n if (typeof source !== 'string' || typeof target !== 'string') {\n throw new PistarParseError(`links[${i}] (${id}): missing \"source\" or \"target\"`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`links[${i}]: duplicated id \"${id}\"`);\n }\n links.set(id, {\n id,\n kind: type as LinkKind,\n source,\n target,\n ...optional('name', typeof raw.name === 'string' ? raw.name : undefined),\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('label', typeof raw.label === 'string' ? raw.label : undefined),\n ...optional('display', displayFor(id) as LinkDisplay | undefined),\n ...optional('extra', extraOf(raw, LINK_KEYS)),\n });\n });\n\n let extraDisplay: Record<string, unknown> | undefined;\n for (const [id, value] of Object.entries(display)) {\n if (!usedDisplay.has(id)) (extraDisplay ??= {})[id] = value;\n }\n\n let diagram: Diagram | undefined;\n if (isRecord(json.diagram)) {\n const d = json.diagram;\n diagram = {\n ...optional('width', typeof d.width === 'number' ? d.width : undefined),\n ...optional('height', typeof d.height === 'number' ? d.height : undefined),\n ...optional('name', typeof d.name === 'string' ? d.name : undefined),\n ...(isRecord(d.customProperties)\n ? { customProperties: d.customProperties as CustomProperties }\n : {}),\n ...optional('extra', extraOf(d, DIAGRAM_KEYS)),\n };\n }\n\n const model: IstarModel = {\n elements,\n links,\n ...optional('diagram', diagram),\n ...optional('tool', typeof json.tool === 'string' ? json.tool : undefined),\n ...optional('istar', typeof json.istar === 'string' ? json.istar : undefined),\n ...optional('saveDate', typeof json.saveDate === 'string' ? json.saveDate : undefined),\n ...optional('extraDisplay', extraDisplay),\n ...optional('extra', extraOf(json, TOP_LEVEL_KEY_SET)),\n };\n layouts.set(model, { keys: Object.keys(json), display: Object.keys(display) });\n return model;\n}\n\nfunction optional<K extends string, V>(key: K, value: V | undefined): { [P in K]?: V } {\n return (value === undefined ? {} : { [key]: value }) as { [P in K]?: V };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Serialization\n\nexport interface ToPistarOptions {\n /**\n * Value for `saveDate`. Defaults to the model's own `saveDate` (so a load/save round trip is\n * lossless), or the current time for models that never had one. Pass `new Date()` when\n * saving an edited model, as piStar does.\n */\n saveDate?: string | Date;\n}\n\nfunction formatDate(date: Date): string {\n // piStar uses the deprecated `toGMTString`, an alias of `toUTCString`.\n return date.toUTCString();\n}\n\nfunction elementJson(element: IstarElement): PistarElementJson {\n return {\n id: element.id,\n text: element.name,\n type: element.kind,\n x: element.x,\n y: element.y,\n ...(element.customProperties ? { customProperties: { ...element.customProperties } } : {}),\n };\n}\n\n/** Builds the save-file object for a model. `toPistar` is this plus `JSON.stringify`. */\nexport function toPistarObject(model: IstarModel, options: ToPistarOptions = {}): PistarFile {\n const actors: PistarActorJson[] = [];\n const orphans: PistarElementJson[] = [];\n const dependencies: PistarDependencyJson[] = [];\n const children = new Map<string, PistarElementJson[]>();\n\n for (const element of model.elements.values()) {\n if (element.parent !== undefined && !isActorKind(element.kind)) {\n let list = children.get(element.parent);\n if (!list) children.set(element.parent, (list = []));\n list.push({ ...elementJson(element), ...element.extra });\n }\n }\n\n for (const element of model.elements.values()) {\n if (isActorKind(element.kind)) {\n actors.push({\n ...elementJson(element),\n nodes: children.get(element.id) ?? [],\n ...element.extra,\n });\n } else if (element.isDependum) {\n // Like piStar, derive depender/dependee from the dependency links.\n const { inbound, outbound } = dependencyLinksOf(model, element.id);\n dependencies.push({\n ...elementJson(element),\n source: inbound?.source ?? element.dependency?.source ?? '',\n target: outbound?.target ?? element.dependency?.target ?? '',\n ...element.extra,\n });\n } else if (element.parent === undefined || !model.elements.has(element.parent)) {\n orphans.push({ ...elementJson(element), ...element.extra });\n }\n }\n\n const links: PistarLinkJson[] = [];\n for (const link of model.links.values()) {\n links.push({\n id: link.id,\n type: link.kind,\n source: link.source,\n target: link.target,\n ...(link.name !== undefined ? { name: link.name } : {}),\n ...(link.customProperties ? { customProperties: { ...link.customProperties } } : {}),\n ...(link.label !== undefined ? { label: link.label } : {}),\n ...link.extra,\n });\n }\n\n const layout = layouts.get(model);\n const display: Record<string, Record<string, unknown>> = {};\n const displayOf = (id: string): Record<string, unknown> | undefined => {\n const owner = model.elements.get(id) ?? model.links.get(id);\n if (owner) return owner.display as Record<string, unknown> | undefined;\n return model.extraDisplay?.[id] as Record<string, unknown> | undefined;\n };\n for (const id of layout?.display ?? []) {\n const entry = displayOf(id);\n if (entry !== undefined) display[id] = { ...entry };\n }\n for (const owner of [...model.elements.values(), ...model.links.values()]) {\n if (owner.display && !(owner.id in display)) display[owner.id] = { ...owner.display };\n }\n for (const [id, entry] of Object.entries(model.extraDisplay ?? {})) {\n if (!(id in display)) display[id] = entry as Record<string, unknown>;\n }\n\n let saveDate: string | undefined;\n if (options.saveDate instanceof Date) saveDate = formatDate(options.saveDate);\n else saveDate = options.saveDate ?? model.saveDate ?? formatDate(new Date());\n\n const d = model.diagram;\n const diagram: PistarDiagramJson | undefined = d && {\n ...(d.width !== undefined ? { width: d.width } : {}),\n ...(d.height !== undefined ? { height: d.height } : {}),\n ...(d.name !== undefined ? { name: d.name } : {}),\n ...(d.customProperties ? { customProperties: { ...d.customProperties } } : {}),\n ...d.extra,\n };\n\n const values: Record<string, unknown> = {\n ...model.extra,\n actors,\n orphans,\n dependencies,\n links,\n display,\n tool: model.tool,\n istar: model.istar,\n saveDate,\n diagram,\n };\n\n // Files written by older piStar versions lack some sections (e.g. `orphans`). Keep them\n // absent while they are empty, so such files round-trip unchanged.\n if (layout) {\n for (const key of ['actors', 'orphans', 'dependencies', 'links', 'display'] as const) {\n const value = values[key] as unknown[] | Record<string, unknown>;\n const empty = Array.isArray(value) ? value.length === 0 : Object.keys(value).length === 0;\n if (empty && !layout.keys.includes(key)) values[key] = undefined;\n }\n }\n\n // Emit keys in the order they had in the source file, then any new ones in piStar's order.\n const order = [...(layout?.keys ?? []), ...TOP_LEVEL_KEYS, ...Object.keys(model.extra ?? {})];\n const file: Record<string, unknown> = {};\n for (const key of order) {\n if (!(key in file) && values[key] !== undefined) file[key] = values[key];\n }\n return file as PistarFile;\n}\n\n/** Serializes a model to piStar's JSON text (2-space indentation, no trailing newline). */\nexport function toPistar(model: IstarModel, options?: ToPistarOptions): string {\n return JSON.stringify(toPistarObject(model, options), null, 2);\n}\n","/**\n * Pure model operations. Each takes a model and returns a new one; inputs are never mutated.\n * The store (`store.ts`) wraps these with undo/redo and change events, and the React layer can\n * use them directly for controlled components.\n *\n * Behaviour follows the piStar web tool (`istarFunctions.js` and its UI):\n * - removing an actor removes its inner elements; removing an element removes its links;\n * - a dependency is two `DependencyLink`s around a dependum, and removing any of the three\n * removes the whole dependency (upstream keeps an `otherHalf` reference for this);\n * - moving an actor moves its inner elements with it (they are JointJS-embedded upstream).\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { ElementKind, LinkKind, NodeKind } from './metamodel';\nimport { LINK_KIND_INFO, isActorKind, isNodeKind, shortKindName } from './metamodel';\nimport type {\n CustomProperties,\n Diagram,\n ElementDisplay,\n IstarElement,\n IstarLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport { dependencyLinksOf } from './model';\nimport { inheritSourceLayout } from './serialization';\n\nexport class ModelOperationError extends Error {\n override name = 'ModelOperationError';\n}\n\n/** Generates ids for new elements and links. piStar uses UUID v4. */\nexport type IdGenerator = () => string;\n\nexport const defaultIdGenerator: IdGenerator = () => {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n // Fallback for non-secure browser contexts, where randomUUID is unavailable.\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n};\n\nexport interface OperationContext {\n readonly createId?: IdGenerator;\n}\n\nfunction derive(from: IstarModel, changes: Partial<IstarModel>): IstarModel {\n return inheritSourceLayout(from, { ...from, ...changes });\n}\n\nfunction requireElement(model: IstarModel, id: string): IstarElement {\n const element = model.elements.get(id);\n if (!element) throw new ModelOperationError(`unknown element \"${id}\"`);\n return element;\n}\n\nfunction requireLink(model: IstarModel, id: string): IstarLink {\n const link = model.links.get(id);\n if (!link) throw new ModelOperationError(`unknown link \"${id}\"`);\n return link;\n}\n\nfunction withoutUndefined<T extends object>(value: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Elements\n\nexport interface NewElement {\n readonly kind: ElementKind;\n readonly x: number;\n readonly y: number;\n readonly id?: string;\n /** Defaults to the kind's short name (\"Goal\"), like piStar. */\n readonly name?: string;\n /** Actor to place the element in. Required in practice for iStar nodes (see NodeKindInfo). */\n readonly parent?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n}\n\nexport function addElement(\n model: IstarModel,\n input: NewElement,\n ctx: OperationContext = {},\n): { model: IstarModel; element: IstarElement } {\n const id = input.id ?? (ctx.createId ?? defaultIdGenerator)();\n if (model.elements.has(id) || model.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n if (input.parent !== undefined) {\n if (isActorKind(input.kind)) throw new ModelOperationError('actors cannot be nested');\n if (!isActorKind(requireElement(model, input.parent).kind)) {\n throw new ModelOperationError(`parent \"${input.parent}\" is not an actor`);\n }\n }\n const element: IstarElement = withoutUndefined({\n id,\n kind: input.kind,\n name: input.name ?? shortKindName(input.kind),\n x: input.x,\n y: input.y,\n parent: input.parent,\n customProperties: input.customProperties,\n display: input.display,\n });\n const elements = new Map(model.elements).set(id, element);\n return { model: derive(model, { elements }), element };\n}\n\nexport interface ElementPatch {\n readonly name?: string;\n /** Replaces the whole map. Use `null` to remove it. */\n readonly customProperties?: CustomProperties | null;\n /** Merged into the current display; a key set to `undefined` is removed. `null` clears it. */\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction mergeDisplay<D extends object>(\n current: D | undefined,\n patch: { readonly [key: string]: unknown } | null | undefined,\n): D | undefined {\n if (patch === undefined) return current;\n if (patch === null) return undefined;\n const merged: Record<string, unknown> = { ...current };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) delete merged[key];\n else merged[key] = value;\n }\n return Object.keys(merged).length > 0 ? (merged as D) : undefined;\n}\n\nexport function updateElement(model: IstarModel, id: string, patch: ElementPatch): IstarModel {\n const current = requireElement(model, id);\n const next: IstarElement = withoutUndefined({\n ...current,\n name: patch.name ?? current.name,\n customProperties:\n patch.customProperties === undefined\n ? current.customProperties\n : (patch.customProperties ?? undefined),\n display: mergeDisplay<ElementDisplay>(current.display, patch.display),\n });\n return derive(model, { elements: new Map(model.elements).set(id, next) });\n}\n\n/**\n * Moves an element to an absolute position. Moving an actor shifts its inner elements by the\n * same offset.\n */\nexport function moveElement(model: IstarModel, id: string, x: number, y: number): IstarModel {\n const current = requireElement(model, id);\n const dx = x - current.x;\n const dy = y - current.y;\n if (dx === 0 && dy === 0) return model;\n const elements = new Map(model.elements);\n elements.set(id, { ...current, x, y });\n if (isActorKind(current.kind)) {\n for (const child of model.elements.values()) {\n if (child.parent === id)\n elements.set(child.id, { ...child, x: child.x + dx, y: child.y + dy });\n }\n }\n return derive(model, { elements });\n}\n\n/**\n * Moves an inner element into another actor (or out of any actor with `null`). The element\n * becomes the actor's last child. Links that become invalid are kept; `validateModel` reports\n * them.\n */\nexport function nestElement(model: IstarModel, id: string, parent: string | null): IstarModel {\n const current = requireElement(model, id);\n if (isActorKind(current.kind)) throw new ModelOperationError('actors cannot be nested');\n if (current.isDependum) throw new ModelOperationError('a dependum cannot be nested');\n if ((current.parent ?? null) === parent) return model;\n if (parent !== null && !isActorKind(requireElement(model, parent).kind)) {\n throw new ModelOperationError(`parent \"${parent}\" is not an actor`);\n }\n const elements = new Map(model.elements);\n elements.delete(id);\n const { parent: _old, ...rest } = current;\n elements.set(id, parent === null ? rest : { ...rest, parent });\n return derive(model, { elements });\n}\n\n/**\n * Removes elements and everything that depends on them: inner elements of removed actors,\n * links touching removed elements, and the rest of any dependency that loses a part.\n */\nexport function removeElements(model: IstarModel, ids: Iterable<string>): IstarModel {\n return removeCascade(model, new Set(ids), new Set());\n}\n\nexport function removeElement(model: IstarModel, id: string): IstarModel {\n requireElement(model, id);\n return removeElements(model, [id]);\n}\n\nfunction removeCascade(\n model: IstarModel,\n elementIds: Set<string>,\n linkIds: Set<string>,\n): IstarModel {\n // Iterate to a fixed point: each round may remove more elements or links.\n let changed = true;\n while (changed) {\n changed = false;\n for (const element of model.elements.values()) {\n if (elementIds.has(element.id)) continue;\n if (element.parent !== undefined && elementIds.has(element.parent)) {\n elementIds.add(element.id);\n changed = true;\n }\n }\n for (const link of model.links.values()) {\n if (linkIds.has(link.id)) continue;\n if (elementIds.has(link.source) || elementIds.has(link.target)) {\n linkIds.add(link.id);\n changed = true;\n }\n }\n // A dependency that lost a half, or its dependum, goes entirely.\n for (const link of model.links.values()) {\n if (!linkIds.has(link.id) || link.kind !== 'istar.DependencyLink') continue;\n for (const end of [link.source, link.target]) {\n const element = model.elements.get(end);\n if (element?.isDependum && !elementIds.has(end)) {\n elementIds.add(end);\n changed = true;\n }\n }\n }\n }\n if (elementIds.size === 0 && linkIds.size === 0) return model;\n const elements = new Map(model.elements);\n for (const id of elementIds) elements.delete(id);\n const links = new Map(model.links);\n for (const id of linkIds) links.delete(id);\n return derive(model, { elements, links });\n}\n\n// ---------------------------------------------------------------------------------------------\n// Links\n\nexport interface NewLink {\n readonly kind: Exclude<LinkKind, 'istar.DependencyLink'>;\n readonly source: string;\n readonly target: string;\n readonly id?: string;\n /** Contribution value: make, help, hurt or break. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface ConnectOptions extends OperationContext {\n /** Skip constraint checking (used when loading or scripting known-good data). */\n readonly force?: boolean;\n /**\n * Retry with source and target swapped if the link is invalid as given. Defaults to the\n * metamodel's `tryReversedWhenAdding` (Needed-By and Qualification), as in piStar.\n */\n readonly tryReversed?: boolean;\n}\n\nexport type ConnectResult =\n | { ok: true; model: IstarModel; link: IstarLink; reversed: boolean }\n | Extract<LinkCheck, { ok: false }>;\n\n/** Adds a link between two elements if the iStar constraints allow it. */\nexport function connect(\n model: IstarModel,\n input: NewLink,\n options: ConnectOptions = {},\n): ConnectResult {\n if ((input.kind as LinkKind) === 'istar.DependencyLink') {\n throw new ModelOperationError('use addDependency to create dependencies');\n }\n let { source, target } = input;\n let reversed = false;\n if (!options.force) {\n let check = canLink(model, source, target, input.kind);\n const tryReversed = options.tryReversed ?? LINK_KIND_INFO[input.kind].tryReversedWhenAdding;\n if (!check.ok && tryReversed) {\n const swapped = canLink(model, target, source, input.kind);\n if (swapped.ok) {\n [source, target] = [target, source];\n reversed = true;\n check = swapped;\n }\n }\n if (!check.ok) return check;\n } else {\n requireElement(model, source);\n requireElement(model, target);\n }\n const id = input.id ?? (options.createId ?? defaultIdGenerator)();\n if (model.elements.has(id) || model.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n const link: IstarLink = withoutUndefined({\n id,\n kind: input.kind,\n source,\n target,\n label: input.label,\n name: input.name,\n customProperties: input.customProperties,\n });\n return {\n ok: true,\n model: derive(model, { links: new Map(model.links).set(id, link) }),\n link,\n reversed,\n };\n}\n\nexport interface NewDependency {\n /** The depender: an actor or one of its inner elements. */\n readonly depender: string;\n /** The dependee: an actor or one of its inner elements. */\n readonly dependee: string;\n readonly dependum: {\n readonly kind: NodeKind;\n readonly name?: string;\n readonly id?: string;\n /** Defaults to the midpoint between depender and dependee, as in piStar. */\n readonly x?: number;\n readonly y?: number;\n readonly customProperties?: CustomProperties;\n };\n readonly linkIds?: readonly [string, string];\n}\n\nexport type AddDependencyResult =\n | {\n ok: true;\n model: IstarModel;\n dependum: IstarElement;\n links: readonly [IstarLink, IstarLink];\n }\n | Extract<LinkCheck, { ok: false }>;\n\n/** Adds depender → dependum → dependee. */\nexport function addDependency(\n model: IstarModel,\n input: NewDependency,\n options: Omit<ConnectOptions, 'tryReversed'> = {},\n): AddDependencyResult {\n if (!isNodeKind(input.dependum.kind)) {\n throw new ModelOperationError(`${input.dependum.kind} cannot be a dependum`);\n }\n if (!options.force) {\n const check = canLink(model, input.depender, input.dependee, 'istar.DependencyLink');\n if (!check.ok) return check;\n }\n const depender = requireElement(model, input.depender);\n const dependee = requireElement(model, input.dependee);\n const createId = options.createId ?? defaultIdGenerator;\n const added = addElement(\n model,\n {\n kind: input.dependum.kind,\n id: input.dependum.id,\n name: input.dependum.name,\n x: input.dependum.x ?? (depender.x + dependee.x) / 2,\n y: input.dependum.y ?? (depender.y + dependee.y) / 2,\n customProperties: input.dependum.customProperties,\n },\n { createId },\n );\n const dependum: IstarElement = { ...added.element, isDependum: true };\n const [id1, id2] = input.linkIds ?? [createId(), createId()];\n const first: IstarLink = {\n id: id1,\n kind: 'istar.DependencyLink',\n source: depender.id,\n target: dependum.id,\n };\n const second: IstarLink = {\n id: id2,\n kind: 'istar.DependencyLink',\n source: dependum.id,\n target: dependee.id,\n };\n for (const id of [id1, id2]) {\n if (added.model.elements.has(id) || added.model.links.has(id) || id1 === id2) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n }\n return {\n ok: true,\n model: derive(model, {\n elements: new Map(added.model.elements).set(dependum.id, dependum),\n links: new Map(model.links).set(id1, first).set(id2, second),\n }),\n dependum,\n links: [first, second],\n };\n}\n\n/** Removes a link. Removing either half of a dependency removes the whole dependency. */\nexport function disconnect(model: IstarModel, id: string): IstarModel {\n requireLink(model, id);\n return removeCascade(model, new Set(), new Set([id]));\n}\n\nexport interface LinkPatch {\n /** `null` removes it. */\n readonly label?: string | null;\n readonly name?: string | null;\n readonly customProperties?: CustomProperties | null;\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction pick<T>(value: T | null | undefined, fallback: T | undefined): T | undefined {\n return value === undefined ? fallback : (value ?? undefined);\n}\n\nexport function updateLink(model: IstarModel, id: string, patch: LinkPatch): IstarModel {\n const current = requireLink(model, id);\n const next: IstarLink = withoutUndefined({\n ...current,\n label: pick(patch.label, current.label),\n name: pick(patch.name, current.name),\n customProperties: pick(patch.customProperties, current.customProperties),\n display: mergeDisplay<LinkDisplay>(current.display, patch.display),\n });\n return derive(model, { links: new Map(model.links).set(id, next) });\n}\n\n// ---------------------------------------------------------------------------------------------\n// Diagram\n\nexport function updateDiagram(model: IstarModel, patch: Partial<Diagram>): IstarModel {\n return derive(model, { diagram: withoutUndefined({ ...model.diagram, ...patch }) });\n}\n\n/** Where dependency depender/dependee currently point (see `dependencyLinksOf`). */\nexport function dependencyEnds(\n model: IstarModel,\n dependumId: string,\n): { depender?: string; dependee?: string } {\n const { inbound, outbound } = dependencyLinksOf(model, dependumId);\n const fallback = model.elements.get(dependumId)?.dependency;\n return {\n depender: inbound?.source ?? fallback?.source,\n dependee: outbound?.target ?? fallback?.target,\n };\n}\n","/**\n * An event-emitting store around an immutable `IstarModel`, with undo/redo.\n *\n * Every mutation produces a new model snapshot; history is a stack of snapshots, which is cheap\n * because unchanged elements and links are shared between snapshots. This replaces piStar's\n * `undoManager.js`, which stacked hand-written undo closures.\n *\n * `subscribe` + `getModel` match React's `useSyncExternalStore` contract.\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { LinkKind } from './metamodel';\nimport type { Diagram, IstarElement, IstarModel } from './model';\nimport { createEmptyModel } from './model';\nimport type {\n ConnectOptions,\n ElementPatch,\n IdGenerator,\n LinkPatch,\n NewDependency,\n NewElement,\n NewLink,\n} from './operations';\nimport * as ops from './operations';\n\n/** What happened, for listeners that want more than the new snapshot. */\nexport type ModelChange =\n | { type: 'addElement'; id: string }\n | { type: 'updateElement'; id: string; patch: ElementPatch }\n | { type: 'moveElement'; id: string; x: number; y: number }\n | { type: 'nestElement'; id: string; parent: string | null }\n | { type: 'removeElements'; ids: readonly string[] }\n | { type: 'connect'; id: string }\n | { type: 'addDependency'; dependumId: string; linkIds: readonly [string, string] }\n | { type: 'updateLink'; id: string; patch: LinkPatch }\n | { type: 'disconnect'; id: string }\n | { type: 'updateDiagram'; patch: Partial<Diagram> }\n | { type: 'replace' };\n\nexport interface ModelChangeEvent {\n readonly model: IstarModel;\n readonly previous: IstarModel;\n /** `undo`/`redo`/`load` carry no changes; a transaction carries all of its changes. */\n readonly changes: readonly ModelChange[];\n readonly source: 'edit' | 'undo' | 'redo' | 'load';\n}\n\nexport type ModelListener = (event: ModelChangeEvent) => void;\n\nexport interface ModelStoreOptions {\n readonly createId?: IdGenerator;\n /** Maximum number of undo steps kept. Default 100. */\n readonly historyLimit?: number;\n}\n\nexport interface ModelStore {\n getModel(): IstarModel;\n /** Returns an unsubscribe function. */\n subscribe(listener: ModelListener): () => void;\n\n canLink(source: string | IstarElement, target: string | IstarElement, kind: LinkKind): LinkCheck;\n\n addElement(input: NewElement): IstarElement;\n updateElement(id: string, patch: ElementPatch): void;\n moveElement(id: string, x: number, y: number): void;\n nestElement(id: string, parent: string | null): void;\n removeElement(id: string): void;\n removeElements(ids: Iterable<string>): void;\n setCollapsed(actorId: string, collapsed: boolean): void;\n\n connect(input: NewLink, options?: Omit<ConnectOptions, 'createId'>): ops.ConnectResult;\n addDependency(\n input: NewDependency,\n options?: Omit<ConnectOptions, 'createId' | 'tryReversed'>,\n ): ops.AddDependencyResult;\n updateLink(id: string, patch: LinkPatch): void;\n disconnect(id: string): void;\n updateDiagram(patch: Partial<Diagram>): void;\n\n /** Replaces the model as one undoable edit. */\n replace(model: IstarModel): void;\n /** Replaces the model and clears history (like opening a file in piStar). */\n load(model: IstarModel): void;\n\n /**\n * Groups several edits into one undo step and one change event. Nested calls join the\n * outermost transaction. If `fn` throws, the model is rolled back.\n */\n transaction<T>(fn: () => T): T;\n\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n clearHistory(): void;\n}\n\nexport function createModelStore(\n initial: IstarModel = createEmptyModel(),\n options: ModelStoreOptions = {},\n): ModelStore {\n const limit = options.historyLimit ?? 100;\n const ctx = { createId: options.createId ?? ops.defaultIdGenerator };\n const listeners = new Set<ModelListener>();\n let model = initial;\n let past: IstarModel[] = [];\n let future: IstarModel[] = [];\n let tx: { start: IstarModel; changes: ModelChange[]; depth: number } | undefined;\n\n const emit = (event: ModelChangeEvent): void => {\n for (const listener of listeners) listener(event);\n };\n\n const commit = (next: IstarModel, change: ModelChange): void => {\n if (next === model) return;\n if (tx) {\n model = next;\n tx.changes.push(change);\n return;\n }\n const previous = model;\n past.push(previous);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n model = next;\n emit({ model, previous, changes: [change], source: 'edit' });\n };\n\n const store: ModelStore = {\n getModel: () => model,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n canLink: (source, target, kind) => canLink(model, source, target, kind),\n\n addElement(input) {\n const result = ops.addElement(model, input, ctx);\n commit(result.model, { type: 'addElement', id: result.element.id });\n return result.element;\n },\n updateElement(id, patch) {\n commit(ops.updateElement(model, id, patch), { type: 'updateElement', id, patch });\n },\n moveElement(id, x, y) {\n commit(ops.moveElement(model, id, x, y), { type: 'moveElement', id, x, y });\n },\n nestElement(id, parent) {\n commit(ops.nestElement(model, id, parent), { type: 'nestElement', id, parent });\n },\n removeElement(id) {\n commit(ops.removeElement(model, id), { type: 'removeElements', ids: [id] });\n },\n removeElements(ids) {\n const list = [...ids];\n commit(ops.removeElements(model, list), { type: 'removeElements', ids: list });\n },\n setCollapsed(actorId, collapsed) {\n const patch = { display: { collapsed: collapsed ? true : undefined } };\n commit(ops.updateElement(model, actorId, patch), {\n type: 'updateElement',\n id: actorId,\n patch,\n });\n },\n\n connect(input, connectOptions) {\n const result = ops.connect(model, input, { ...connectOptions, ...ctx });\n if (result.ok) commit(result.model, { type: 'connect', id: result.link.id });\n return result;\n },\n addDependency(input, dependencyOptions) {\n const result = ops.addDependency(model, input, { ...dependencyOptions, ...ctx });\n if (result.ok) {\n commit(result.model, {\n type: 'addDependency',\n dependumId: result.dependum.id,\n linkIds: [result.links[0].id, result.links[1].id],\n });\n }\n return result;\n },\n updateLink(id, patch) {\n commit(ops.updateLink(model, id, patch), { type: 'updateLink', id, patch });\n },\n disconnect(id) {\n commit(ops.disconnect(model, id), { type: 'disconnect', id });\n },\n updateDiagram(patch) {\n commit(ops.updateDiagram(model, patch), { type: 'updateDiagram', patch });\n },\n\n replace(next) {\n commit(next, { type: 'replace' });\n },\n load(next) {\n if (tx) throw new ops.ModelOperationError('cannot load inside a transaction');\n const previous = model;\n model = next;\n past = [];\n future = [];\n emit({ model, previous, changes: [], source: 'load' });\n },\n\n transaction<T>(fn: () => T): T {\n if (tx) {\n tx.depth++;\n try {\n return fn();\n } finally {\n tx.depth--;\n }\n }\n tx = { start: model, changes: [], depth: 1 };\n let result: T;\n try {\n result = fn();\n } catch (error) {\n model = tx.start;\n tx = undefined;\n throw error;\n }\n const { start, changes } = tx;\n tx = undefined;\n if (model !== start) {\n past.push(start);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n emit({ model, previous: start, changes, source: 'edit' });\n }\n return result;\n },\n\n undo() {\n const previous = past.pop();\n if (!previous || tx) return false;\n future.push(model);\n const current = model;\n model = previous;\n emit({ model, previous: current, changes: [], source: 'undo' });\n return true;\n },\n redo() {\n const next = future.pop();\n if (!next || tx) return false;\n past.push(model);\n const current = model;\n model = next;\n emit({ model, previous: current, changes: [], source: 'redo' });\n return true;\n },\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n clearHistory() {\n past = [];\n future = [];\n },\n };\n return store;\n}\n","import type { ElementKind, LinkKind } from './metamodel';\nimport type { CustomProperties, IstarModel } from './model';\n\nexport type PropertyResult<T> = { ok: true; value: T } | { ok: false; error: string };\n\nexport interface PropertyOptions<T> {\n default?: T;\n optional?: boolean;\n label?: string;\n description?: string;\n}\n\nexport interface PropertyType<T> {\n readonly type: 'string' | 'number' | 'boolean' | 'enum';\n readonly options: PropertyOptions<T>;\n readonly values?: readonly string[];\n readonly integer?: boolean;\n readonly min?: number;\n readonly max?: number;\n parse(raw: string): PropertyResult<T>;\n serialize(value: T): string;\n}\n\nexport function string(options?: PropertyOptions<string>): PropertyType<string> {\n const opts: PropertyOptions<string> = options ?? {};\n return {\n type: 'string',\n options: opts,\n parse(raw: string): PropertyResult<string> {\n return { ok: true, value: raw };\n },\n serialize(value: string): string {\n return value;\n },\n };\n}\n\nexport function number(\n options?: PropertyOptions<number> & { integer?: boolean; min?: number; max?: number },\n): PropertyType<number> {\n const opts: PropertyOptions<number> = options ?? {};\n const integer = options?.integer;\n const min = options?.min;\n const max = options?.max;\n return {\n type: 'number',\n options: opts,\n integer,\n min,\n max,\n parse(raw: string): PropertyResult<number> {\n const value = Number(raw);\n if (!Number.isFinite(value)) {\n return { ok: false, error: 'must be a finite number' };\n }\n if (integer && !Number.isInteger(value)) {\n return { ok: false, error: 'must be an integer' };\n }\n if (min !== undefined && value < min) {\n return { ok: false, error: `must be at least ${min}` };\n }\n if (max !== undefined && value > max) {\n return { ok: false, error: `must be at most ${max}` };\n }\n return { ok: true, value };\n },\n serialize(value: number): string {\n return String(value);\n },\n };\n}\n\nexport function boolean(options?: PropertyOptions<boolean>): PropertyType<boolean> {\n const opts: PropertyOptions<boolean> = options ?? {};\n return {\n type: 'boolean',\n options: opts,\n parse(raw: string): PropertyResult<boolean> {\n if (raw === 'true') return { ok: true, value: true };\n if (raw === 'false') return { ok: true, value: false };\n return { ok: false, error: 'must be true or false' };\n },\n serialize(value: boolean): string {\n return value ? 'true' : 'false';\n },\n };\n}\n\nexport function enumOf<const V extends readonly string[]>(\n values: V,\n options?: PropertyOptions<V[number]>,\n): PropertyType<V[number]> {\n const opts: PropertyOptions<V[number]> = options ?? {};\n return {\n type: 'enum',\n options: opts,\n values,\n parse(raw: string): PropertyResult<V[number]> {\n if ((values as readonly string[]).includes(raw)) {\n return { ok: true, value: raw as V[number] };\n }\n return { ok: false, error: `must be one of: ${values.join(', ')}` };\n },\n serialize(value: V[number]): string {\n return value;\n },\n };\n}\n\nexport const prop: {\n string: typeof string;\n number: typeof number;\n boolean: typeof boolean;\n enum: typeof enumOf;\n} = {\n string,\n number,\n boolean,\n enum: enumOf,\n};\n\nexport type PropertyShape = Record<string, PropertyType<unknown>>;\n\nexport type InferProperties<S extends PropertyShape> = {\n [K in keyof S]: S[K] extends PropertyType<infer T> ? T : never;\n};\n\nexport interface PropertyIssue {\n key: string;\n message: string;\n}\n\nexport interface PropertySchema<S extends PropertyShape = PropertyShape> {\n readonly kind: ElementKind | LinkKind;\n readonly shape: S;\n read(source: CustomProperties | undefined | PropertyOwner): {\n values: Partial<InferProperties<S>>;\n issues: PropertyIssue[];\n };\n validate(source: CustomProperties | undefined | PropertyOwner): PropertyIssue[];\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties;\n defaults(): CustomProperties;\n}\n\n/** An element or link, read through its `customProperties`. */\nexport interface PropertyOwner {\n readonly kind: string;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface ModelPropertyIssue extends PropertyIssue {\n id: string;\n}\n\ntype PropertySource = CustomProperties | undefined | PropertyOwner;\n\nfunction isCustomPropertiesRecord(source: NonNullable<PropertySource>): source is CustomProperties {\n // Elements and links are passed whole, possibly without `customProperties`; recognize them by\n // their `istar.*` kind and numeric/structural fields a bag of strings can't have.\n if ('customProperties' in source) return false;\n const owner = source as { kind?: unknown; x?: unknown; source?: unknown; target?: unknown };\n const isModelObject =\n typeof owner.kind === 'string' &&\n owner.kind.startsWith('istar.') &&\n (typeof owner.x === 'number' || (owner.source !== undefined && owner.target !== undefined));\n return !isModelObject;\n}\n\nfunction resolveCustomProperties(source: PropertySource): CustomProperties | undefined {\n if (source === undefined) return undefined;\n if (isCustomPropertiesRecord(source)) return source;\n return source.customProperties;\n}\n\nfunction isRequired(options: PropertyOptions<unknown>): boolean {\n return options.optional !== true && options.default === undefined;\n}\n\nfunction emptyMeansAbsent(\n type: PropertyType<unknown>['type'],\n optional: boolean | undefined,\n): boolean {\n return type !== 'string' && optional === true;\n}\n\nfunction readShape<S extends PropertyShape>(\n shape: S,\n source: PropertySource,\n): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n const custom = resolveCustomProperties(source);\n const values: Partial<InferProperties<S>> = {};\n const issues: PropertyIssue[] = [];\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const opts = field.options;\n const hasKey = custom !== undefined && Object.prototype.hasOwnProperty.call(custom, key);\n const raw = hasKey ? custom[key] : undefined;\n\n if (raw === undefined) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n } else if (isRequired(opts)) {\n issues.push({ key, message: 'is required' });\n }\n continue;\n }\n\n if (raw === '' && field.type !== 'string') {\n if (emptyMeansAbsent(field.type, opts.optional)) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n }\n continue;\n }\n issues.push({\n key,\n message:\n field.type === 'boolean'\n ? 'must be true or false'\n : field.type === 'enum'\n ? `must be one of: ${field.values?.join(', ') ?? ''}`\n : 'must be a finite number',\n });\n continue;\n }\n\n const parsed = field.parse(raw);\n if (!parsed.ok) {\n issues.push({ key, message: parsed.error });\n continue;\n }\n (values as Record<string, unknown>)[key] = parsed.value;\n }\n\n return { values, issues };\n}\n\nexport function defineProperties<const S extends PropertyShape>(\n kind: ElementKind | LinkKind,\n shape: S,\n options?: { validate?: (values: Partial<InferProperties<S>>) => PropertyIssue[] },\n): PropertySchema<S> {\n const crossValidate = options?.validate;\n\n return {\n kind,\n shape,\n read(source: PropertySource): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n return readShape(shape, source);\n },\n validate(source: PropertySource): PropertyIssue[] {\n const { values, issues } = readShape(shape, source);\n const cross = crossValidate ? crossValidate(values) : [];\n return [...issues, ...cross];\n },\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties {\n const result: Record<string, string> = {};\n const seen = new Set<string>();\n\n if (current) {\n for (const [key, value] of Object.entries(current)) {\n if (Object.prototype.hasOwnProperty.call(patch, key)) {\n const patched = patch[key as keyof S];\n if (patched === undefined) {\n continue;\n }\n const field = shape[key];\n if (field) {\n result[key] = field.serialize(patched as never);\n }\n } else {\n result[key] = value;\n }\n seen.add(key);\n }\n }\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n if (seen.has(key)) continue;\n if (!Object.prototype.hasOwnProperty.call(patch, key)) continue;\n const patched = patch[key];\n if (patched === undefined) continue;\n const field = shape[key];\n if (field) {\n result[key] = field.serialize(patched as never);\n }\n }\n\n return result;\n },\n defaults(): CustomProperties {\n const result: Record<string, string> = {};\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const def = field.options.default;\n if (def !== undefined) {\n result[key] = field.serialize(def as never);\n }\n }\n return result;\n },\n };\n}\n\nexport function validateModelProperties(\n model: IstarModel,\n schemas: readonly PropertySchema[],\n): ModelPropertyIssue[] {\n const byKind = new Map<ElementKind | LinkKind, PropertySchema[]>();\n for (const schema of schemas) {\n const list = byKind.get(schema.kind) ?? [];\n list.push(schema);\n byKind.set(schema.kind, list);\n }\n\n const issues: ModelPropertyIssue[] = [];\n\n for (const element of model.elements.values()) {\n const kindSchemas = byKind.get(element.kind);\n if (!kindSchemas) continue;\n for (const schema of kindSchemas) {\n for (const issue of schema.validate(element)) {\n issues.push({ ...issue, id: element.id });\n }\n }\n }\n\n for (const link of model.links.values()) {\n const kindSchemas = byKind.get(link.kind);\n if (!kindSchemas) continue;\n for (const schema of kindSchemas) {\n for (const issue of schema.validate(link)) {\n issues.push({ ...issue, id: link.id });\n }\n }\n }\n\n return issues;\n}\n"],"mappings":"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"}
|