/* tslint:disable */
/* eslint-disable */
/**
*/
export function run(): void;
/**
* @param {({ peer: PeerID, counter: number })[]} frontiers
* @returns {Uint8Array}
*/
export function encodeFrontiers(frontiers: ({ peer: PeerID, counter: number })[]): Uint8Array;
/**
* @param {Uint8Array} bytes
* @returns {{ peer: PeerID, counter: number }[]}
*/
export function decodeFrontiers(bytes: Uint8Array): { peer: PeerID, counter: number }[];
/**
* Enable debug info of Loro
*/
export function setDebug(): void;
/**
* Decode the metadata of the import blob.
*
* This method is useful to get the following metadata of the import blob:
*
* - startVersionVector
* - endVersionVector
* - startTimestamp
* - endTimestamp
* - isSnapshot
* - changeNum
* @param {Uint8Array} blob
* @returns {ImportBlobMetadata}
*/
export function decodeImportBlobMeta(blob: Uint8Array): ImportBlobMetadata;

/**
* Container types supported by loro.
*
* It is most commonly used to specify the type of sub-container to be created.
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* const containerType = "Text";
* const text = list.insertContainer(1, containerType);
* ```
*/
export type ContainerType = "Text" | "Map" | "List"| "Tree" | "MovableList";

export type PeerID = `${number}`;
/**
* The unique id of each container.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* const containerId = list.id;
* ```
*/
export type ContainerID =
  | `cid:root-${string}:${ContainerType}`
  | `cid:${number}@${PeerID}:${ContainerType}`;

/**
 * The unique id of each tree node.
 */
export type TreeID = `${number}@${PeerID}`;

interface LoroDoc {
    /**
     * Export updates from the specific version to the current version
     *
     * @deprecated Use `export({mode: "update", from: version})` instead
     *
     *  @example
     *  ```ts
     *  import { LoroDoc } from "loro-crdt";
     *
     *  const doc = new LoroDoc();
     *  const text = doc.getText("text");
     *  text.insert(0, "Hello");
     *  // get all updates of the doc
     *  const updates = doc.exportFrom();
     *  const version = doc.oplogVersion();
     *  text.insert(5, " World");
     *  // get updates from specific version to the latest version
     *  const updates2 = doc.exportFrom(version);
     *  ```
     */
    exportFrom(version?: VersionVector): Uint8Array;
    /**
     *
     *  Get the container corresponding to the container id
     *
     *
     *  @example
     *  ```ts
     *  import { LoroDoc } from "loro-crdt";
     *
     *  const doc = new LoroDoc();
     *  let text = doc.getText("text");
     *  const textId = text.id;
     *  text = doc.getContainerById(textId);
     *  ```
     */
    getContainerById(id: ContainerID): Container;

    /**
     * Subscribe to updates from local edits.
     *
     * This method allows you to listen for local changes made to the document.
     * It's useful for syncing changes with other instances or saving updates.
     *
     * @param f - A callback function that receives a Uint8Array containing the update data.
     * @returns A function to unsubscribe from the updates.
     *
     * @example
     * ```ts
     * const loro = new Loro();
     * const text = loro.getText("text");
     *
     * const unsubscribe = loro.subscribeLocalUpdates((update) => {
     *   console.log("Local update received:", update);
     *   // You can send this update to other Loro instances
     * });
     *
     * text.insert(0, "Hello");
     * loro.commit();
     *
     * // Later, when you want to stop listening:
     * unsubscribe();
     * ```
     *
     * @example
     * ```ts
     * const loro1 = new Loro();
     * const loro2 = new Loro();
     *
     * // Set up two-way sync
     * loro1.subscribeLocalUpdates((updates) => {
     *   loro2.import(updates);
     * });
     *
     * loro2.subscribeLocalUpdates((updates) => {
     *   loro1.import(updates);
     * });
     *
     * // Now changes in loro1 will be reflected in loro2 and vice versa
     * ```
     */
    subscribeLocalUpdates(f: (bytes: Uint8Array) => void): () => void
}

/**
 * Represents a `Delta` type which is a union of different operations that can be performed.
 *
 * @typeparam T - The data type for the `insert` operation.
 *
 * The `Delta` type can be one of three distinct shapes:
 *
 * 1. Insert Operation:
 *    - `insert`: The item to be inserted, of type T.
 *    - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext
 *
 * 2. Delete Operation:
 *    - `delete`: The number of elements to delete.
 *
 * 3. Retain Operation:
 *    - `retain`: The number of elements to retain.
 *    - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext
 */
export type Delta<T> =
  | {
    insert: T;
    attributes?: { [key in string]: {} };
    retain?: undefined;
    delete?: undefined;
  }
  | {
    delete: number;
    attributes?: undefined;
    retain?: undefined;
    insert?: undefined;
  }
  | {
    retain: number;
    attributes?: { [key in string]: {} };
    delete?: undefined;
    insert?: undefined;
  };

/**
 * The unique id of each operation.
 */
export type OpId = { peer: PeerID, counter: number };

/**
 * Change is a group of continuous operations
 */
export interface Change {
    peer: PeerID,
    counter: number,
    lamport: number,
    length: number,
    /**
     * The timestamp in seconds.
     *
     * [Unix time](https://en.wikipedia.org/wiki/Unix_time)
     * It is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.
     */
    timestamp: number,
    deps: OpId[],
    message: string | undefined,
}


/**
 * Data types supported by loro
 */
export type Value =
  | ContainerID
  | string
  | number
  | boolean
  | null
  | { [key: string]: Value }
  | Uint8Array
  | Value[];

export type UndoConfig = {
    mergeInterval?: number,
    maxUndoSteps?: number,
    excludeOriginPrefixes?: string[],
    onPush?: (isUndo: boolean, counterRange: { start: number, end: number }) => { value: Value, cursors: Cursor[] },
    onPop?: (isUndo: boolean, value: { value: Value, cursors: Cursor[] }, counterRange: { start: number, end: number }) => void
};
export type Container = LoroList | LoroMap | LoroText | LoroTree | LoroMovableList;

export interface ImportBlobMetadata {
    /**
     * The version vector of the start of the import.
     *
     * Import blob includes all the ops from `partial_start_vv` to `partial_end_vv`.
     * However, it does not constitute a complete version vector, as it only contains counters
     * from peers included within the import blob.
     */
    partialStartVersionVector: VersionVector;
    /**
     * The version vector of the end of the import.
     *
     * Import blob includes all the ops from `partial_start_vv` to `partial_end_vv`.
     * However, it does not constitute a complete version vector, as it only contains counters
     * from peers included within the import blob.
     */
    partialEndVersionVector: VersionVector;

    startFrontiers: OpId[],
    startTimestamp: number;
    endTimestamp: number;
    isSnapshot: boolean;
    changeNum: number;
}

interface LoroText {
    /**
     * Get the cursor position at the given pos.
     *
     * When expressing the position of a cursor, using "index" can be unstable
     * because the cursor's position may change due to other deletions and insertions,
     * requiring updates with each edit. To stably represent a position or range within
     * a list structure, we can utilize the ID of each item/character on List CRDT or
     * Text CRDT for expression.
     *
     * Loro optimizes State metadata by not storing the IDs of deleted elements. This
     * approach complicates tracking cursors since they rely on these IDs. The solution
     * recalculates position by replaying relevant history to update cursors
     * accurately. To minimize the performance impact of history replay, the system
     * updates cursor info to reference only the IDs of currently present elements,
     * thereby reducing the need for replay.
     *
     * @example
     * ```ts
     *
     * const doc = new LoroDoc();
     * const text = doc.getText("text");
     * text.insert(0, "123");
     * const pos0 = text.getCursor(0, 0);
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(0);
     * }
     * text.insert(0, "1");
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(1);
     * }
     * ```
     */
    getCursor(pos: number, side?: Side): Cursor | undefined;
}

