/**
 * Entity projection — sparse EQL bindings ↔ plain entity records.
 *
 * Shared by the realtime subscription path (server hydrates before push) and
 * the client read layer (skips `read()` when rows are already full entities).
 *
 * @module trellis/schema
 */
import type { EntityData } from '../client/sdk.js';
/** Minimal kernel surface for hydration. */
export interface EntityReader {
    getEntity(id: string): EntityRecordLike | null;
}
export interface EntityRecordLike {
    id: string;
    type: string;
    facts: Array<{
        a: string;
        v: unknown;
    }>;
}
export declare function entityRecordToPlain(entity: EntityRecordLike): EntityData;
/** Extract an entity id from a query binding row. */
export declare function bindingEntityId(row: Record<string, unknown>): string | null;
/** True when the row is a sparse `{ e: id }` trigger, not a hydrated entity. */
export declare function isSparseBinding(row: Record<string, unknown>): boolean;
/** Normalize a binding row to {@link EntityData} (hydrated or sparse+partial). */
export declare function bindingToEntity(row: Record<string, unknown>): EntityData;
/**
 * Hydrate sparse subscription bindings to full entity records via the kernel.
 * Already-hydrated rows pass through unchanged.
 */
export declare function hydrateBindings(kernel: EntityReader, bindings: Record<string, unknown>[]): EntityData[];
//# sourceMappingURL=entity-projection.d.ts.map