/**
 * Options available for doing diffs. Currently no options are defined.
 *
 * @public
 */
type DiffOptions = Record<string, never>;
/**
 * The recognized diff value types
 *
 * @public
 */
type ValueType = 'array' | 'boolean' | 'null' | 'number' | 'object' | 'string' | 'undefined';
/**
 * An "input" holds the _type_ of the value, the actual value, an optional annotation,
 * along with potential helper methods and properties, which vary dependending on the type
 *
 * @public
 */
type Input<T> = NumberInput<T> | BooleanInput<T> | StringInput<T> | NullInput<T> | ObjectInput<T> | ArrayInput<T>;
/**
 * Shared properties for all input types
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface BaseInput<A> {
  annotation: A;
}
/**
 * Input type for strings, which supports slicing parts of the string while maintaining the
 * annotation of the parent.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface StringInput<A> extends BaseInput<A> {
  type: 'string';
  value: string;
  sliceAnnotation(start: number, end: number): {
    text: string;
    annotation: A;
  }[];
}
/**
 * Input type for numbers.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface NumberInput<A> extends BaseInput<A> {
  type: 'number';
  value: number;
}
/**
 * Input type for booleans.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface BooleanInput<A> extends BaseInput<A> {
  type: 'boolean';
  value: boolean;
}
/**
 * Input type for `null` values.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface NullInput<A> extends BaseInput<A> {
  type: 'null';
  value: null;
}
/**
 * Input type for object values. Caches the available keys, and allows retrieval of properties,
 * while automatically wrapping the retrieved property in a typed input container.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface ObjectInput<A> extends BaseInput<A> {
  type: 'object';
  /**
   * The actual object value
   */
  value: Record<string, unknown>;
  /**
   * The keys of the object
   */
  keys: string[];
  /**
   * Retrieve the property with the given `key`, automatically wrapping it in an input container.
   *
   * @param key - The key of the property you want to retrieve.
   * @returns Typed input container, or `undefined` if the property does not exist
   */
  get(key: string): Input<A> | undefined;
}
/**
 * Input type for array values. Helper functions are available for getting the item and/or
 * annotation at a given index.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface ArrayInput<A> extends BaseInput<A> {
  type: 'array';
  /**
   * The actual array value
   */
  value: unknown[];
  /**
   * The length of the array
   */
  length: number;
  /**
   * Retrieve the value at the given `index`, automatically wrapping it in an input container.
   *
   * @param index - The index of the item to retrieve
   * @returns Typed input container, or `undefined` if the item does not exist
   */
  at(index: number): Input<A>;
  /**
   * Retrieve the _annotation_ for an item at the given index
   *
   * @param index - The index of the item to fetch the annotation for
   * @returns The annotation at the given index, or `undefined` if the item does not exist
   */
  annotationAt(index: number): A;
}
/**
 * Diff for something that has been added - eg a property in an object,
 * an item in an array, a segment of a string or similar.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Value. The type of the destination (eg `after` or `to`) value.
 * @public
 */
interface AddedDiff<A, V> {
  action: 'added';
  isChanged: true;
  fromValue: null | undefined;
  toValue: V;
  annotation: A;
}
/**
 * Diff for something that has been removed - eg a property in an object,
 * an item in an array, a segment of a string or similar.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Value. The type of the source (eg `before` or `from`) value.
 * @public
 */
interface RemovedDiff<A, V> {
  action: 'removed';
  isChanged: true;
  fromValue: V;
  toValue: null | undefined;
  annotation: A;
}
/**
 * Diff for something that has changed - eg it was not added or removed, but the
 * value has changed "in place". Note that {@link TypeChangeDiff} is used for values that change
 * their _type_, thus the `V` type parameter represents both the source and the destination value
 * in this type.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Value. The type of the value.
 * @public
 */
interface ChangedDiff<A, V> {
  action: 'changed';
  isChanged: true;
  fromValue: V;
  toValue: V;
  annotation: A;
}
/**
 * Diff (or lack thereof, in this case) for a value that has _not_ changed.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Value. The type of the destination (eg `after`) value.
 * @public
 */
interface UnchangedDiff<A, V> {
  action: 'unchanged';
  isChanged: false;
  fromValue: V;
  toValue: V;
}
/**
 * Diff with all the possible diff types.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Value. Type of the value repesented in the diff.
 * @public
 */
