import type { CanvasGraph } from './graph-projection.js'; import type { YarramateOperation } from './operations.js'; import type { RelationshipKind } from './profile.js'; /** * Drafting a relationship between two subjects already on a canvas. * * The point of doing this here rather than in the editor is that an editor * offering exactly {@link connectableKinds} cannot draw an edge `check` would * refuse with `YM404`, and that guarantee is about the ArchiMate table and the * compiler agreeing rather than about any user interface. These functions are * pure and hold no React, so the property can be tested by compiling what they * produce. * * Everything here reads the rendered graph, which is what a canvas has, rather * than the compiled model, which it does not. */ /** * The relationship kinds ArchiMate permits from one subject to another, sorted * so a palette is stable between renders. * * Empty when either endpoint is unknown to the graph, or when its kind does not * resolve to a core one - an extension kind outside the ArchiMate vocabulary * has no row in the table, and guessing a row for it would be inventing * permission the compiler never granted. `association` is in every non-empty * answer, so a pair the table knows is never a dead end. */ export declare const connectableKinds: (graph: CanvasGraph, fromId: string, toId: string) => readonly RelationshipKind[]; /** * An id for a new relationship, unique across the graph. * * `--` reads as the sentence the relationship makes and is * already valid: a subject id is lowercase and hyphenated, and every core * relationship kind is a single lowercase word. A collision takes a numeric * suffix rather than a hash, because the id is authored text a human will read * in a diff. * * `reserved` carries ids the graph does not know yet: a staged-but-uncommitted * draft never enters the rendered graph, so without it a second relationship * between the same pair re-proposed the identical id and the editor's * replace-by-target staging silently swallowed the first (#306). The schema * places no uniqueness on the (from, kind, to) triple - parallel relationships * with distinct ids compile cleanly - so the id proposal is the only place the * collision can be stepped past. */ export declare const proposeRelationshipId: (graph: CanvasGraph, fromId: string, kind: RelationshipKind, toId: string, reserved?: Iterable) => string; /** * The operation that lands a drafted relationship, or `null` when the draft is * one the table does not permit. * * Refusing here rather than trusting the caller is what makes the guarantee * hold for any caller, not only for an editor that remembered to filter its * palette first. * * The relationship is written into the *source* subject's document. A * relationship has to live somewhere, both endpoints are equally defensible, * and the source is where a reader looking for what this thing does would go * first. * * A caller holding drafts the graph has not landed yet - an editor with a * pending changeset - passes their ids as `reserved`, so a second parallel * relationship steps to `-2` instead of colliding with the first (#306). */ export declare const draftRelationship: (graph: CanvasGraph, fromId: string, kind: RelationshipKind, toId: string, reserved?: Iterable) => YarramateOperation | null; /** * The ids a pending changeset already claims, for `proposeRelationshipId`'s * `reserved` parameter. Every operation that names a subject id reserves it - * an update's id is already in the graph and reserving it twice is harmless, * while an add's id is exactly the one the graph cannot know yet. */ export declare const stagedSubjectIds: (operations: readonly YarramateOperation[]) => readonly string[];