Class LoroMovableList<T>

The handler of a list container.

Learn more at https://loro.dev/docs/tutorial/list

Type Parameters

  • T = unknown

Constructors

  • Create a new detached LoroMovableList (not attached to any LoroDoc).

    The edits on a detached container will not be persisted. To attach the container to the document, please insert it into an attached container.

    Type Parameters

    • T = unknown

    Returns LoroMovableList<T>

  • Returns LoroMovableList<T>

Properties

Get the id of this container.

length: number

Get the length of list.

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

Methods

  • Delete all elements in the list.

    Returns void

  • Parameters

    • pos: number
    • len: number

    Returns void

  • Delete elements from index to index + len.

    Parameters

    • index: number
    • len: number

    Returns void

    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); // []
  • Returns void

  • Get the value at the index. If the value is a container, the corresponding handler will be returned.

    Parameters

    • index: number

    Returns T

     import { LoroDoc } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    console.log(list.get(0)); // 100
    console.log(list.get(1)); // undefined
  • Returns LoroMovableList<T>

  • Get the attached container associated with this.

    Returns an attached Container that equals to this or created by this, otherwise undefined.

    Returns LoroList<unknown>

  • Get the creator of the list item at the given position.

    Parameters

    • pos: number

    Returns `${number}`

  • 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.

    Parameters

    • pos: number
    • Optionalside: Side

    Returns Cursor


    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);
    }
  • Get the last editor of the list item at the given position.

    Parameters

    • pos: number

    Returns `${number}`

  • Get the last mover of the list item at the given position.

    Parameters

    • pos: number

    Returns `${number}`

  • Get the shallow value of the movable list.

    Unlike toJSON() which recursively resolves all containers to their values, getShallowValue() returns container IDs as strings for any nested containers.

    const doc = new LoroDoc();
    doc.setPeerId("1");
    const list = doc.getMovableList("list");
    list.insert(0, 1);
    list.insert(1, "two");
    const subList = list.insertContainer(2, new LoroList());
    subList.insert(0, "sub");
    list.getShallowValue(); // [1, "two", "cid:2@1:List"]
    list.toJSON(); // [1, "two", ["sub"]]

    Returns Value[]

  • Insert a value at index.

    Type Parameters

    • V

    Parameters

    Returns void

     import { LoroDoc } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    list.insert(1, "foo");
    list.insert(2, true);
    console.log(list.value); // [100, "foo", true];
  • Insert a container at the index.

    Type Parameters

    Parameters

    • pos: number
    • child: C

    Returns T extends C ? T<T> : C

     import { LoroDoc, LoroText } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    const text = list.insertContainer(1, new LoroText());
    text.insert(0, "Hello");
    console.log(list.toJSON()); // [100, "Hello"];
  • Whether the container is attached to a document.

    If it's detached, the operations on the container will not be persisted.

    Returns boolean

  • Check if the container is deleted

    Returns boolean

  • "MovableList"

    Returns "MovableList"

  • 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.

    Parameters

    • from: number
    • to: number

    Returns 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

  • Pop a value from the end of the list.

    Returns Value

  • Type Parameters

    • V

    Parameters

    Returns void

  • Push a container to the end of the list.

    Type Parameters

    Parameters

    • child: C

    Returns T extends C ? T<T> : C

  • Set the value at the given position.

    It's different from delete + insert that it will replace the value at the position.

    For example, if you have a list [1, 2, 3], and you call set(1, 100), the list will be [1, 100, 3]. If concurrently someone call set(1, 200), the list will be [1, 200, 3] or [1, 100, 3].

    But if you use delete + insert to simulate the set operation, they may create redundant operations and the final result will be [1, 100, 200, 3] or [1, 200, 100, 3].

    Type Parameters

    • V

    Parameters

    Returns void

     import { LoroDoc } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    list.insert(1, "foo");
    list.insert(2, true);
    list.set(1, "bar");
    console.log(list.value); // [100, "bar", true];
  • Set a container at the index.

    Type Parameters

    Parameters

    • pos: number
    • child: C

    Returns T extends C ? T<T> : C

     import { LoroDoc, LoroText } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    const text = list.setContainer(0, new LoroText());
    text.insert(0, "Hello");
    console.log(list.toJSON()); // ["Hello"];
  • Get elements of the list. If the value is a child container, the corresponding Container will be returned.

    Returns T[]

     import { LoroDoc, LoroText } from "loro-crdt";

    const doc = new LoroDoc();
    const list = doc.getMovableList("list");
    list.insert(0, 100);
    list.insert(1, "foo");
    list.insert(2, true);
    list.insertContainer(3, new LoroText());
    console.log(list.value); // [100, "foo", true, LoroText];
  • Get elements of the list. If the type of a element is a container, it will be resolved recursively.

    Returns any

    import { LoroDoc, LoroText } 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.toJSON()); // [100, "Hello"];