interface LoroList {
    /**
     * Get the cursor position at the given pos.
     *
     * When expressing the position of a cursor, using "index" can be unstable
     * because the cursor's position may change due to other deletions and insertions,
     * requiring updates with each edit. To stably represent a position or range within
     * a list structure, we can utilize the ID of each item/character on List CRDT or
     * Text CRDT for expression.
     *
     * Loro optimizes State metadata by not storing the IDs of deleted elements. This
     * approach complicates tracking cursors since they rely on these IDs. The solution
     * recalculates position by replaying relevant history to update cursors
     * accurately. To minimize the performance impact of history replay, the system
     * updates cursor info to reference only the IDs of currently present elements,
     * thereby reducing the need for replay.
     *
     * @example
     * ```ts
     *
     * const doc = new LoroDoc();
     * const text = doc.getList("list");
     * text.insert(0, "1");
     * const pos0 = text.getCursor(0, 0);
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(0);
     * }
     * text.insert(0, "1");
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(1);
     * }
     * ```
     */
    getCursor(pos: number, side?: Side): Cursor | undefined;
}

export type TreeNodeValue = {
    id: TreeID,
    parent: TreeID | undefined,
    index: number,
    fractionalIndex: string,
    meta: LoroMap,
    children: TreeNodeValue[],
}

interface LoroTree{
    toArray(): TreeNodeValue[];
    getNodes(options?: { withDeleted: boolean = false }): LoroTreeNode[];
}

interface LoroMovableList {
    /**
     * Get the cursor position at the given pos.
     *
     * When expressing the position of a cursor, using "index" can be unstable
     * because the cursor's position may change due to other deletions and insertions,
     * requiring updates with each edit. To stably represent a position or range within
     * a list structure, we can utilize the ID of each item/character on List CRDT or
     * Text CRDT for expression.
     *
     * Loro optimizes State metadata by not storing the IDs of deleted elements. This
     * approach complicates tracking cursors since they rely on these IDs. The solution
     * recalculates position by replaying relevant history to update cursors
     * accurately. To minimize the performance impact of history replay, the system
     * updates cursor info to reference only the IDs of currently present elements,
     * thereby reducing the need for replay.
     *
     * @example
     * ```ts
     *
     * const doc = new LoroDoc();
     * const text = doc.getMovableList("text");
     * text.insert(0, "1");
     * const pos0 = text.getCursor(0, 0);
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(0);
     * }
     * text.insert(0, "1");
     * {
     *   const ans = doc.getCursorPos(pos0!);
     *   expect(ans.offset).toBe(1);
     * }
     * ```
     */
    getCursor(pos: number, side?: Side): Cursor | undefined;
}

export type Side = -1 | 0 | 1;



export type JsonOpID = `${number}@${PeerID}`;
export type JsonContainerID =  `🦜:${ContainerID}` ;
export type JsonValue  =
  | JsonContainerID
  | string
  | number
  | boolean
  | null
  | { [key: string]: JsonValue }
  | Uint8Array
  | JsonValue[];

export type JsonSchema = {
  schema_version: number;
  start_version: Map<string, number>,
  peers: PeerID[],
  changes: JsonChange[]
};

export type JsonChange = {
  id: JsonOpID
  /**
   * The timestamp in seconds.
   *
   * [Unix time](https://en.wikipedia.org/wiki/Unix_time)
   * It is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.
   */
  timestamp: number,
  deps: JsonOpID[],
  lamport: number,
  msg: string | null,
  ops: JsonOp[]
}

export type ExportMode = {
    mode: "update",
    from?: VersionVector,
} | {
    mode: "snapshot",
} | {
    mode: "shallow-snapshot",
    frontiers: Frontiers,
} | {
    mode: "updates-in-range",
    spans: {
        id: ID,
        len: number,
    }[],
};

export type JsonOp = {
  container: ContainerID,
  counter: number,
  content: ListOp | TextOp | MapOp | TreeOp | MovableListOp | UnknownOp
}

export type ListOp = {
  type: "insert",
  pos: number,
  value: JsonValue
} | {
  type: "delete",
  pos: number,
  len: number,
  start_id: JsonOpID,
};

export type MovableListOp = {
  type: "insert",
  pos: number,
  value: JsonValue
} | {
  type: "delete",
  pos: number,
  len: number,
  start_id: JsonOpID,
}| {
  type: "move",
  from: number,
  to: number,
  elem_id: JsonOpID,
}|{
  type: "set",
  elem_id: JsonOpID,
  value: JsonValue
}

export type TextOp = {
  type: "insert",
  pos: number,
  text: string
} | {
  type: "delete",
  pos: number,
  len: number,
  start_id: JsonOpID,
} | {
  type: "mark",
  start: number,
  end: number,
  style_key: string,
  style_value: JsonValue,
  info: number
}|{
  type: "mark_end"
};

export type MapOp = {
  type: "insert",
  key: string,
  value: JsonValue
} | {
  type: "delete",
  key: string,
};

export type TreeOp = {
  type: "create",
  target: TreeID,
  parent: TreeID | undefined,
  fractional_index: string
}|{
  type: "move",
  target: TreeID,
  parent: TreeID | undefined,
  fractional_index: string
}|{
  type: "delete",
  target: TreeID
};

export type UnknownOp = {
  type: "unknown"
  prop: number,
  value_type: "unknown",
  value: {
    kind: number,
    data: Uint8Array
  }
};

export type CounterSpan = { start: number, end: number };

export type ImportStatus = {
  success: Map<PeerID, CounterSpan>,
  pending: Map<PeerID, CounterSpan> | null
}