type FullDiff<A, V> = AddedDiff<A, V> | RemovedDiff<A, V> | ChangedDiff<A, V> | UnchangedDiff<A, V>;
/**
 * Diff of a string. Holds an additional array of string _segments_,
 * indicating which portions of the string is changed/unchanged.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type StringDiff<A> = FullDiff<A, string> & {
  type: 'string';
  segments: StringDiffSegment<A>[];
};
/**
 * Diff of a number.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type NumberDiff<A> = FullDiff<A, number> & {
  type: 'number';
};
/**
 * Diff of a boolean.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type BooleanDiff<A> = FullDiff<A, boolean> & {
  type: 'boolean';
};
/**
 * Diff for a value that has changed from one type to another.
 * For example, an object property going from `null` to `string`.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface TypeChangeDiff<A> {
  type: 'typeChange';
  action: 'changed';
  isChanged: true;
  fromType: string;
  fromValue: unknown;
  fromDiff: Diff<A> & {
    action: 'removed';
  };
  toType: string;
  toValue: unknown;
  toDiff: Diff<A> & {
    action: 'added';
  };
  annotation: A;
}
/**
 * Diff for an object value.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam T - Value type.
 * @public
 */
type ObjectDiff<A, T extends object = Record<string, any>> = FullDiff<A, T> & {
  type: 'object';
  fields: Record<keyof T, Diff<A>>;
};
/**
 * Diff for an array value.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @typeParam V - Item value type.
 * @public
 */
type ArrayDiff<A, V = unknown> = FullDiff<A, V[]> & {
  type: 'array';
  items: ItemDiff<A>[];
};
/**
 * Diff for a `null` value.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type NullDiff<A> = FullDiff<A, null> & {
  type: 'null';
};
/**
 * Diff for any value type.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type Diff<A> = NullDiff<A> | StringDiff<A> | NumberDiff<A> | BooleanDiff<A> | ObjectDiff<A> | ArrayDiff<A> | TypeChangeDiff<A>;
/**
 * Diff of a string segment (eg a portion/slice), and whether or not it was changed or unchanged.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
type StringDiffSegment<A> = StringSegmentChanged<A> | StringSegmentUnchanged;
/**
 * Diff of a string segment that has changed.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface StringSegmentChanged<A> {
  type: 'stringSegment';
  action: 'added' | 'removed';
  text: string;
  annotation: A;
}
/**
 * Diff of a string segment that is unchanged.
 *
 * @public
 */
interface StringSegmentUnchanged {
  type: 'stringSegment';
  action: 'unchanged';
  text: string;
}
/**
 * Diff of an item in an array, representing whether or not it has moved within the array,
 * and if so, which index it was moved from/to.
 *
 * If not moved, `fromIndex` and `toIndex` will have the same value.
 * If the item was added, `fromIndex` will be `undefined`.
 * If the item was removed, `toIndex` will be `undefined`.
 *
 * @typeParam A - Annotation. Timestamps, author and similar info is attached by Sanity, but anything is allowed.
 * @public
 */
interface ItemDiff<A> {
  fromIndex: number | undefined;
  toIndex: number | undefined;
  hasMoved: boolean;
  diff: Diff<A>;
  annotation: A;
}
/**
 * Takes a `from` and `to` input and calulates a diff between the two
 *
 * @param fromInput - The source (`from`) input - use {@link wrap | the wrap() method} to generate an "input"
 * @param toInput - The destination (`to`) input - use {@link wrap | the wrap() method} to generate an "input"
 * @param options - Options for the diffing process - currently no options are defined
 * @returns A diff object representing the change
 * @public
 */
declare function diffInput<A>(fromInput: Input<A>, toInput: Input<A>, options?: DiffOptions): Diff<A>;
/**
 * Takes an input (any JSON-serializable value) and an annotation, and generates an input
 * object for it, to be used with {@link diffInput | the diffInput() method} and others.
 *
 * @param input - The value to wrap in an input object
 * @param annotation - Annotation attached to the input - will be bound to generated diffs
 * @returns A input object
 * @throws if `input` is not a JSON-serializable type
 * @public
 */
declare function wrap<A>(input: unknown, annotation: A): Input<A>;
export { AddedDiff, ArrayDiff, ArrayInput, BaseInput, BooleanDiff, BooleanInput, ChangedDiff, Diff, DiffOptions, FullDiff, Input, ItemDiff, NullDiff, NullInput, NumberDiff, NumberInput, ObjectDiff, ObjectInput, RemovedDiff, StringDiff, StringDiffSegment, StringInput, StringSegmentChanged, StringSegmentUnchanged, TypeChangeDiff, UnchangedDiff, ValueType, diffInput, wrap };