Options
All
  • Public
  • Public/Protected
  • All
Menu

Class CList<C, InsertArgs>

A collaborative list with mutable values of type C.

Values are internally mutable. Specifically, each value is its own Collab, and operations on that Collab are collaborative as usual.

CList<C> has a similar API to Array<C>, but it is mutated more like a linked list: instead of mutating existing values, you insert and delete list entries. Insertions and deletions shift later entries, changing their indices, like in collaborative text editing or Array.splice.

To insert values, you use the pattern described in collections of Collabs: one user calls insert with InsertArgs; each replica passes those InsertArgs to its valueConstructor; and valueConstructor returns the local copy of the new value Collab.

When a value is deleted with delete, it is deleted permanently and can no longer be used; future and concurrent operations on that value are ignored. Alternately, use archive and restore.

It is not safe to modify a CList while iterating over it. The iterator will attempt to throw an exception if it detects such modification, but this is not guaranteed.

See also: CValueList, CText, CRichText.

Type Parameters

  • C extends Collab

    The value type, which is a Collab.

  • InsertArgs extends unknown[]

    The type of arguments to insert.

Hierarchy

Index

Constructors

  • new CList<C, InsertArgs>(init: InitToken, valueConstructor: ((valueInit: InitToken, ...args: InsertArgs) => C), options?: { argsSerializer?: Serializer<InsertArgs> }): CList<C, InsertArgs>

Properties

children: Map<string, Collab<CollabEventsRecord>>

The children (registered Collab properties), keyed by name.

This map should only be read, not mutated. It is exposed to subclasses as a convenience for methods that loop over all children.

name: string

Internal (this/parent) use only.

This Collab's name, which distinguishes it among its siblings in the tree of Collabs.

parent: Parent

Internal (this/parent) use only.

This Collab's parent in the tree of Collabs.

runtime: IRuntime

The ambient IRuntime.

Use this to access utilities like IRuntime.replicaID.

totalOrder: CTotalOrder

The abstract total order underlying this list CRDT.

Access this to construct separate LocalList views on top of the same total order, e.g., a view of all archived values.

Accessors

  • get length(): number
  • The length of the list.

    Returns number

