Options
All
  • Public
  • Public/Protected
  • All
Menu

Class CLazyMap<K, C>

A collaborative "lazy" map with keys of type K and mutable values of type C.

"Lazy" means that every key-value pair implicitly exists, but only nontrivial values are actually stored in memory. get(key) will construct its value if needed using the valueConstructor passed to the constructor. This is inspired by Apache Commons LazyMap.

Due to laziness, there is no explicit operation to "set" the value at a key. (The set method is a no-op.) Instead, all replicas get the same value, and any operations they perform on that value are "merged", affecting everyone. This contrasts with CMap, in which each set operation overwrites the previous value at its key, erasing any changes (including concurrent ones).

See also: CMap, CValueMap.

Key Presence

All values implicitly exist, and get always returns non-undefined. However, has, getIfPresent, size, and iterators determine key presence by: a key is present if its value is nontrivial, i.e., not in the initial state returned by valueConstructor.

For example, a CVar is nontrivial after CVar.value is first set. It becomes trivial again if CVar.clear is called and there are no concurrent operations. (Generally, a clear method makes its Collab trivial, except for lists.)

"Set" and "Delete" events respect these key presence rules: "Set" is emitted for a key when its value goes from trivial to nontrivial, and "Delete" is emitted when its value goes from nontrivial to trivial. Because a "Set" event is not emitted until after a value becomes nontrivial, it is important to register values' event handlers in valueConstructor instead of during the "Set" event.

delete and clear throw errors (grow-only semantics). set has no effect; it just returns the same value as get.

Garbage Collection

Internally, a value is considered trivial if its Collab.canGC method returns true or if it has performed no operations. Trivial values are only weakly referenced and so may be garbage collected. After garbage collection, they are re-created using valueConstructor if needed.

Type Parameters

  • K

    The type of keys.

  • C extends Collab

    The type of mutable values, represented by a Collab.

Hierarchy

Implements

Index

Constructors

Properties

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.

Accessors

  • get size(): number
  • The number of present (nontrivial) values in the map.

    Returns number

Methods

  • [iterator](): IterableIterator<[K, C]>
  • Returns an iterator for entries in the map.

    The iteration order is NOT eventually consistent: it may differ on replicas with the same state.

    Returns IterableIterator<[K, C]>

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

    If this Collab is in its initial, post-constructor state, then this method may (but is not required to) return true; otherwise, it returns false.

    By default, this method always returns false; override to change.

    If this method returns true:

    1. The parent may choose to weakly reference this object to save memory (e.g., CLazyMap does so). If this becomes garbage collected, then is needed later, the parent will recreate it using the same constructor call.
    2. The parent may skip calling save during saving. When loading the resulting saved state, the parent will call load(null, meta). load should process this as if called with the output of save from a garbage-collectable state. For a nontrivial example, see [[CMultiValueMap.load]]'s implementation.

    Returns boolean

  • Internal (Collab.send) use only.

    Sends the given message on behalf of child. In general, this parent is then responsible for delivering the given message to Collab.receive on each replica of child, with guarantees set by the runtime.

    Parameters

    Returns void

  • clear(): void
  • Unsupported (throws error).

    Returns void

  • delete(_key: K): void
  • Unsupported (throws error).

    Parameters

    • _key: K

    Returns void

  • Emits an event, which triggers all the registered event handlers.

    See CollabEventsRecord for advice on what events to emit.

    This is a wrapper around EventEmitter.emit that forces events to extend CollabEvent and also emits an "Any" event.

    Type Parameters

    Parameters

    • eventName: K
    • event: MapEventsRecord<K, C>[K] & CollabEvent
    • Optional options: { skipAnyEvent?: boolean }
      • Optional skipAnyEvent?: boolean

        Set to true to skip emitting an "Any" event.

    Returns void

  • entries(): IterableIterator<[K, C]>
  • Returns an iterator of key, value pairs for every entry in the map.

    The iteration order is NOT eventually consistent: it may differ on replicas with the same state.

    Returns IterableIterator<[K, C]>

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

    Called by this Collab's parent when it has been deleted from a collection on the local replica and can no longer be used (e.g., due to CSet.delete on this or an ancestor). A Collab implementation can implement this method to clean up external resources, e.g., associated DOM elements.

    finalize has no relation to the JavaScript garbage collector or canGC.

    By default, this method does nothing.

    Returns void

  • forEach(callbackfn: ((value: C, key: K, map: CLazyMap<K, C>) => void), thisArg?: any): void
  • Executes a provided function once for each (key, value) pair in the map, in the same order as entries.

    Parameters

    • callbackfn: ((value: C, key: K, map: CLazyMap<K, C>) => void)
        • (value: C, key: K, map: CLazyMap<K, C>): void
        • Parameters

          Returns void

    • Optional thisArg: any

    Returns void

  • fromID<D>(id: CollabID<D>, startIndex?: number): undefined | D
  • 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<D>
    • Optional startIndex: number

    Returns undefined | D

  • get(key: K): C
  • Returns the value associated to key, constructing it with valueConstructor if needed.

    This will never return undefined, even if has(key) is false. See getIfPresent.

    Parameters

    • key: K

    Returns C

  • getIfPresent(key: K): undefined | C
  • Returns the value associated to key, or undefined if it is not present.

    Key presence is defined in the class header.

    Parameters

    • key: K

    Returns undefined | C

  • has(key: K): boolean
  • Returns whether key is present in the map.

    Parameters

    • key: K

    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>

  • keyOf(searchElement: C): undefined | K
  • Returns the unique key associated to a value in this map, in O(1) time.

    If value is not a value in this map, returned undefined.

    Parameters

    • searchElement: C

      The value to locate in this map.

    Returns undefined | K

  • keys(): IterableIterator<K>
  • Returns an iterator for keys in the map.

    The iteration order is NOT eventually consistent: it may differ on replicas with the same state.

    Returns IterableIterator<K>

  • Internal (parent) use only.

    Called by this Collab's parent to load saved state. You may assume that the saved state was generated by save on some replica of this Collab, possibly in a different collaboration session, with guarantees set by the runtime.

    This method may also be called with savedStateTree = null; you should ignore such calls (i.e., return immediately) unless you override canGC. If you do override canGC, see that method's docs for instructions.

    Parameters

    Returns void

  • on<K>(eventName: K, handler: ((event: MapEventsRecord<K, C>[K], caller: CLazyMap<K, C>) => 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: MapEventsRecord<K, C>[K], caller: CLazyMap<K, C>) => 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.

  • 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

  • Internal (parent) use only.

    Returns saved state describing the current state of this Collab.

    The saved state may later be passed to load on a replica of this Collab, possibly in a different collaboration session, with rules set by the runtime. For example, CRuntime allows load at any time; it must then act as a merge operation (like a state-based CRDT), applying all updates that the saved replica had applied before saving, ignoring duplicates.

    save may be called at any time, possibly many times while an app is running. Calling save should not affect this Collab's user-visible state.

    For convenience, the saved state may be expressed as a tree of Uint8Arrays instead of just a single Uint8Array; see [[SaveStateTree]]'s docs.

    Returns SavedStateTree

    The saved state.

  • 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

  • set(key: K): C
  • No-op, just returns get(key).

    Parameters

    • key: K

    Returns C

  • toString(): string
  • values(): IterableIterator<C>
  • Returns an iterator for values in the map.

    The iteration order is NOT eventually consistent: it may differ on replicas with the same state.

    Returns IterableIterator<C>

Generated using TypeDoc