Yex.Map (y_ex v0.10.2)

View Source

A shareable Map type that supports concurrent modifications with automatic conflict resolution. This module provides functionality for collaborative key-value pair management with support for nested shared types and JSON compatibility.

Features

  • Concurrent modifications with automatic conflict resolution
  • Support for nested shared types (Array, Text, Map)
  • JSON-compatible serialization
  • Key-value pair management with atomic operations
  • Observable changes for real-time collaboration

Summary

Functions

Converts the map to its preliminary representation. This is useful when you need to serialize or transfer the map's contents.

Deletes a key from the map. Returns :ok on success, :error on failure.

Retrieves a value by key from the map. Returns {:ok, value} if found, :error if not found.

Similar to fetch/2 but raises ArgumentError if the key is not found.

get a key from the map. ## Examples

Gets a value by key from the map, or lazily evaluates the given function if the key is not found. This is useful when the default value is expensive to compute and should only be evaluated when needed.

Checks if a key exists in the map. Returns true if the key exists, false otherwise.

Returns a list of all keys in the map.

Sets a key-value pair in the map. Returns :ok on success, :error on failure.

Sets a key-value pair in the map and returns the set value. Returns the value on success, raises on failure.

Returns the number of key-value pairs in the map.

Converts the map to a JSON-compatible format. This is useful for serialization or when you need to transfer the map's contents.

Converts the map to a list of key-value tuples.

Converts the map to a standard Elixir map. This is useful when you need to work with the map's contents in a non-collaborative context.

Returns a list of all values in the map.

Types

t()

@type t() :: %Yex.Map{doc: Yex.Doc.t(), reference: reference()}

value()

@type value() :: term()

Functions

as_prelim(map)

@spec as_prelim(t()) :: Yex.MapPrelim.t()

Converts the map to its preliminary representation. This is useful when you need to serialize or transfer the map's contents.

Parameters

  • map - The map to convert

delete(map, key)

@spec delete(t(), binary()) :: :ok

Deletes a key from the map. Returns :ok on success, :error on failure.

Parameters

  • map - The map to modify
  • key - The key to delete

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> Yex.Map.delete(map, "plane")
:ok

fetch(map, key)

@spec fetch(t(), binary()) :: {:ok, value()} | :error

Retrieves a value by key from the map. Returns {:ok, value} if found, :error if not found.

Parameters

  • map - The map to query
  • key - The key to look up

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> Yex.Map.fetch(map, "plane")
{:ok, ["Hello", "World"]}
iex> Yex.Map.fetch(map, "not_found")
:error

fetch!(map, key)

@spec fetch!(t(), binary()) :: value()

Similar to fetch/2 but raises ArgumentError if the key is not found.

Parameters

  • map - The map to query
  • key - The key to look up

Raises

  • ArgumentError - If the key is not found

get(map, key, default \\ nil)

@spec get(t(), binary(), default :: value()) :: value()

get a key from the map. ## Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> Yex.Map.get(map, "plane")
["Hello", "World"]
iex> Yex.Map.get(map, "not_found")
nil

get_lazy(map, key, fun)

@spec get_lazy(t(), binary(), fun :: (-> value())) :: value()

Gets a value by key from the map, or lazily evaluates the given function if the key is not found. This is useful when the default value is expensive to compute and should only be evaluated when needed.

Parameters

  • map - The map to query
  • key - The key to look up
  • fun - A function that returns the default value (only called if key is not found)

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> Yex.Map.get_lazy(map, "plane", fn -> ["Default"] end)
["Hello", "World"]
iex> Yex.Map.get_lazy(map, "not_found", fn -> ["Computed"] end)
["Computed"]

Particularly useful with set_and_get/3 for get-or-create patterns:

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> # Get existing value or create and return new one
iex> value = Yex.Map.get_lazy(map, "counter", fn ->
...>   Yex.Map.set_and_get(map, "counter", 0)
...> end)
iex> value
0.0
iex> # Next call returns existing value without calling the function
iex> Yex.Map.get_lazy(map, "counter", fn -> Yex.Map.set_and_get(map, "counter", 0) end)
0.0

has_key?(map, key)

@spec has_key?(t(), binary()) :: boolean()

Checks if a key exists in the map. Returns true if the key exists, false otherwise.

Parameters

  • map - The map to check
  • key - The key to look for

keys(map)

@spec keys(t()) :: [binary()]

Returns a list of all keys in the map.

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "foo", "bar")
iex> Yex.Map.set(map, "baz", "qux")
iex> keys = Yex.Map.keys(map)
iex> Enum.sort(keys) # keys order is not guaranteed
["baz", "foo"]

link(map, key)

@spec link(t(), binary()) :: Yex.WeakPrelim.t() | nil

⚠️ Experimental

Creates a weak link to a value in the map by key. Returns [Yex.WeakPrelim] to a given key, if it exists in a current map.

set(map, key, content)

@spec set(t(), binary(), Yex.input_type()) :: :ok

Sets a key-value pair in the map. Returns :ok on success, :error on failure.

Parameters

  • map - The map to modify
  • key - The key to set
  • content - The value to associate with the key

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
:ok

set_and_get(map, key, content)

@spec set_and_get(t(), binary(), Yex.input_type()) :: value()

Sets a key-value pair in the map and returns the set value. Returns the value on success, raises on failure.

Parameters

  • map - The map to modify
  • key - The key to set
  • content - The value to associate with the key

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> value = Yex.Map.set_and_get(map, "plane", ["Hello", "World"])
iex> value
["Hello", "World"]

size(map)

@spec size(t()) :: integer()

Returns the number of key-value pairs in the map.

to_json(map)

@spec to_json(t()) :: map()

Converts the map to a JSON-compatible format. This is useful for serialization or when you need to transfer the map's contents.

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "array", Yex.ArrayPrelim.from(["Hello", "World"]))
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> assert %{"plane" => ["Hello", "World"], "array" => ["Hello", "World"]} = Yex.Map.to_json(map)

to_list(map)

@spec to_list(t()) :: [{binary(), term()}]

Converts the map to a list of key-value tuples.

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> Yex.Map.to_list(map)
[{"plane", ["Hello", "World"]}]

to_map(map)

@spec to_map(t()) :: map()

Converts the map to a standard Elixir map. This is useful when you need to work with the map's contents in a non-collaborative context.

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "array", Yex.ArrayPrelim.from(["Hello", "World"]))
iex> Yex.Map.set(map, "plane", ["Hello", "World"])
iex> assert %{"plane" => ["Hello", "World"], "array" => %Yex.Array{}} = Yex.Map.to_map(map)

values(map)

@spec values(t()) :: [value()]

Returns a list of all values in the map.

Examples

iex> doc = Yex.Doc.new()
iex> map = Yex.Doc.get_map(doc, "map")
iex> Yex.Map.set(map, "foo", "bar")
iex> Yex.Map.set(map, "baz", 123)
iex> values = Yex.Map.values(map)
iex> Enum.sort(values) # values order is not guaranteed
[123.0, "bar"]