/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { ChangeFamily, ChangeRebaser, TaggedChange, AnchorSet, ChangeFamilyEditor, DeltaFieldMap, DeltaRoot, ChangeFamilyCodec, ChangeEncodingContext } from "../core/index.js";
import { IJsonCodec } from "../codec/index.js";
import { JsonCompatibleReadOnly, RecursiveReadonly } from "../util/index.js";
export interface NonEmptyTestChange {
    /**
     * Identifies the document state that the change should apply to.
     * Represented as the concatenation of all previous intentions.
     */
    inputContext: number[];
    /**
     * Identifies the document state brought about by applying the change to the document.
     * Represented as the concatenation of all previous intentions and the intentions in this change.
     */
    outputContext: number[];
    /**
     * Identifies the editing intentions included in the change.
     * Editing intentions can be thought of as user actions, where each user action is unique.
     * Editing intentions can be inverted (represented negative number of the same magnitude) but are
     * otherwise unchanged by rebasing.
     */
    intentions: number[];
}
export interface EmptyTestChange {
    intentions: [];
}
export type TestChange = NonEmptyTestChange | EmptyTestChange;
declare function mint(inputContext: readonly number[], intention: number | number[]): NonEmptyTestChange;
declare function compose(change1: TestChange | undefined, change2: TestChange | undefined, verify?: boolean): TestChange;
declare function composeList(changes: TestChange[], verify?: boolean): TestChange;
declare function invert(change: TestChange): TestChange;
declare function rebase(change: TestChange | undefined, over: TestChange | undefined): TestChange | undefined;
declare function checkChangeList(changes: readonly RecursiveReadonly<TestChange>[], intentions: number[]): void;
declare function toDelta({ change }: TaggedChange<TestChange>): DeltaFieldMap;
export interface AnchorRebaseData {
    rebases: RecursiveReadonly<NonEmptyTestChange>[];
    intentions: number[];
}
export declare const TestChange: {
    emptyChange: EmptyTestChange;
    mint: typeof mint;
    compose: typeof compose;
    composeList: typeof composeList;
    invert: typeof invert;
    rebase: typeof rebase;
    checkChangeList: typeof checkChangeList;
    toDelta: typeof toDelta;
    isEmpty: typeof isEmpty;
    codec: IJsonCodec<TestChange, JsonCompatibleReadOnly, JsonCompatibleReadOnly, ChangeEncodingContext> & ChangeFamilyCodec<TestChange>;
};
export declare class TestChangeRebaser implements ChangeRebaser<TestChange> {
    compose(changes: TaggedChange<TestChange>[]): TestChange;
    invert(change: TaggedChange<TestChange>): TestChange;
    rebase(change: TestChange, over: TaggedChange<TestChange>): TestChange;
}
export declare class UnrebasableTestChangeRebaser extends TestChangeRebaser {
    rebase(change: TestChange, over: TaggedChange<TestChange>): TestChange;
}
export declare class NoOpChangeRebaser extends TestChangeRebaser {
    rebasedCount: number;
    invertedCount: number;
    composedCount: number;
    rebase(change: TestChange, over: TaggedChange<TestChange>): TestChange;
    invert(change: TaggedChange<TestChange>): TestChange;
    compose(changes: TaggedChange<TestChange>[]): TestChange;
}
export declare class ConstrainedTestChangeRebaser extends TestChangeRebaser {
    private readonly constraint;
    constructor(constraint: (change: TestChange, over: TaggedChange<TestChange>) => boolean);
    rebase(change: TestChange, over: TaggedChange<TestChange>): TestChange;
}
export declare class TestAnchorSet extends AnchorSet implements AnchorRebaseData {
    rebases: RecursiveReadonly<NonEmptyTestChange>[];
    intentions: number[];
}
export type TestChangeFamily = ChangeFamily<ChangeFamilyEditor, TestChange>;
/**
 * This is a hack to encode arbitrary information (the intentions) into a Delta
 * The resulting Delta does not represent a concrete change to a document tree.
 * It is instead used as composite value in deep comparisons that verify that `EditManager` calls
 * `ChangeFamily.intoDelta` with the expected change.
 */
export declare function asDelta(intentions: number[]): DeltaRoot;
export declare function testChangeFamilyFactory(rebaser?: ChangeRebaser<TestChange>): ChangeFamily<ChangeFamilyEditor, TestChange>;
export declare function isEmpty(change: TestChange): boolean;
export {};
//# sourceMappingURL=testChange.d.ts.map