import type { RelationDef } from './types.js'; /** A relation name (and an inverse name): lowercase words joined by hyphens — * `blocks`, `blocked-by`, `relates-to`. The name becomes a query field and * an edge label, so the grammar is the expression lexer's ident shape. */ export declare const RELATION_NAME_RE: RegExp; /** The shape of a relation TARGET — a record uuid. RFC 4122 hex is * case-insensitive, which is why every comparison in this module folds. */ export declare const RECORD_UUID_RE: RegExp; /** How many targets one relation cell may hold. Past this the relation is a * query, not a cell — refused at the funnel (`record-relation-too-many`). */ export declare const RELATION_MAX_TARGETS = 64; /** The uuid list a relation cell holds, split and trimmed — TOTAL: null, * undefined, empty, and separator debris (`,,`) all answer cleanly. * Duplicates survive verbatim: parsing reports what the cell SAYS, so the * funnel's duplicate warn can see them; normalization is serialize's job. * * `empty` is the format's DECLARED empty markers (`def.emptyMarkers` — `—`, * `-`, `''` by default). A relation cell is an ordinary cell first: an author * who wrote the em dash the rest of the format reads as "nothing here" wrote * nothing here, and a parse that took `—` for an address would hand every * consumer a phantom target — a removable chip addressing an em dash, a first * write refused as `record-relation-not-uuid`, and a derived query field that * answers true for every record. Callers WITHOUT a definition (the write * funnel, which guards with `isEmptyCell` itself) pass nothing and get the * literal split. */ export declare function parseRelationCell(raw: string | null | undefined, empty?: Iterable | null): string[]; /** Targets back into one cell — comma-joined, one scalar, so the sidecar's * one-scalar-per-field rule is untouched. Order-preserving dedupe, folded: * the first spelling of a uuid wins and later duplicates (any case) drop. */ export declare function serializeRelationCell(targets: readonly string[]): string; /** The cell with `uuid` among its targets — appended when absent (case-folded), * byte-identical membership otherwise modulo the serialize normalization. */ export declare function relationCellWith(raw: string | null | undefined, uuid: string): string; /** The cell without `uuid` — every spelling of it (case-folded). Removing a * target that was never there is a no-op, not an error. */ export declare function relationCellWithout(raw: string | null | undefined, uuid: string): string; /** The definition shape this module reads — structural, so a compiled * definition, a test fixture and (later) a payload slice all qualify. */ export interface RelationsDefLike { blocks: Record; relations: ReadonlyMap; } /** The relations `block` CARRIES — those it declares a column for, in column * order, deduped. Empty for a block with no relation columns. */ export declare function relationsCarriedBy(def: RelationsDefLike, block: string): RelationDef[]; /** The relations `block` RECEIVES — those whose `to:` names it, in vocabulary * declaration order. Receiving is derived from the vocabulary alone: the * target block declares nothing (P6 — the inverse is a reading, not a column). */ export declare function relationsReceivedBy(def: RelationsDefLike, block: string): RelationDef[]; /** block → (column key → relation name), only for blocks that carry one — * the map P12 hands `buildGraph`, so an undeclared literal rel-ish column in * a markdown table emits nothing at all. */ export declare function relationColumnsOf(def: RelationsDefLike): ReadonlyMap>; /** The column whose cell a RECORD's chip prints as its title — one ladder, * shared by the graph's record nodes, the D.relations payload slice and (by * way of that slice) RecordChips, so every surface names a record the same * way: the dj/work title binding where the block is on the spine, else the * display column playing the CARD TITLE role, else the first declared column * that is not the id grammar's, else the first column. Structural over the * compiled block (like RelationsDefLike) — no BlockDef import, no display * type: this module stays types-only and bundle-safe. */ export declare function recordTitleKey(b: { columns: { key: string; idGrammar?: unknown; }[]; work?: { title: string; }; display?: unknown; }): string; /** The context fields a relation DERIVES for the query grammar (§2.1): a * directed relation derives its inverse reading's field (`blocked-by` → * `blocked_by`); a symmetric one derives the both-directions union under its * own name (`relates-to` → `relates_to`). Hyphens become underscores so the * expression lexer reads them as idents. The loader uses this for the * load-time collision check (`relation-derived-field-collision`); the rowCtx * fields themselves land with the query surface. */ export declare function relationDerivedFields(rel: Pick): string[];