Methods

  • [iterator](): IterableIterator<C>
  • Returns an iterator for values in the list, in list order.

    Returns IterableIterator<C>

  • archive(index: number, count?: number): void
  • Archives count values starting at index, i.e., values [index, index + count - 1).

    All later values shift to the left, decreasing their indices by count.

    Unlike delete, archived merely marks values as not present. Archived values can still perform collaborative operations, and they can be made present again with restore.

    throws

    if index < 0 or index + count >= this.length.

    Parameters

    • index: number
    • Optional count: number

      The number of values to archive. Defaults to 1 (archive the value at index only).

    Returns void

  • canGC(): boolean
  • Internal (parent) use only.

    By default, this method returns true if canGC returns true on every child. Override to change this behavior.

    See Collab.canGC.

    Returns boolean

  • clear(): void
  • Deletes every value in the list.

    Returns void

  • delete(index: number, count?: number): void
  • Delete count values starting at index, i.e., values [index, index + count - 1).

    All later values shift to the left, decreasing their indices by count.

    The values are deleted permanently and can no longer be used; future and concurrent operations on those values are ignored. Local operations will succeed but will not affect remote replicas. The values can perform cleanup in their Collab.finalize methods.

    See also: archive, CSet.delete.

    Parameters

    • index: number
    • Optional count: number

    Returns void

  • entries(): IterableIterator<[index: number, value: C, position: string]>
  • Returns an iterator of [index, value, position] tuples for every value in the list, in list order.

    Note: If you move list elements, you should not use position as a React key, since a value's position changes when it moves. Instead, use the object itself as the key.

    Returns IterableIterator<[index: number, value: C, position: string]>

  • finalize(): void
  • Internal (parent) use only.

    By default, this methods calls finalize on every child. Override to change this behavior, e.g., to add your own finalization steps (but consider calling super.finalize()).

    Returns void

  • forEach(callbackfn: ((value: C, index: number, list: CList<C, InsertArgs>) => void), thisArg?: any): void
  • Performs the specified action for each element in this list.

    Parameters

    • callbackfn: ((value: C, index: number, list: CList<C, InsertArgs>) => void)
        • (value: C, index: number, list: CList<C, InsertArgs>): void
        • Parameters

          • value: C
          • index: number
          • list: CList<C, InsertArgs>

          Returns void

    • Optional thisArg: any

    Returns void

  • fromID<C>(id: CollabID<C>, startIndex?: number): undefined | C
  • Inverse of idOf.

    Specifically, given a CollabID returned by idOf on some replica of this parent, returns this replica's copy of the original descendant. If that descendant does not exist (e.g., it was deleted or it is not present in this program version), returns undefined.

    Type Parameters

    Parameters

    • id: CollabID<C>
    • Optional startIndex: number

    Returns undefined | C

  • get(index: number): C
  • Returns the value currently at index.

    Parameters

    • index: number

    Returns C

  • getByPosition(position: string): undefined | C
  • Returns the value at position, or undefined if it is not currently present (hasPosition returns false).

    Parameters

    • position: string

    Returns undefined | C

  • getPosition(index: number): string
  • Returns the position currently at index.

    Parameters

    • index: number

    Returns string

  • hasPosition(position: string): boolean
  • Returns whether position is currently present in the list, i.e., its value is present (neither deleted nor archived).

    Parameters

    • position: string

    Returns boolean

  • Returns a CollabID for the given strict descendant of this parent.

    The CollabID may be passed to fromID on any replica of this parent (but not other parents) to obtain that replica's copy of descendant.

    Type Parameters

    Parameters

    • descendant: C

    Returns CollabID<C>

  • indexOf(searchElement: C, fromIndex?: number): number
  • Returns the index of the first occurrence of a value in this list, or -1 if it is not present.

    Parameters

    • searchElement: C
    • Optional fromIndex: number

    Returns number

  • indexOfPosition(position: string, searchDir?: "none" | "left" | "right"): number
  • Returns the current index of position.

    If position is not currently present in the list (hasPosition returns false), then the result depends on searchDir:

    • "none" (default): Returns -1.
    • "left": Returns the next index to the left of position. If there are no values to the left of position, returns -1.
    • "right": Returns the next index to the right of position. If there are no values to the right of position, returns length.

    To find the index where a position would be if present, use searchDir = "right".

    Parameters

    • position: string
    • Optional searchDir: "none" | "left" | "right"

    Returns number

  • insert(index: number, ...args: InsertArgs): C
  • Inserts a value at the given index using args.

    All values currently at or after index shift to the right, incrementing their indices.

    The args are broadcast to all replicas in serialized form. Every replica then passes them to valueConstructor to construct the actual value of type C, a new Collab that is collaborative as usual.

    throws

    If index is not in [0, this.length].

    Parameters

    • index: number

      The insertion index in the range [0, this.length]. If this.length, the value is appended to the end of the list.

    • Rest ...args: InsertArgs

    Returns C

    The inserted value, or undefined if it is not constructed immediately.

  • Internal (parent) use only.

    Called by this Collab's parent to load saved state. See Collab.load.

    A CObject subclass may override this method to load additional state from Collab.save or to perform extra setup - e.g., refreshing functional views that were not automatically updated by children's load events. It is recommended to do so as follows:

    load(savedStateTree: SavedStateTree | null, meta: SavedStateMeta) {
    super.load(savedStateTree, meta);
    // Process your extra saved state from savedStateTree.self.
    const savedState = savedStateTree === null? null: savedStateTree.self!;
    ...
    // Perform extra setup as needed.
    ...
    }

    Parameters

    Returns void

  • map<U>(callbackfn: ((value: C, index: number, list: CList<C, InsertArgs>) => U), thisArg?: any): U[]
  • Calls a defined callback function on each element of this list, and returns an array that contains the results.

    Type Parameters

    • U

    Parameters

    • callbackfn: ((value: C, index: number, list: CList<C, InsertArgs>) => U)
        • (value: C, index: number, list: CList<C, InsertArgs>): U
        • Parameters

          • value: C
          • index: number
          • list: CList<C, InsertArgs>

          Returns U

    • Optional thisArg: any

    Returns U[]

  • move(index: number, insertionIndex: number, count?: number): number
  • Moves count values from index to insertionIndex.

    That is, the range of values at [index, index + count - 1) is moved to the position currently at insertionIndex.

    Other values shift to accommodate the move.

    Collaborative operations on the values continue to work normally, even if concurrent to the move.

    throws

    if index < 0 or index + count >= this.length.

    Parameters

    • index: number
    • insertionIndex: number
    • Optional count: number

      The number of values to move. Defaults to 1 (move the value at index only).

    Returns number

    The new index of the first moved value. This will be less then insertionIndex if index < insertionIndex.

  • on<K>(eventName: K, handler: ((event: ListExtendedEventsRecord<C>[K], caller: CList<C, InsertArgs>) => void), options?: { once?: boolean }): (() => void)
  • Registers an event handler that is triggered when the event happens.

    Type Parameters

    Parameters

    • eventName: K

      Name of the event to listen on.

    • handler: ((event: ListExtendedEventsRecord<C>[K], caller: CList<C, InsertArgs>) => void)

      Callback that handles the event.

    • Optional options: { once?: boolean }
      • Optional once?: boolean

        If true, the event handler is triggered at most once (the next time the event happens), then unsubscribed.

    Returns (() => void)

    An "off" function that removes the event handler when called.

      • (): void
      • Registers an event handler that is triggered when the event happens.

        Returns void

        An "off" function that removes the event handler when called.

  • positionOf(value: C): undefined | string
  • Returns value's position, or undefined if it is deleted or never an element of this list.

    For an archived (but not deleted) value, returns the position that it would have when restored. You can use list.indexOfPosition(list.positionOf(value), "right") to find the index that it would have when restored.

    Parameters

    • value: C

    Returns undefined | string

  • positions(): IterableIterator<string>
  • Returns an iterator for present positions, in list order.

    Returns IterableIterator<string>

  • push(...args: InsertArgs): C
  • Inserts a value at the end of the list using args. Equivalent to this.insert(this.length, ...args).

    Parameters

    • Rest ...args: InsertArgs

    Returns C

    The inserted value.

  • receive(messageStack: (string | Uint8Array)[], meta: MessageMeta): void
  • Internal (parent) use only.

    Receives a message sent by send on a local or remote replica of this Collab.

    This method processes the message, changes the local state accordingly, and emits events describing the local changes.

    This method should make assumptions and ensure consistency guarantees appropriate to its use case. For example, CRDTs may assume eventual, exactly-once, causal-order message delivery, and they must ensure strong eventual consistency.

    Parameters

    Returns void

  • registerCollab<C>(name: string, collabCallback: ((init: InitToken) => C)): C
  • Registers a Collab property of this CObject with the given name, making it one of our children.

    Typically, you will call this method during the constructor in the style:

    this.foo = this.registerCollab("foo", (init) => new FooClass(init, constructor args...));
    

    where readonly foo: FooClass; is a Collab property. See Data Modeling for examples.

    Registrations must be identical across all replicas.

    See also: CRuntime.registerCollab.

    Type Parameters

    Parameters

    • name: string

      A name for this property, unique among this class's registerCollab calls. We recommend using the same name as the property, but you can also use short strings to reduce network usage ("", "0", "1", ...).

    • collabCallback: ((init: InitToken) => C)

      A callback that uses the given InitToken to construct the registered Collab.

    Returns C

    The registered Collab.

  • restore(value: C): void
  • Restores the given value, marking it as present in the list.

    The value re-appears at its previous position, unless moved by move. All values after that position shift to the right, incrementing their indices.

    In case of concurrent restore and archive operations, the restore wins. If the value is deleted (not just archived), this method has no effect.

    One usage pattern is to call restore on a value each time you mutate that value. That way, if one user archives a value while it is still in use by another user, the archive will be canceled (update-wins semantics).

    Parameters

    • value: C

    Returns void

  • Internal (parent) use only.

    Returns saved state describing the current state of this CObject. See Collab.save.

    A CObject subclass may override this method to save additional state. It is recommended to do so as follows:

    save() {
    const ans = super.save();
    // Put your extra saved state in ans.self, which is otherwise unused.
    ans.self = <subclass's saved state>;
    return ans;
    }

    Returns SavedStateTree

  • send(messageStack: (string | Uint8Array)[], metaRequests: MetaRequest[]): void
  • Broadcasts a message to other replicas of this Collab. The message will be delivered to all replicas' receive, including locally.

    For convenience, the message may be expressed as a stack of (Uint8Array | string), instead of just a single Uint8Array. This is useful for parents sending messages on behalf of their children; see the implementation of CObject for an example.

    Parameters

    • messageStack: (string | Uint8Array)[]

      The message to send, in the form of a stack of Uint8Arrays. Note that this method may mutate it in-place.

    • metaRequests: MetaRequest[]

      A stack of metadata requests. The runtime will use the union of these when creating the MessageMeta for receive. Note that the stack need not align with messageStack, and this method may mutate it in place.

    Returns void

  • slice(start?: number, end?: number): C[]
  • Returns a copy of a section of this list, as an array. For both start and end, a negative index can be used to indicate an offset from the end of the list. For example, -2 refers to the second to last element of the list.

    Parameters

    • Optional start: number
    • Optional end: number

    Returns C[]

  • toString(): string
  • unshift(...args: InsertArgs): C
  • Inserts a value at the start of the list using args. Equivalent to this.insert(0, ...args).

    Parameters

    • Rest ...args: InsertArgs

    Returns C

    The inserted value.

  • values(): IterableIterator<C>
  • Returns an iterator for values in the list, in list order.

    Returns IterableIterator<C>

Generated using TypeDoc