import type { DesignDocument, DocumentDiagnostic, DocumentNode, DocumentNodePatch, DocumentTransaction, DocumentValue } from '../document/contracts.js'; import type { TokenLibraryDocument, TokenValueResolution } from './contracts.js'; export type VariableScalar = string | number | boolean; export interface VariableBinding { libraryId: string; tokenId: string; modeId?: string; } export type VariableBindings = Record; export type VariableValueCodec = (library: TokenLibraryDocument, resolved: TokenValueResolution) => VariableScalar; export type VariableModeProvider = { kind: 'binding'; } | { kind: 'node'; nodeId: string; } | { kind: 'instance'; instanceId: string; overrideAddress: string; } | { kind: 'default'; }; export interface VariableModeResolution { collectionId: string; /** The requested mode, even when an alias is authored in a fallback mode. */ modeId: string; provider: VariableModeProvider; visitedNodeIds: readonly string[]; } export interface VariableInstanceAddress { instanceId: string; overrideAddress: string; } export type VariableOccurrenceAddress = { nodeId: string; } | VariableInstanceAddress; export interface VariableOccurrencePlan { address: VariableOccurrenceAddress; property: VariableTarget; binding: VariableBinding; mode: VariableModeResolution; resolved: TokenValueResolution; value: VariableScalar; before: DocumentValue | undefined; /** Literal projection only. Binding identity and transaction ownership stay with the caller. */ patch: DocumentNodePatch; } export interface VariableChange { nodeId: string; overrideAddress?: string; property: string; tokenId: string; before: DocumentValue | undefined; after: VariableScalar; } export interface VariableUpdatePlan { documentFingerprint: string; libraryId: string; sourceRevision: string; libraryFingerprint: string; patches: { nodeId: string; overrideAddress?: string; patch: DocumentNodePatch; }[]; changes: VariableChange[]; diagnostics: DocumentDiagnostic[]; } export declare const VARIABLE_TARGETS: { readonly width: "number"; readonly height: "number"; readonly radius: "number"; readonly opacity: "number"; readonly fontSize: "number"; readonly fontWeight: "number"; readonly lineHeight: "number"; readonly letterSpacing: "number"; readonly text: "string"; readonly fontFamily: "string"; readonly fill: "string"; readonly color: "string"; readonly visible: "boolean"; readonly hidden: "boolean"; readonly clip: "boolean"; }; export type VariableTarget = keyof typeof VARIABLE_TARGETS; export declare function isVariableBinding(value: unknown): value is VariableBinding; export declare function nodeVariableBindings(node: Pick): VariableBindings; /** Built-in values are JSON scalars. Other syntax remains the host codec's responsibility. */ export declare function resolveScalarVariable(library: TokenLibraryDocument, resolved: TokenValueResolution, seen?: Set): VariableScalar; export declare function resolveVariableModeForNode(document: DesignDocument, nodeId: string, library: TokenLibraryDocument, tokenId: string, explicit?: string): VariableModeResolution; export declare function variableModeForNode(document: DesignDocument, nodeId: string, library: TokenLibraryDocument, tokenId: string, explicit?: string): string; /** Resolves an opaque override address through the actual component resolver. */ export declare function resolveVariableModeForInstance(document: DesignDocument, address: VariableInstanceAddress, library: TokenLibraryDocument, binding: VariableBinding): VariableModeResolution; export declare function variableTargetsForNode(node: DocumentNode): VariableTarget[]; /** Candidates use the same value projection as binding, without validating the library once per row. */ export declare function variableBindingChoices(document: DesignDocument, nodeId: string, property: VariableTarget, library: TokenLibraryDocument, codec?: VariableValueCodec): { token: import("./contracts.js").LibraryToken; mode: VariableModeResolution; value: VariableScalar; }[]; /** Override projection stays sparse; unrelated inherited properties never become local overrides. */ export declare function projectVariableScalar(node: DocumentNode, property: VariableTarget, value: VariableScalar, placement: 'own' | 'override'): DocumentNodePatch; /** Reads one occurrence without refreshing unrelated nodes or changing either document. */ export declare function planVariableOccurrence(document: DesignDocument, address: VariableOccurrenceAddress, property: VariableTarget, library: TokenLibraryDocument, codec?: VariableValueCodec): VariableOccurrencePlan; export declare function bindVariablePatch(document: DesignDocument, nodeId: string, property: VariableTarget, library: TokenLibraryDocument, binding: VariableBinding, codec?: VariableValueCodec): DocumentNodePatch; export declare function detachVariablePatch(node: DocumentNode, property: VariableTarget): DocumentNodePatch; /** A refresh plan records all affected nodes before the caller commits one history entry. */ export declare function planVariableLibraryUpdate(document: DesignDocument, library: TokenLibraryDocument, codec?: VariableValueCodec): VariableUpdatePlan; export declare function commitVariableLibraryUpdate(tx: DocumentTransaction, document: DesignDocument, plan: VariableUpdatePlan): void; export declare function commitVariableMode(tx: DocumentTransaction, document: DesignDocument, nodeId: string, library: TokenLibraryDocument, collectionId: string, modeId: string | null, codec?: VariableValueCodec): void; /** Literal projection does not claim that source code preserves the binding or mode relationship. */ export declare function variablesSourceDiagnostics(after: DesignDocument, before: DesignDocument): DocumentDiagnostic[];