/**
 * One child slot of a {@link ProjectionTransformer}'s fixed output layout: a run of static text, a
 * single static node/embed, or a single hole (filled by a sub-transformer's output).
 *
 * A hole's `carrier` records how its sub-transformer's output is placed: `'value'` lifts a
 * `lib0:value` carrier to a bare scalar embed (1 position, replaced on update); `'node'` embeds a
 * structural node verbatim (a nested `project`'s render, or a non-value carrier) and forwards its
 * incremental change as a `modify`. The kind is fixed once: known at `init` for auto-wrapped nested
 * projects, otherwise sniffed from the first render and cached (`lastScalar` keeps the last lifted
 * scalar so a view deletion of a value slot can be self-healed).
 *
 * @typedef {{ kind: 'text', str: string, format?: any, attribution?: any }
 *  | { kind: 'static', el: any, format?: any, attribution?: any }
 *  | { kind: 'hole', t: Transformer<any,any>, el: any, carrier?: 'value'|'node', lastScalar?: any, format?: any, attribution?: any }} ChildItem
 */
/**
 * Stateful transformer produced by {@link ProjectionTemplate}. Side A is the data (the
 * *projectionDelta*); side B is the projected structure - the spec with each hole filled by its
 * sub-transformer's output. `project` resolves the `lib0:value` carrier itself: at an *attribute*
 * position (keyed) and at a *child* position (positional, 1->1) it lifts the carrier to its bare
 * scalar. A child hole that is a nested `project` (or any non-`lib0:value` carrier) is embedded as a
 * node. A `lib0:inline` fragment is left intact for a downstream `inline(['lib0:inline'])`.
 *
 * The output layout is *fixed*: every hole occupies exactly one attribute or one child node, and
 * static content is constant. So `applyA` routes data changes into holes, and `applyB` routes view
 * edits at *node*-hole positions back to holes while **self-healing** edits to static content and to
 * value slots (a bare scalar has no `modify` channel, so a value-slot view edit is not round-tripped
 * to data in v1 - use an attribute hole for an editable binding).
 *
 * @extends {Transformer<any,any>}
 */
export class ProjectionTransformer extends Transformer<any, any> {
    /**
     * @param {import('../../schema.js').Schema<delta.Delta<any>>} $in
     * @param {import('../../schema.js').Schema<delta.Delta<any>>} $out
     * @param {string} name
     * @param {Array<{ key: string|number, value: any, attribution?: any }>} staticAttrs
     * @param {Array<{ key: string|number, t: Transformer<any,any> }>} attrHoles
     * @param {Array<ChildItem>} items child slots in output order
     */
    constructor($in: import("../../schema.js").Schema<delta.Delta<any>>, $out: import("../../schema.js").Schema<delta.Delta<any>>, name: string, staticAttrs: Array<{
        key: string | number;
        value: any;
        attribution?: any;
    }>, attrHoles: Array<{
        key: string | number;
        t: Transformer<any, any>;
    }>, items: Array<ChildItem>);
    name: string;
    staticAttrs: {
        key: string | number;
        value: any;
        attribution?: any;
    }[];
    attrHoles: {
        key: string | number;
        t: Transformer<any, any>;
    }[];
    items: ChildItem[];
    /**
     * @type {Array<{ start: number, len: number, item: ChildItem }>}
     */
    segs: Array<{
        start: number;
        len: number;
        item: ChildItem;
    }>;
    initialized: boolean;
    /**
     * Lift a child hole's sub-transformer output and place it on `out`. Returns the output count (1).
     * For a value carrier the bare scalar is inserted (and cached for self-heal); otherwise the node is
     * embedded verbatim. The hole's `carrier` kind is sniffed once here and cached.
     *
     * @param {delta.DeltaBuilderAny} out
     * @param {ChildItem & { kind: 'hole' }} item
     * @param {delta.DeltaAny?} rb the sub-transformer's B output
     */
    _placeHole(out: delta.DeltaBuilderAny, item: ChildItem & {
        kind: "hole";
    }, rb: delta.DeltaAny | null): void;
    /**
     * Initial render: emit the full structure with every hole filled.
     *
     * @param {delta.DeltaBuilderAny} d
     */
    _render(d: delta.DeltaBuilderAny): {
        a: delta.DeltaBuilder<any, false> | null;
        b: delta.DeltaBuilder<any, false> | null;
        isEmpty(): boolean;
        clear(): void;
        applyA(a: delta.DeltaBuilder<any, false> | null): /*elided*/ any;
        applyB(b: delta.DeltaBuilder<any, false> | null): /*elided*/ any;
        reverse(): /*elided*/ any;
    };
    /**
     * Incremental data change: emit only the hole updates. A value hole is *replaced*
     * (`delete(1).insert([scalar])`, since a scalar embed has no inner structure to modify); a node
     * hole forwards its sub-transformer's incremental change as a `modify`.
     *
     * @param {delta.DeltaBuilderAny} d
     */
    _update(d: delta.DeltaBuilderAny): {
        a: delta.DeltaBuilder<any, false> | null;
        b: delta.DeltaBuilder<any, false> | null;
        isEmpty(): boolean;
        clear(): void;
        applyA(a: delta.DeltaBuilder<any, false> | null): /*elided*/ any;
        applyB(b: delta.DeltaBuilder<any, false> | null): /*elided*/ any;
        reverse(): /*elided*/ any;
    };
    /**
     * Reconstruct the content occupying output positions `[start, start+len)` as insert ops on `out`
     * (used to self-heal a view delete). Static text/nodes are restored from the spec, and a value
     * slot is restored from its last-rendered scalar. Node-hole positions are skipped (their dynamic
     * structure cannot be restored without the current data).
     *
     * @param {delta.DeltaBuilderAny} out
     * @param {number} start
     * @param {number} len
     */
    _restore(out: delta.DeltaBuilderAny, start: number, len: number): void;
}
/**
 * Template that projects the *projectionDelta* onto a fixed structure described by `spec` - an
 * ordinary {@link import('../delta.js').create delta} whose attribute values and inserted children
 * may be transformer {@link Template templates} ("holes"). Each hole receives the whole
 * projectionDelta; its output is placed at that position. The spec is a *write-only template*: it is
 * walked once at {@link ProjectionTemplate#init} and never fingerprinted/diffed.
 *
 * Holes resolve themselves: a `lib0:value` carrier (produced by {@link import('./attr.js').attr}) is
 * lifted to a bare scalar; a nested subtree that contains a hole is **auto-wrapped** into a nested
 * `project` at `init`, so deep structure composes through nested templates with the recursion built
 * once (bounded by spec depth). Plain static subtrees are embedded verbatim.
 *
 * @template {delta.DeltaConf} [IN=any]
 * @template {delta.DeltaConf} [SpecConf=any]
 * @extends {Template<IN, ProjectOutput<SpecConf>>}
 */