/**
* `Awareness` is a structure that tracks the ephemeral state of peers.
*
* It can be used to synchronize cursor positions, selections, and the names of the peers.
*
* The state of a specific peer is expected to be removed after a specified timeout. Use
* `remove_outdated` to eliminate outdated states.
*/
export class AwarenessWasm {
  free(): void;
/**
* Creates a new `Awareness` instance.
*
* The `timeout` parameter specifies the duration in milliseconds.
* A state of a peer is considered outdated, if the last update of the state of the peer
* is older than the `timeout`.
* @param {number | bigint | `${number}`} peer
* @param {number} timeout
*/
  constructor(peer: number | bigint | `${number}`, timeout: number);
/**
* Encodes the state of the given peers.
* @param {Array<any>} peers
* @returns {Uint8Array}
*/
  encode(peers: Array<any>): Uint8Array;
/**
* Encodes the state of all peers.
* @returns {Uint8Array}
*/
  encodeAll(): Uint8Array;
/**
* Applies the encoded state of peers.
*
* Each peer's deletion countdown will be reset upon update, requiring them to pass through the `timeout`
* interval again before being eligible for deletion.
* @param {Uint8Array} encoded_peers_info
* @returns {{ updated: PeerID[], added: PeerID[] }}
*/
  apply(encoded_peers_info: Uint8Array): { updated: PeerID[], added: PeerID[] };
/**
* Get the PeerID of the local peer.
* @returns {PeerID}
*/
  peer(): PeerID;
/**
* Get the timestamp of the state of a given peer.
* @param {number | bigint | `${number}`} peer
* @returns {number | undefined}
*/
  getTimestamp(peer: number | bigint | `${number}`): number | undefined;
/**
* Remove the states of outdated peers.
* @returns {(PeerID)[]}
*/
  removeOutdated(): (PeerID)[];
/**
* Get the number of peers.
* @returns {number}
*/
  length(): number;
/**
* If the state is empty.
* @returns {boolean}
*/
  isEmpty(): boolean;
/**
* Get all the peers
* @returns {(PeerID)[]}
*/
  peers(): (PeerID)[];
}
/**
* Cursor is a stable position representation in the doc.
* When expressing the position of a cursor, using "index" can be unstable
* because the cursor's position may change due to other deletions and insertions,
* requiring updates with each edit. To stably represent a position or range within
* a list structure, we can utilize the ID of each item/character on List CRDT or
* Text CRDT for expression.
*
* Loro optimizes State metadata by not storing the IDs of deleted elements. This
* approach complicates tracking cursors since they rely on these IDs. The solution
* recalculates position by replaying relevant history to update cursors
* accurately. To minimize the performance impact of history replay, the system
* updates cursor info to reference only the IDs of currently present elements,
* thereby reducing the need for replay.
*
* @example
* ```ts
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "123");
* const pos0 = text.getCursor(0, 0);
* {
*   const ans = doc.getCursorPos(pos0!);
*   expect(ans.offset).toBe(0);
* }
* text.insert(0, "1");
* {
*   const ans = doc.getCursorPos(pos0!);
*   expect(ans.offset).toBe(1);
* }
* ```
*/
export class Cursor {
  free(): void;
/**
* Get the id of the given container.
* @returns {ContainerID}
*/
  containerId(): ContainerID;
/**
* Get the ID that represents the position.
*
* It can be undefined if it's not bind into a specific ID.
* @returns {{ peer: PeerID, counter: number } | undefined}
*/
  pos(): { peer: PeerID, counter: number } | undefined;
/**
* Get which side of the character/list item the cursor is on.
* @returns {Side}
*/
  side(): Side;
/**
* Encode the cursor into a Uint8Array.
* @returns {Uint8Array}
*/
  encode(): Uint8Array;
/**
* Decode the cursor from a Uint8Array.
* @param {Uint8Array} data
* @returns {Cursor}
*/
  static decode(data: Uint8Array): Cursor;
/**
* "Cursor"
* @returns {any}
*/
  kind(): any;
}
/**
* The handler of a tree(forest) container.
*/
export class LoroCounter {
  free(): void;
/**
* Create a new LoroCounter.
*/
  constructor();
/**
* Increment the counter by the given value.
* @param {number} value
*/
  increment(value: number): void;
/**
* Decrement the counter by the given value.
* @param {number} value
*/
  decrement(value: number): void;
/**
* Subscribe to the changes of the counter.
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Get the parent container of the counter container.
*
* - The parent container of the root counter is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a docuemnt.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroTree | undefined}
*/
  getAttached(): LoroTree | undefined;
/**
* Get the value of the counter.
*/
  readonly value: number;
}
/**
* The CRDTs document. Loro supports different CRDTs include [**List**](LoroList),
* [**RichText**](LoroText), [**Map**](LoroMap) and [**Movable Tree**](LoroTree),
* you could build all kind of applications by these.
*
* @example
* ```ts
* import { LoroDoc } import "loro-crdt"
*
* const loro = new LoroDoc();
* const text = loro.getText("text");
* const list = loro.getList("list");
* const map = loro.getMap("Map");
* const tree = loro.getTree("tree");
* ```
*/
export class LoroDoc {
  free(): void;
/**
* Create a new loro document.
*
* New document will have random peer id.
*/
  constructor();
/**
* Enables editing in detached mode, which is disabled by default.
*
* The doc enter detached mode after calling `detach` or checking out a non-latest version.
*
* # Important Notes:
*
* - This mode uses a different PeerID for each checkout.
* - Ensure no concurrent operations share the same PeerID if set manually.
* - Importing does not affect the document's state or version; changes are
*   recorded in the [OpLog] only. Call `checkout` to apply changes.
* @param {boolean} enable
*/
  setDetachedEditing(enable: boolean): void;
/**
* Whether the editing is enabled in detached mode.
*
* The doc enter detached mode after calling `detach` or checking out a non-latest version.
*
* # Important Notes:
*
* - This mode uses a different PeerID for each checkout.
* - Ensure no concurrent operations share the same PeerID if set manually.
* - Importing does not affect the document's state or version; changes are
*   recorded in the [OpLog] only. Call `checkout` to apply changes.
* @returns {boolean}
*/
  isDetachedEditingEnabled(): boolean;
/**
* Set whether to record the timestamp of each change. Default is `false`.
*
* If enabled, the Unix timestamp will be recorded for each change automatically.
*
* You can also set each timestamp manually when you commit a change.
* The timestamp manually set will override the automatic one.
*
* NOTE: Timestamps are forced to be in ascending order.
* If you commit a new change with a timestamp that is less than the existing one,
* the largest existing timestamp will be used instead.
* @param {boolean} auto_record
*/
  setRecordTimestamp(auto_record: boolean): void;
/**
* If two continuous local changes are within the interval, they will be merged into one change.
*
* The default value is 1_000_000, the default unit is milliseconds.
* @param {number} interval
*/
  setChangeMergeInterval(interval: number): void;
/**
* Set the rich text format configuration of the document.
*
* You need to config it if you use rich text `mark` method.
* Specifically, you need to config the `expand` property of each style.
*
* Expand is used to specify the behavior of expanding when new text is inserted at the
* beginning or end of the style.
*
* You can specify the `expand` option to set the behavior when inserting text at the boundary of the range.
*
* - `after`(default): when inserting text right after the given range, the mark will be expanded to include the inserted text
* - `before`: when inserting text right before the given range, the mark will be expanded to include the inserted text
* - `none`: the mark will not be expanded to include the inserted text at the boundaries
* - `both`: when inserting text either right before or right after the given range, the mark will be expanded to include the inserted text
*
* @example
* ```ts
* const doc = new LoroDoc();
* doc.configTextStyle({
*   bold: { expand: "after" },
*   link: { expand: "before" }
* });
* const text = doc.getText("text");
* text.insert(0, "Hello World!");
* text.mark({ start: 0, end: 5 }, "bold", true);
* expect(text.toDelta()).toStrictEqual([
*   {
*     insert: "Hello",
*     attributes: {
*       bold: true,
*     },
*   },
*   {
*     insert: " World!",
*   },
* ] as Delta<string>[]);
* ```
* @param {{[key: string]: { expand: 'before'|'after'|'none'|'both' }}} styles
*/
  configTextStyle(styles: {[key: string]: { expand: 'before'|'after'|'none'|'both' }}): void;
/**
* Get a loro document from the snapshot.
*
* @see You can check out what is the snapshot [here](#).
*
* @example
* ```ts
* import { LoroDoc } import "loro-crdt"
*
* const bytes = /* The bytes encoded from other loro document *\/;
* const loro = LoroDoc.fromSnapshot(bytes);
* ```
* @param {Uint8Array} snapshot
* @returns {LoroDoc}
*/
  static fromSnapshot(snapshot: Uint8Array): LoroDoc;
/**
* Attach the document state to the latest known version.
*
* > The document becomes detached during a `checkout` operation.
* > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
* > In a detached state, the document is not editable, and any `import` operations will be
* > recorded in the `OpLog` without being applied to the `DocState`.
*
* This method has the same effect as invoking `checkout_to_latest`.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* const frontiers = doc.frontiers();
* text.insert(0, "Hello World!");
* loro.checkout(frontiers);
* // you need call `attach()` or `checkoutToLatest()` before changing the doc.
* loro.attach();
* text.insert(0, "Hi");
* ```
*/
  attach(): void;
/**
* `detached` indicates that the `DocState` is not synchronized with the latest version of `OpLog`.
*
* > The document becomes detached during a `checkout` operation.
* > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
* > In a detached state, the document is not editable, and any `import` operations will be
* > recorded in the `OpLog` without being applied to the `DocState`.
*
* When `detached`, the document is not editable.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* const frontiers = doc.frontiers();
* text.insert(0, "Hello World!");
* console.log(doc.is_detached());  // false
* loro.checkout(frontiers);
* console.log(doc.is_detached());  // true
* loro.attach();
* console.log(doc.is_detached());  // false
* ```
* @returns {boolean}
*/
  isDetached(): boolean;
/**
* Detach the document state from the latest known version.
*
* After detaching, all import operations will be recorded in the `OpLog` without being applied to the `DocState`.
* When `detached`, the document is not editable.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* doc.detach();
* console.log(doc.is_detached());  // true
* ```
*/
  detach(): void;
/**
* Duplicate the document with a different PeerID
*
* The time complexity and space complexity of this operation are both O(n),
* @returns {LoroDoc}
*/
  fork(): LoroDoc;
/**
* Creates a new LoroDoc at a specified version (Frontiers)
* @param {({ peer: PeerID, counter: number })[]} frontiers
* @returns {LoroDoc}
*/
  forkAt(frontiers: ({ peer: PeerID, counter: number })[]): LoroDoc;
/**
* Checkout the `DocState` to the latest version of `OpLog`.
*
* > The document becomes detached during a `checkout` operation.
* > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
* > In a detached state, the document is not editable, and any `import` operations will be
* > recorded in the `OpLog` without being applied to the `DocState`.
*
* This has the same effect as `attach`.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* const frontiers = doc.frontiers();
* text.insert(0, "Hello World!");
* loro.checkout(frontiers);
* // you need call `checkoutToLatest()` or `attach()` before changing the doc.
* loro.checkoutToLatest();
* text.insert(0, "Hi");
* ```
*/
  checkoutToLatest(): void;
/**
* @param {({ peer: PeerID, counter: number })[]} ids
* @param {Function} f
*/
  travelChangeAncestors(ids: ({ peer: PeerID, counter: number })[], f: Function): void;
/**
* Checkout the `DocState` to a specific version.
*
* > The document becomes detached during a `checkout` operation.
* > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
* > In a detached state, the document is not editable, and any `import` operations will be
* > recorded in the `OpLog` without being applied to the `DocState`.
*
* You should call `attach` to attach the `DocState` to the latest version of `OpLog`.
*
* @param frontiers - the specific frontiers
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* const frontiers = doc.frontiers();
* text.insert(0, "Hello World!");
* loro.checkout(frontiers);
* console.log(doc.toJSON()); // {"text": ""}
* ```
* @param {({ peer: PeerID, counter: number })[]} frontiers
*/
  checkout(frontiers: ({ peer: PeerID, counter: number })[]): void;
/**
* Set the peer ID of the current writer.
*
* It must be a number, a BigInt, or a decimal string that can be parsed to a unsigned 64-bit integer.
*
* Note: use it with caution. You need to make sure there is not chance that two peers
* have the same peer ID. Otherwise, we cannot ensure the consistency of the document.
* @param {number | bigint | `${number}`} peer_id
*/
  setPeerId(peer_id: number | bigint | `${number}`): void;
/**
* Commit the cumulative auto committed transaction.
*
* You can specify the `origin`, `timestamp`, and `message` of the commit.
*
* The `origin` is used to mark the event, and the `message` works like a git commit message.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.export(mode)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* NOTE: Timestamps are forced to be in ascending order.
* If you commit a new change with a timestamp that is less than the existing one,
* the largest existing timestamp will be used instead.
*
* NOTE: The `origin` will not be persisted, but the `message` will.
* @param {{ origin?: string, timestamp?: number, message?: string } | undefined} [options]
*/
  commit(options?: { origin?: string, timestamp?: number, message?: string }): void;
/**
* Get the number of operations in the pending transaction.
*
* The pending transaction is the one that is not committed yet. It will be committed
* automatically after calling `doc.commit()`, `doc.export(mode)` or `doc.checkout(version)`.
* @returns {number}
*/
  getPendingTxnLength(): number;
/**
* Get a LoroText by container id.
*
* The object returned is a new js object each time because it need to cross
* the WASM boundary.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* ```
* @param {ContainerID | string} cid
* @returns {LoroText}
*/
  getText(cid: ContainerID | string): LoroText;
/**
* Get a LoroCounter by container id
* @param {ContainerID | string} cid
* @returns {LoroCounter}
*/
  getCounter(cid: ContainerID | string): LoroCounter;
/**
* Set the commit message of the next commit
* @param {string} msg
*/
  setNextCommitMessage(msg: string): void;
/**
* Get deep value of the document with container id
* @returns {any}
*/
  getDeepValueWithID(): any;
/**
* Get the path from the root to the container
* @param {ContainerID} id
* @returns {Array<any> | undefined}
*/
  getPathToContainer(id: ContainerID): Array<any> | undefined;
/**
* Evaluate JSONPath against a LoroDoc
* @param {string} jsonpath
* @returns {Array<any>}
*/
  JSONPath(jsonpath: string): Array<any>;
/**
* Get the encoded version vector of the current document.
*
* If you checkout to a specific version, the version vector will change.
* @returns {VersionVector}
*/
  version(): VersionVector;
/**
* The doc only contains the history since this version
*
* This is empty if the doc is not shallow.
*
* The ops included by the shallow history start version vector are not in the doc.
* @returns {VersionVector}
*/
  shallowSinceVV(): VersionVector;
/**
* Check if the doc contains the full history.
* @returns {boolean}
*/
  isShallow(): boolean;
/**
* The doc only contains the history since this version
*
* This is empty if the doc is not shallow.
*
* The ops included by the shallow history start frontiers are not in the doc.
* @returns {{ peer: PeerID, counter: number }[]}
*/
  shallowSinceFrontiers(): { peer: PeerID, counter: number }[];
/**
* Get the encoded version vector of the latest version in OpLog.
*
* If you checkout to a specific version, the version vector will not change.
* @returns {VersionVector}
*/
  oplogVersion(): VersionVector;
/**
* Get the frontiers of the current document.
*
* If you checkout to a specific version, this value will change.
* @returns {{ peer: PeerID, counter: number }[]}
*/
  frontiers(): { peer: PeerID, counter: number }[];
/**
* Get the frontiers of the latest version in OpLog.
*
* If you checkout to a specific version, this value will not change.
* @returns {{ peer: PeerID, counter: number }[]}
*/
  oplogFrontiers(): { peer: PeerID, counter: number }[];
/**
* Compare the version of the OpLog with the specified frontiers.
*
* This method is useful to compare the version by only a small amount of data.
*
* This method returns an integer indicating the relationship between the version of the OpLog (referred to as 'self')
* and the provided 'frontiers' parameter:
*
* - -1: The version of 'self' is either less than 'frontiers' or is non-comparable (parallel) to 'frontiers',
*        indicating that it is not definitively less than 'frontiers'.
* - 0: The version of 'self' is equal to 'frontiers'.
* - 1: The version of 'self' is greater than 'frontiers'.
*
* # Internal
*
* Frontiers cannot be compared without the history of the OpLog.
* @param {({ peer: PeerID, counter: number })[]} frontiers
* @returns {number}
*/
  cmpWithFrontiers(frontiers: ({ peer: PeerID, counter: number })[]): number;
/**
* Compare the ordering of two Frontiers.
*
* It's assumed that both Frontiers are included by the doc. Otherwise, an error will be thrown.
*
* Return value:
*
* - -1: a < b
* - 0: a == b
* - 1: a > b
* - undefined: a ∥ b: a and b are concurrent
* @param {({ peer: PeerID, counter: number })[]} a
* @param {({ peer: PeerID, counter: number })[]} b
* @returns {-1 | 1 | 0 | undefined}
*/
  cmpFrontiers(a: ({ peer: PeerID, counter: number })[], b: ({ peer: PeerID, counter: number })[]): -1 | 1 | 0 | undefined;
/**
* Export the snapshot of current version, it's include all content of
* operations and states
*
* @deprecated Use `export({mode: "snapshot"})` instead
* @returns {Uint8Array}
*/
  exportSnapshot(): Uint8Array;
/**
* Export the document based on the specified ExportMode.
*
* @param mode - The export mode to use. Can be one of:
*   - `{ mode: "snapshot" }`: Export a full snapshot of the document.
*   - `{ mode: "update", from: VersionVector }`: Export updates from the given version vector.
*   - `{ mode: "updates-in-range", spans: { id: ID, len: number }[] }`: Export updates within the specified ID spans.
*   - `{ mode: "shallow-snapshot", frontiers: Frontiers }`: Export a garbage-collected snapshot up to the given frontiers.
*
* @returns A byte array containing the exported data.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* doc.setText("text", "Hello World");
*
* // Export a full snapshot
* const snapshotBytes = doc.export({ mode: "snapshot" });
*
* // Export updates from a specific version
* const vv = doc.oplogVersion();
* doc.setText("text", "Hello Loro");
* const updateBytes = doc.export({ mode: "update", from: vv });
*
* // Export a garbage-collected snapshot
* const gcBytes = doc.export({ mode: "shallow-snapshot", frontiers: doc.oplogFrontiers() });
*
* // Export updates within specific ID spans
* const spanBytes = doc.export({
*   mode: "updates-in-range",
*   spans: [{ id: "1", len: 10 }, { id: "2", len: 5 }]
* });
* ```
* @param {ExportMode} mode
* @returns {Uint8Array}
*/
  export(mode: ExportMode): Uint8Array;
/**
* Export updates from the specific version to the current version with JSON format.
* @param {VersionVector | undefined} [start_vv]
* @param {VersionVector | undefined} [end_vv]
* @returns {JsonSchema}
*/
  exportJsonUpdates(start_vv?: VersionVector, end_vv?: VersionVector): JsonSchema;
/**
* Import updates from the JSON format.
*
* only supports backward compatibility but not forward compatibility.
* @param {string | JsonSchema} json
* @returns {ImportStatus}
*/
  importJsonUpdates(json: string | JsonSchema): ImportStatus;
/**
* Import a snapshot or a update to current doc.
*
* Note:
* - Updates within the current version will be ignored
* - Updates with missing dependencies will be pending until the dependencies are received
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* // get all updates of the doc
* const updates = doc.exportFrom();
* const snapshot = doc.exportSnapshot();
* const doc2 = new LoroDoc();
* // import snapshot
* doc2.import(snapshot);
* // or import updates
* doc2.import(updates);
* ```
* @param {Uint8Array} update_or_snapshot
* @returns {ImportStatus}
*/
  import(update_or_snapshot: Uint8Array): ImportStatus;
/**
* Import a batch of updates.
*
* It's more efficient than importing updates one by one.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* const updates = doc.exportFrom();
* const snapshot = doc.exportSnapshot();
* const doc2 = new LoroDoc();
* doc2.importUpdateBatch([snapshot, updates]);
* ```
* @param {Array<any>} data
*/
  importUpdateBatch(data: Array<any>): void;
/**
* Get the shallow json format of the document state.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* const tree = doc.getTree("tree");
* const map = doc.getMap("map");
* const shallowValue = doc.toShallowJSON();
* /*
* {"list": ..., "tree": ..., "map": ...}
*  *\/
* console.log(shallowValue);
* ```
* @returns {any}
*/
  getShallowValue(): any;
/**
* Get the json format of the document state.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, "Hello");
* const text = list.insertContainer(0, new LoroText());
* text.insert(0, "Hello");
* const map = list.insertContainer(1, new LoroMap());
* map.set("foo", "bar");
* /*
* {"list": ["Hello", {"foo": "bar"}]}
*  *\/
* console.log(doc.toJSON());
* ```
* @returns {any}
*/
  toJSON(): any;
/**
* Subscribe to the changes of the loro document. The function will be called when the
* transaction is committed or updates from remote are imported.
*
* Returns a subscription ID, which can be used to unsubscribe.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* doc.subscribe((event)=>{
*     console.log(event);
* });
* text.insert(0, "Hello");
* // the events will be emitted when `commit()` is called.
* doc.commit();
* ```
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Debug the size of the history
*/
  debugHistory(): void;
/**
* Get all of changes in the oplog
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* const changes = doc.getAllChanges();
*
* for (let [peer, changes] of changes.entries()){
*     console.log("peer: ", peer);
*     for (let change in changes){
*         console.log("change: ", change);
*     }
* }
* ```
* @returns {Map<PeerID, Change[]>}
*/
  getAllChanges(): Map<PeerID, Change[]>;
/**
* Get the change of a specific ID
* @param {{ peer: PeerID, counter: number }} id
* @returns {Change}
*/
  getChangeAt(id: { peer: PeerID, counter: number }): Change;
/**
* Get the change of with specific peer_id and lamport <= given lamport
* @param {string} peer_id
* @param {number} lamport
* @returns {Change | undefined}
*/
  getChangeAtLamport(peer_id: string, lamport: number): Change | undefined;
/**
* Get all ops of the change of a specific ID
* @param {{ peer: PeerID, counter: number }} id
* @returns {any[]}
*/
  getOpsInChange(id: { peer: PeerID, counter: number }): any[];
/**
* Convert frontiers to a readable version vector
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* const frontiers = doc.frontiers();
* const version = doc.frontiersToVV(frontiers);
* ```
* @param {({ peer: PeerID, counter: number })[]} frontiers
* @returns {VersionVector}
*/
  frontiersToVV(frontiers: ({ peer: PeerID, counter: number })[]): VersionVector;
/**
* Convert a version vector to frontiers
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* const version = doc.version();
* const frontiers = doc.vvToFrontiers(version);
* ```
* @param {VersionVector} vv
* @returns {{ peer: PeerID, counter: number }[]}
*/
  vvToFrontiers(vv: VersionVector): { peer: PeerID, counter: number }[];
/**
* Get the value or container at the given path
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("key", 1);
* console.log(doc.getByPath("map/key")); // 1
* console.log(doc.getByPath("map"));     // LoroMap
* ```
* @param {string} path
* @returns {Value | Container | undefined}
*/
  getByPath(path: string): Value | Container | undefined;
/**
* Get the absolute position of the given Cursor
*
* @example
* ```ts
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "123");
* const pos0 = text.getCursor(0, 0);
* {
*    const ans = doc.getCursorPos(pos0!);
*    expect(ans.offset).toBe(0);
* }
* text.insert(0, "1");
* {
*    const ans = doc.getCursorPos(pos0!);
*    expect(ans.offset).toBe(1);
* }
* ```
* @param {Cursor} cursor
* @returns {{ update?: Cursor, offset: number, side: Side }}
*/
  getCursorPos(cursor: Cursor): { update?: Cursor, offset: number, side: Side };
/**
* Peer ID of the current writer.
*/
  readonly peerId: bigint;
/**
* Get peer id in decimal string.
*/
  readonly peerIdStr: PeerID;
}
/**
* The handler of a list container.
*
* Learn more at https://loro.dev/docs/tutorial/list
*/
export class LoroList {
  free(): void;
/**
* Create a new detached LoroList.
*
* The edits on a detached container will not be persisted.
* To attach the container to the document, please insert it into an attached container.
*/
  constructor();
/**
* "List"
* @returns {'List'}
*/
  kind(): 'List';
/**
* Delete elements from index to index + len.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* list.delete(0, 1);
* console.log(list.value);  // []
* ```
* @param {number} index
* @param {number} len
*/
  delete(index: number, len: number): void;
/**
* Get elements of the list. If the type of a element is a container, it will be
* resolved recursively.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* const text = list.insertContainer(1, new LoroText());
* text.insert(0, "Hello");
* console.log(list.getDeepValue());  // [100, "Hello"];
* ```
* @returns {any}
*/
  toJSON(): any;
/**
* Subscribe to the changes of the list.
*
* Returns a subscription id, which can be used to unsubscribe.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.subscribe((event)=>{
*     console.log(event);
* });
* list.insert(0, 100);
* doc.commit();
* ```
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Get the parent container.
*
* - The parent container of the root tree is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a document.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroList | undefined}
*/
  getAttached(): LoroList | undefined;
/**
* Pop a value from the end of the list.
* @returns {Value | undefined}
*/
  pop(): Value | undefined;
/**
* Delete all elements in the list.
*/
  clear(): void;
/**
* Get the id of this container.
*/
  readonly id: ContainerID;
/**
* Get the length of list.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* list.insert(1, "foo");
* list.insert(2, true);
* console.log(list.length);  // 3
* ```
*/
  readonly length: number;
}
/**
* The handler of a map container.
*
* Learn more at https://loro.dev/docs/tutorial/map
*/
export class LoroMap {
  free(): void;
/**
* Create a new detached LoroMap.
*
* The edits on a detached container will not be persisted.
* To attach the container to the document, please insert it into an attached container.
*/
  constructor();
/**
* "Map"
* @returns {'Map'}
*/
  kind(): 'Map';
/**
* Remove the key from the map.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* map.delete("foo");
* ```
* @param {string} key
*/
  delete(key: string): void;
/**
* Get the keys of the map.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* map.set("baz", "bar");
* const keys = map.keys(); // ["foo", "baz"]
* ```
* @returns {any[]}
*/
  keys(): any[];
/**
* Get the values of the map. If the value is a child container, the corresponding
* `Container` will be returned.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* map.set("baz", "bar");
* const values = map.values(); // ["bar", "bar"]
* ```
* @returns {any[]}
*/
  values(): any[];
/**
* Get the entries of the map. If the value is a child container, the corresponding
* `Container` will be returned.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* map.set("baz", "bar");
* const entries = map.entries(); // [["foo", "bar"], ["baz", "bar"]]
* ```
* @returns {([string, Value | Container])[]}
*/
  entries(): ([string, Value | Container])[];
/**
* Get the keys and the values. If the type of value is a child container,
* it will be resolved recursively.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* const text = map.setContainer("text", new LoroText());
* text.insert(0, "Hello");
* console.log(map.getDeepValue());  // {"foo": "bar", "text": "Hello"}
* ```
* @returns {any}
*/
  toJSON(): any;
/**
* Subscribe to the changes of the map.
*
* Returns a subscription id, which can be used to unsubscribe.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* @param {Listener} f - Event listener
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.subscribe((event)=>{
*     console.log(event);
* });
* map.set("foo", "bar");
* doc.commit();
* ```
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Get the parent container.
*
* - The parent container of the root tree is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a document.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroMap | undefined}
*/
  getAttached(): LoroMap | undefined;
/**
* Delete all key-value pairs in the map.
*/
  clear(): void;
/**
* The container id of this handler.
*/
  readonly id: ContainerID;
/**
* Get the size of the map.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const map = doc.getMap("map");
* map.set("foo", "bar");
* console.log(map.size);   // 1
* ```
*/
  readonly size: number;
}
/**
* The handler of a list container.
*
* Learn more at https://loro.dev/docs/tutorial/list
*/
export class LoroMovableList {
  free(): void;
/**
* Create a new detached LoroList.
*
* The edits on a detached container will not be persisted.
* To attach the container to the document, please insert it into an attached container.
*/
  constructor();
/**
* "MovableList"
* @returns {'MovableList'}
*/
  kind(): 'MovableList';
/**
* Delete elements from index to index + len.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* list.delete(0, 1);
* console.log(list.value);  // []
* ```
* @param {number} index
* @param {number} len
*/
  delete(index: number, len: number): void;
/**
* Get elements of the list. If the type of a element is a container, it will be
* resolved recursively.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* const text = list.insertContainer(1, new LoroText());
* text.insert(0, "Hello");
* console.log(list.getDeepValue());  // [100, "Hello"];
* ```
* @returns {any}
*/
  toJSON(): any;
/**
* Subscribe to the changes of the list.
*
* Returns a subscription id, which can be used to unsubscribe.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.subscribe((event)=>{
*     console.log(event);
* });
* list.insert(0, 100);
* doc.commit();
* ```
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Get the parent container.
*
* - The parent container of the root tree is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a document.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroList | undefined}
*/
  getAttached(): LoroList | undefined;
/**
* Move the element from `from` to `to`.
*
* The new position of the element will be `to`.
* Move the element from `from` to `to`.
*
* The new position of the element will be `to`. This method is optimized to prevent redundant
* operations that might occur with a naive remove and insert approach. Specifically, it avoids
* creating surplus values in the list, unlike a delete followed by an insert, which can lead to
* additional values in cases of concurrent edits. This ensures more efficient and accurate
* operations in a MovableList.
* @param {number} from
* @param {number} to
*/
  move(from: number, to: number): void;
/**
* Pop a value from the end of the list.
* @returns {Value | undefined}
*/
  pop(): Value | undefined;
/**
* Delete all elements in the list.
*/
  clear(): void;
/**
* Get the id of this container.
*/
  readonly id: ContainerID;
/**
* Get the length of list.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const list = doc.getList("list");
* list.insert(0, 100);
* list.insert(1, "foo");
* list.insert(2, true);
* console.log(list.length);  // 3
* ```
*/
  readonly length: number;
}
/**
* The handler of a text container. It supports rich text CRDT.
*
* ## Updating Text Content Using a Diff Algorithm
*
* A common requirement is to update the current text to a target text.
* You can implement this using a text diff algorithm of your choice.
* Below is a sample you can directly copy into your code, which uses the
* [fast-diff](https://www.npmjs.com/package/fast-diff) package.
*
* ```ts
* import { diff } from "fast-diff";
* import { LoroText } from "loro-crdt";
*
* function updateText(text: LoroText, newText: string) {
*   const src = text.toString();
*   const delta = diff(src, newText);
*   let index = 0;
*   for (const [op, text] of delta) {
*     if (op === 0) {
*     index += text.length;
*   } else if (op === 1) {
*     text.insert(index, text);
*     index += text.length;
*   } else {
*     text.delete(index, text.length);
*   }
* }
* ```
*
*
* Learn more at https://loro.dev/docs/tutorial/text
*/
export class LoroText {
  free(): void;
/**
* Create a new detached LoroText.
*
* The edits on a detached container will not be persisted.
* To attach the container to the document, please insert it into an attached container.
*/
  constructor();
/**
* "Text"
* @returns {'Text'}
*/
  kind(): 'Text';
/**
* Iterate each span(internal storage unit) of the text.
*
* The callback function will be called for each span in the text.
* If the callback returns `false`, the iteration will stop.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.iter((str) => (console.log(str), true));
* ```
* @param {Function} callback
*/
  iter(callback: Function): void;
/**
* Update the current text based on the provided text.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.update("Hello World");
* ```
* @param {string} text
*/
  update(text: string): void;
/**
* Update the current text based on the provided text line by line.
* @param {string} text
*/
  updateByLine(text: string): void;
/**
* Insert some string at index.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* ```
* @param {number} index
* @param {string} content
*/
  insert(index: number, content: string): void;
/**
* Get a string slice.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.slice(0, 2); // "He"
* ```
* @param {number} start_index
* @param {number} end_index
* @returns {string}
*/
  slice(start_index: number, end_index: number): string;
/**
* Get the character at the given position.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.charAt(0); // "H"
* ```
* @param {number} pos
* @returns {string}
*/
  charAt(pos: number): string;
/**
* Delete and return the string at the given range and insert a string at the same position.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.splice(2, 3, "llo"); // "llo"
* ```
* @param {number} pos
* @param {number} len
* @param {string} s
* @returns {string}
*/
  splice(pos: number, len: number, s: string): string;
/**
* Insert some string at utf-8 index.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insertUtf8(0, "Hello");
* ```
* @param {number} index
* @param {string} content
*/
  insertUtf8(index: number, content: string): void;
/**
* Delete elements from index to index + len
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insert(0, "Hello");
* text.delete(1, 3);
* const s = text.toString();
* console.log(s); // "Ho"
* ```
* @param {number} index
* @param {number} len
*/
  delete(index: number, len: number): void;
/**
* Delete elements from index to utf-8 index + len
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* text.insertUtf8(0, "Hello");
* text.deleteUtf8(1, 3);
* const s = text.toString();
* console.log(s); // "Ho"
* ```
* @param {number} index
* @param {number} len
*/
  deleteUtf8(index: number, len: number): void;
/**
* Mark a range of text with a key and a value.
*
* > You should call `configTextStyle` before using `mark` and `unmark`.
*
* You can use it to create a highlight, make a range of text bold, or add a link to a range of text.
*
* Note: this is not suitable for unmergeable annotations like comments.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* doc.configTextStyle({bold: {expand: "after"}});
* const text = doc.getText("text");
* text.insert(0, "Hello World!");
* text.mark({ start: 0, end: 5 }, "bold", true);
* ```
* @param {{ start: number, end: number }} range
* @param {string} key
* @param {any} value
*/
  mark(range: { start: number, end: number }, key: string, value: any): void;
/**
* Unmark a range of text with a key and a value.
*
* > You should call `configTextStyle` before using `mark` and `unmark`.
*
* You can use it to remove highlights, bolds or links
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* doc.configTextStyle({bold: {expand: "after"}});
* const text = doc.getText("text");
* text.insert(0, "Hello World!");
* text.mark({ start: 0, end: 5 }, "bold", true);
* text.unmark({ start: 0, end: 5 }, "bold");
* ```
* @param {{ start: number, end: number }} range
* @param {string} key
*/
  unmark(range: { start: number, end: number }, key: string): void;
/**
* Convert the state to string
* @returns {string}
*/
  toString(): string;
/**
* Get the text in [Delta](https://quilljs.com/docs/delta/) format.
*
* The returned value will include the rich text information.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* doc.configTextStyle({bold: {expand: "after"}});
* text.insert(0, "Hello World!");
* text.mark({ start: 0, end: 5 }, "bold", true);
* console.log(text.toDelta());  // [ { insert: 'Hello', attributes: { bold: true } } ]
* ```
* @returns {Delta<string>[]}
*/
  toDelta(): Delta<string>[];
/**
* Subscribe to the changes of the text.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* returns a subscription id, which can be used to unsubscribe.
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Change the state of this text by delta.
*
* If a delta item is `insert`, it should include all the attributes of the inserted text.
* Loro's rich text CRDT may make the inserted text inherit some styles when you use
* `insert` method directly. However, when you use `applyDelta` if some attributes are
* inherited from CRDT but not included in the delta, they will be removed.
*
* Another special property of `applyDelta` is if you format an attribute for ranges out of
* the text length, Loro will insert new lines to fill the gap first. It's useful when you
* build the binding between Loro and rich text editors like Quill, which might assume there
* is always a newline at the end of the text implicitly.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const text = doc.getText("text");
* doc.configTextStyle({bold: {expand: "after"}});
* text.insert(0, "Hello World!");
* text.mark({ start: 0, end: 5 }, "bold", true);
* const delta = text.toDelta();
* const text2 = doc.getText("text2");
* text2.applyDelta(delta);
* expect(text2.toDelta()).toStrictEqual(delta);
* ```
* @param {Delta<string>[]} delta
*/
  applyDelta(delta: Delta<string>[]): void;
/**
* Get the parent container.
*
* - The parent container of the root tree is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a document.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroText | undefined}
*/
  getAttached(): LoroText | undefined;
/**
* Get the container id of the text.
*/
  readonly id: ContainerID;
/**
* Get the length of text
*/
  readonly length: number;
}
/**
* The handler of a tree(forest) container.
*
* Learn more at https://loro.dev/docs/tutorial/tree
*/
export class LoroTree {
  free(): void;
/**
* Create a new detached LoroTree.
*
* The edits on a detached container will not be persisted.
* To attach the container to the document, please insert it into an attached container.
*/
  constructor();
/**
* "Tree"
* @returns {'Tree'}
*/
  kind(): 'Tree';
/**
* Move the target tree node to be a child of the parent.
* It's not allowed that the target is an ancestor of the parent
* or the target and the parent are the same node.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* const node = root.createNode();
* const node2 = node.createNode();
* tree.move(node2, root);
* // Error will be thrown if move operation creates a cycle
* tree.move(root, node);
* ```
* @param {TreeID} target
* @param {TreeID | undefined} parent
* @param {number | undefined} [index]
*/
  move(target: TreeID, parent: TreeID | undefined, index?: number): void;
/**
* Delete a tree node from the forest.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* const node = root.createNode();
* tree.delete(node.id);
* ```
* @param {TreeID} target
*/
  delete(target: TreeID): void;
/**
* Return `true` if the tree contains the TreeID, include deleted node.
* @param {TreeID} target
* @returns {boolean}
*/
  has(target: TreeID): boolean;
/**
* Return `None` if the node is not exist, otherwise return `Some(true)` if the node is deleted.
* @param {TreeID} target
* @returns {boolean}
*/
  isNodeDeleted(target: TreeID): boolean;
/**
* Get the hierarchy array with metadata of the forest.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* root.data.set("color", "red");
* // [ { id: '0@F2462C4159C4C8D1', parent: null, meta: { color: 'red' }, children: [] } ]
* console.log(tree.toJSON());
* ```
* @returns {any}
*/
  toJSON(): any;
/**
* Get all tree nodes of the forest, including deleted nodes.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* const node = root.createNode();
* const node2 = node.createNode();
* console.log(tree.nodes());
* ```
* @returns {(LoroTreeNode)[]}
*/
  nodes(): (LoroTreeNode)[];
/**
* Get the root nodes of the forest.
* @returns {(LoroTreeNode)[]}
*/
  roots(): (LoroTreeNode)[];
/**
* Subscribe to the changes of the tree.
*
* Returns a subscription id, which can be used to unsubscribe.
*
* Trees have three types of events: `create`, `delete`, and `move`.
* - `create`: Creates a new node with its `target` TreeID. If `parent` is undefined,
*             a root node is created; otherwise, a child node of `parent` is created.
*             If the node being created was previously deleted and has archived child nodes,
*             create events for these child nodes will also be received.
* - `delete`: Deletes the target node. The structure and state of the target node and
*             its child nodes are archived, and delete events for the child nodes will not be received.
* - `move`:   Moves the target node. If `parent` is undefined, the target node becomes a root node;
*             otherwise, it becomes a child node of `parent`.
*
* If a tree container is subscribed, the event of metadata changes will also be received as a MapDiff.
* And event's `path` will end with `TreeID`.
*
* The events will be emitted after a transaction is committed. A transaction is committed when:
*
* - `doc.commit()` is called.
* - `doc.exportFrom(version)` is called.
* - `doc.import(data)` is called.
* - `doc.checkout(version)` is called.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* tree.subscribe((event)=>{
*     // event.type: "create" | "delete" | "move"
* });
* const root = tree.createNode();
* const node = root.createNode();
* doc.commit();
* ```
* @param {Function} f
* @returns {any}
*/
  subscribe(f: Function): any;
/**
* Get the parent container of the tree container.
*
* - The parent container of the root tree is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {Container | undefined}
*/
  parent(): Container | undefined;
/**
* Whether the container is attached to a document.
*
* If it's detached, the operations on the container will not be persisted.
* @returns {boolean}
*/
  isAttached(): boolean;
/**
* Get the attached container associated with this.
*
* Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
* @returns {LoroTree | undefined}
*/
  getAttached(): LoroTree | undefined;
/**
* Set whether to generate fractional index for Tree Position.
*
* The jitter is used to avoid conflicts when multiple users are creating the node at the same position.
* value 0 is default, which means no jitter, any value larger than 0 will enable jitter.
*
* Generally speaking, jitter will affect the growth rate of document size.
* [Read more about it](https://www.loro.dev/blog/movable-tree#implementation-and-encoding-size)
* @param {number} jitter
*/
  enableFractionalIndex(jitter: number): void;
/**
* Disable the fractional index generation for Tree Position when
* you don't need the Tree's siblings to be sorted. The fractional index will be always default.
*/
  disableFractionalIndex(): void;
/**
* Whether the tree enables the fractional index generation.
* @returns {boolean}
*/
  isFractionalIndexEnabled(): boolean;
/**
* Get the id of the container.
*/
  readonly id: ContainerID;
}
/**
* The handler of a tree node.
*/
export class LoroTreeNode {
  free(): void;
/**
* @returns {string}
*/
  __getClassname(): string;
/**
* Move this tree node to be a child of the parent.
* If the parent is undefined, this node will be a root node.
*
* If the index is not provided, the node will be appended to the end.
*
* It's not allowed that the target is an ancestor of the parent.
*
* @example
* ```ts
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createChildNode();
* const node = root.createChildNode();
* const node2 = node.createChildNode();
* node2.moveTo(undefined, 0);
* // node2   root
* //          |
* //         node
*
* ```
* @param {LoroTreeNode | undefined} parent
* @param {number | undefined} [index]
*/
  move(parent: LoroTreeNode | undefined, index?: number): void;
/**
* Move the tree node to be after the target node.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* const node = root.createNode();
* const node2 = root.createNode();
* node2.moveAfter(node);
* // root
* //  /  \
* // node node2
* ```
* @param {LoroTreeNode} target
*/
  moveAfter(target: LoroTreeNode): void;
/**
* Move the tree node to be before the target node.
*
* @example
* ```ts
* import { LoroDoc } from "loro-crdt";
*
* const doc = new LoroDoc();
* const tree = doc.getTree("tree");
* const root = tree.createNode();
* const node = root.createNode();
* const node2 = root.createNode();
* node2.moveBefore(node);
* //   root
* //  /    \
* // node2 node
* ```
* @param {LoroTreeNode} target
*/
  moveBefore(target: LoroTreeNode): void;
/**
* Get the index of the node in the parent's children.
* @returns {number | undefined}
*/
  index(): number | undefined;
/**
* Get the `Fractional Index` of the node.
*
* Note: the tree container must be attached to the document.
* @returns {string | undefined}
*/
  fractionalIndex(): string | undefined;
/**
* Get the parent node of this node.
*
* - The parent of the root node is `undefined`.
* - The object returned is a new js object each time because it need to cross
*   the WASM boundary.
* @returns {LoroTreeNode | undefined}
*/
  parent(): LoroTreeNode | undefined;
/**
* Check if the node is deleted.
* @returns {boolean}
*/
  isDeleted(): boolean;
/**
* The TreeID of the node.
*/
  readonly id: TreeID;
}
/**
* `UndoManager` is responsible for handling undo and redo operations.
*
* By default, the maxUndoSteps is set to 100, mergeInterval is set to 1000 ms.
*
* Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
* Undo steps can be merged if they occur within a specified merge interval.
*
* Note that undo operations are local and cannot revert changes made by other peers.
* To undo changes made by other peers, consider using the time travel feature.
*
* Once the `peerId` is bound to the `UndoManager` in the document, it cannot be changed.
* Otherwise, the `UndoManager` may not function correctly.
*/
export class UndoManager {
  free(): void;
/**
* `UndoManager` is responsible for handling undo and redo operations.
*
* PeerID cannot be changed during the lifetime of the UndoManager.
*
* Note that undo operations are local and cannot revert changes made by other peers.
* To undo changes made by other peers, consider using the time travel feature.
*
* Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
* Undo steps can be merged if they occur within a specified merge interval.
*
* ## Config
*
* - `mergeInterval`: Optional. The interval in milliseconds within which undo steps can be merged. Default is 1000 ms.
* - `maxUndoSteps`: Optional. The maximum number of undo steps to retain. Default is 100.
* - `excludeOriginPrefixes`: Optional. An array of string prefixes. Events with origins matching these prefixes will be excluded from undo steps.
* - `onPush`: Optional. A callback function that is called when an undo/redo step is pushed.
*    The function can return a meta data value that will be attached to the given stack item.
* - `onPop`: Optional. A callback function that is called when an undo/redo step is popped.
*    The function will have a meta data value that was attached to the given stack item when
*   `onPush` was called.
* @param {LoroDoc} doc
* @param {UndoConfig} config
*/
  constructor(doc: LoroDoc, config: UndoConfig);
/**
* Undo the last operation.
* @returns {boolean}
*/
  undo(): boolean;
/**
* Redo the last undone operation.
* @returns {boolean}
*/
  redo(): boolean;
/**
* Can undo the last operation.
* @returns {boolean}
*/
  canUndo(): boolean;
/**
* Can redo the last operation.
* @returns {boolean}
*/
  canRedo(): boolean;
/**
* The number of max undo steps.
* If the number of undo steps exceeds this number, the oldest undo step will be removed.
* @param {number} steps
*/
  setMaxUndoSteps(steps: number): void;
/**
* Set the merge interval (in ms).
* If the interval is set to 0, the undo steps will not be merged.
* Otherwise, the undo steps will be merged if the interval between the two steps is less than the given interval.
* @param {number} interval
*/
  setMergeInterval(interval: number): void;
/**
* If a local event's origin matches the given prefix, it will not be recorded in the
* undo stack.
* @param {string} prefix
*/
  addExcludeOriginPrefix(prefix: string): void;
/**
* Check if the undo manager is bound to the given document.
* @param {LoroDoc} doc
* @returns {boolean}
*/
  checkBinding(doc: LoroDoc): boolean;
/**
*/
  clear(): void;
}
/**
* [VersionVector](https://en.wikipedia.org/wiki/Version_vector)
* is a map from [PeerID] to [Counter]. Its a right-open interval.
*
* i.e. a [VersionVector] of `{A: 1, B: 2}` means that A has 1 atomic op and B has 2 atomic ops,
* thus ID of `{client: A, counter: 1}` is out of the range.
*/
export class VersionVector {
  free(): void;
/**
* Create a new version vector.
* @param {Map<PeerID, number> | Uint8Array | VersionVector | undefined | null} value
*/
  constructor(value: Map<PeerID, number> | Uint8Array | VersionVector | undefined | null);
/**
* Create a new version vector from a Map.
* @param {Map<PeerID, number>} version
* @returns {VersionVector}
*/
  static parseJSON(version: Map<PeerID, number>): VersionVector;
/**
* Convert the version vector to a Map
* @returns {Map<PeerID, number>}
*/
  toJSON(): Map<PeerID, number>;
/**
* Encode the version vector into a Uint8Array.
* @returns {Uint8Array}
*/
  encode(): Uint8Array;
/**
* Decode the version vector from a Uint8Array.
* @param {Uint8Array} bytes
* @returns {VersionVector}
*/
  static decode(bytes: Uint8Array): VersionVector;
/**
* Get the counter of a peer.
* @param {number | bigint | `${number}`} peer_id
* @returns {number | undefined}
*/
  get(peer_id: number | bigint | `${number}`): number | undefined;
/**
* Compare the version vector with another version vector.
*
* If they are concurrent, return undefined.
* @param {VersionVector} other
* @returns {number | undefined}
*/
  compare(other: VersionVector): number | undefined;
}