export class ProjectionTemplate<IN extends delta.DeltaConf = any, SpecConf extends delta.DeltaConf = any> extends Template<IN, delta.DeltaConfOverwrite<delta.AsDeltaConf<Omit<SpecConf, "children" | "attrs"> & (SpecConf extends {
    attrs: infer A;
} ? {
    attrs: ResolveAttrs<A>;
} : {}) & (SpecConf extends {
    children: infer Ch;
} ? {
    children: ResolveChild<Ch>;
} : {})>, {}>> {
    /**
     * @param {import('../../schema.js').Schema<delta.Delta<IN>>} $d
     * @param {delta.Delta<SpecConf>} spec
     */
    constructor($d: import("../../schema.js").Schema<delta.Delta<IN>>, spec: delta.Delta<SpecConf>);
    spec: delta.Delta<SpecConf>;
}
export function project<IN extends delta.DeltaConf, SpecConf extends delta.DeltaConf>($d: import("../../schema.js").Schema<delta.Delta<IN>>, spec: delta.Delta<SpecConf>): ProjectionTemplate<IN, SpecConf>;
/**
 * Resolve a hole template's output conf `OUT` to its projected placement type: a `lib0:value` carrier
 * lifts to its bare scalar; any other node is embedded as a `Delta<OUT>`.
 */
export type ResolveHoleOut<OUT extends delta.DeltaConf> = OUT extends {
    name: "lib0:value";
    attrs: {
        value: infer V;
    };
} ? V : delta.Delta<OUT>;
/**
 * Resolve one spec child element to its projected output type, distributing over a children union: a
 * hole ({@link Template}, whose output conf the spec carries) resolves via its `OUT`, a nested spec
 * delta recurses, and anything else (text, a static scalar/node) is kept verbatim.
 */
export type ResolveChild<C> = C extends Template<any, infer OUT extends delta.DeltaConf> ? ResolveHoleOut<OUT> : C extends delta.Delta<infer NC extends delta.DeltaConf> ? delta.Delta<ProjectOutput<NC>> : C;
/**
 * Resolve a spec's attrs map: a hole attribute value resolves via its output conf; a static value is kept.
 */
export type ResolveAttrs<A> = { [K in keyof A]: A[K] extends Template<any, infer OUT extends delta.DeltaConf> ? ResolveHoleOut<OUT> : A[K]; };
/**
 * The concrete output conf of a `project($d, spec)` whose spec has conf `SpecConf`: static structure
 * is kept, value holes lift to their scalar, nested specs / node holes recurse. Holes are schema-bound
 * {@link Template}s, so their output conf is already concrete in `SpecConf` (no input param needed).
 */
export type ProjectOutput<SpecConf extends delta.DeltaConf> = import("./core.js").ResolveOut<delta.AsDeltaConf<Omit<SpecConf, "attrs" | "children"> & (SpecConf extends {
    attrs: infer A;
} ? {
    attrs: ResolveAttrs<A>;
} : {}) & (SpecConf extends {
    children: infer Ch;
} ? {
    children: ResolveChild<Ch>;
} : {})>>;
/**
 * One child slot of a {@link ProjectionTransformer}'s fixed output layout: a run of static text, a
 * single static node/embed, or a single hole (filled by a sub-transformer's output).
 *
 * A hole's `carrier` records how its sub-transformer's output is placed: `'value'` lifts a
 * `lib0:value` carrier to a bare scalar embed (1 position, replaced on update); `'node'` embeds a
 * structural node verbatim (a nested `project`'s render, or a non-value carrier) and forwards its
 * incremental change as a `modify`. The kind is fixed once: known at `init` for auto-wrapped nested
 * projects, otherwise sniffed from the first render and cached (`lastScalar` keeps the last lifted
 * scalar so a view deletion of a value slot can be self-healed).
 */
export type ChildItem = {
    kind: "text";
    str: string;
    format?: any;
    attribution?: any;
} | {
    kind: "static";
    el: any;
    format?: any;
    attribution?: any;
} | {
    kind: "hole";
    t: Transformer<any, any>;
    el: any;
    carrier?: "value" | "node";
    lastScalar?: any;
    format?: any;
    attribution?: any;
};
import { Transformer } from './core.js';
import * as delta from '../delta.js';
import { Template } from './core.js';
//# sourceMappingURL=project.d.ts.map