Yex.Array (y_ex v0.10.2)

View Source

A shareable Array-like type that supports efficient insert/delete of elements at any position. This module provides functionality for collaborative array manipulation with support for concurrent modifications and automatic conflict resolution.

Features

  • Insert and delete elements at any position
  • Push and unshift operations for adding elements
  • Move elements between positions
  • Support for nested shared types
  • Automatic conflict resolution for concurrent modifications

Summary

Functions

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

Deletes content at the specified index. Returns :ok on success, :error on failure.

Deletes a range of contents starting at the specified index. Returns :ok on success, :error on failure. capped to the array bounds.

Get content at the specified index.

Get content at the specified index or raises ArgumentError if out of bounds. @see fetch/2

Gets a value by index from the array, or lazily evaluates the given function if the index is out of bounds. This is useful when the default value is expensive to compute and should only be evaluated when needed.

Inserts content at the specified index. Returns :ok on success.

Inserts content at the specified index and returns the inserted content. Returns the content on success, raises on failure.

Insert contents at the specified index.

Returns the length of the array

Moves element found at source index into target index position. Both indexes refer to a current state of the document.

Pushes content to the end of the array. Returns :ok on success, :error on failure.

Pushes content to the end of the array and returns the pushed content. Returns the content on success, raises on failure.

slices the array from start_index for amount of elements, then gets them back as Elixir List.

slices the array from start_index for amount of elements, then gets them back as Elixir List and takes every step element.

Convert to json-compatible format.

Returns as list

Unshifts content to the beginning of the array. Returns :ok on success, :error on failure.

Types

t()

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

value()

@type value() :: term()

Functions

as_prelim(array)

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

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

Parameters

  • array - The array to convert

delete(array, index)

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

Deletes content at the specified index. Returns :ok on success, :error on failure.

Parameters

  • array - The array to modify
  • index - The position to delete from (0-based)

delete_range(array, index, length)

@spec delete_range(t(), integer(), integer()) :: :ok

Deletes a range of contents starting at the specified index. Returns :ok on success, :error on failure. capped to the array bounds.

Parameters

  • array - The array to modify
  • index - The starting position to delete from (0-based)
  • length - The number of elements to delete

Examples

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "1")
iex> Yex.Array.push(array, "2")
iex> Yex.Array.push(array, "3")
iex> :ok = Yex.Array.delete_range(array, 0, 2); Yex.Array.to_list(array)
["3"]
iex> :ok = Yex.Array.delete_range(array, 0, 1); Yex.Array.to_list(array)
[]
iex> Yex.Array.insert_list(array, 0, ["1", "2", "3", "4", "5"])
iex> Yex.Array.delete_range(array, -4, 10); Yex.Array.to_list(array)
["1"]

fetch(array, index)

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

Get content at the specified index.

Examples pushes a string then fetches it back

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "Hello")
iex> Yex.Array.fetch(array, 0)
{:ok, "Hello"}

fetch!(array, index)

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

Get content at the specified index or raises ArgumentError if out of bounds. @see fetch/2

get(array, index, default \\ nil)

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

get_lazy(array, index, fun)

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

Gets a value by index from the array, or lazily evaluates the given function if the index is out of bounds. This is useful when the default value is expensive to compute and should only be evaluated when needed.

Parameters

  • array - The array to query
  • index - The index to look up
  • fun - A function that returns the default value (only called if index is out of bounds)

Examples

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "Hello")
iex> Yex.Array.get_lazy(array, 0, fn -> "Default" end)
"Hello"
iex> Yex.Array.get_lazy(array, 10, fn -> "Computed" end)
"Computed"

Particularly useful with insert_and_get/3 or push_and_get/2 for get-or-create patterns:

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> # Get existing value or create and return new one
iex> value = Yex.Array.get_lazy(array, 0, fn ->
...>   Yex.Array.push_and_get(array, "initial")
...> end)
iex> value
"initial"
iex> # Next call returns existing value without calling the function
iex> Yex.Array.get_lazy(array, 0, fn -> Yex.Array.push_and_get(array, "initial") end)
"initial"

insert(array, index, content)

@spec insert(t(), integer(), Yex.input_type()) :: :ok

Inserts content at the specified index. Returns :ok on success.

Parameters

  • array - The array to modify
  • index - The position to insert at (0-based). Supports negative indexing: -1 for end (append), -2 for before last, etc.
  • content - The content to insert (can be any JSON-compatible value or shared type)

Examples

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.insert(array, 0, "Hello")
:ok
iex> Yex.Array.insert(array, 1, "World")
:ok
iex> Yex.Array.to_json(array)
["Hello", "World"]

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.insert(array, 0, Yex.ArrayPrelim.from([1, 2, 3]))
:ok
iex> {:ok, nested} = Yex.Array.fetch(array, 0)
iex> Yex.Array.to_json(nested)
[1.0, 2.0, 3.0]

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "first")
iex> Yex.Array.push(array, "second")
iex> Yex.Array.push(array, "third")
iex> Yex.Array.insert(array, -1, "after_last")
:ok
iex> Yex.Array.to_json(array)
["first", "second", "third", "after_last"]

insert_and_get(array, index, content)

@spec insert_and_get(t(), integer(), Yex.input_type()) :: value()

Inserts content at the specified index and returns the inserted content. Returns the content on success, raises on failure.

Parameters

  • array - The array to modify
  • index - The position to insert at (0-based)
  • content - The content to insert

insert_list(array, index, contents)

@spec insert_list(t(), integer(), [Yex.any_type()]) :: :ok

Insert contents at the specified index.

Parameters

  • array - The array to modify
  • index - The position to insert at (0-based). Supports negative indexing: -1 for end (append), -2 for before last, etc.
  • contents - A list of contents to insert

Examples

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.insert_list(array, 0, [1,2,3,4,5])
iex> Yex.Array.to_json(array)
[1.0, 2.0, 3.0, 4.0, 5.0]

length(array)

Returns the length of the array

Examples adds a few items to an array and returns its length

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "Hello")
iex> Yex.Array.push(array, "World")
iex> Yex.Array.length(array)
2

member?(array, val)

move_to(array, from, to)

@spec move_to(t(), integer(), integer()) :: :ok

Moves element found at source index into target index position. Both indexes refer to a current state of the document.

Examples pushes a string then fetches it back

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, Yex.ArrayPrelim.from([1, 2]))
iex> Yex.Array.push(array, Yex.ArrayPrelim.from([3, 4]))
iex> :ok = Yex.Array.move_to(array, 0, 2)
iex> Yex.Array.to_json(array)
[[3.0, 4.0], [1.0, 2.0]]

push(array, content)

@spec push(t(), Yex.input_type()) :: :ok

Pushes content to the end of the array. Returns :ok on success, :error on failure.

Parameters

  • array - The array to modify
  • content - The content to append

push_and_get(array, content)

@spec push_and_get(t(), Yex.input_type()) :: value()

Pushes content to the end of the array and returns the pushed content. Returns the content on success, raises on failure.

Parameters

  • array - The array to modify
  • content - The content to append

Examples

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> value = Yex.Array.push_and_get(array, "Hello")
iex> value
"Hello"

quote(array, index, length)

@spec quote(t(), integer(), integer()) :: Yex.WeakPrelim.t() | {:error, term()}

⚠️ Experimental

Quotes a range of array content, returning it as a new WeakPrelim object.

slice(array, start_index, amount)

slices the array from start_index for amount of elements, then gets them back as Elixir List.

slice_take_every(array, start_index, amount, step)

slices the array from start_index for amount of elements, then gets them back as Elixir List and takes every step element.

to_json(array)

@spec to_json(t()) :: term()

Convert to json-compatible format.

Examples adds a few items to an array and returns as Elixir List

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "Hello")
iex> Yex.Array.push(array, "World")
iex> Yex.Array.to_json(array)
["Hello", "World"]

to_list(array)

Returns as list

Examples adds a few items to an array, then gets them back as Elixir List

iex> doc = Yex.Doc.new()
iex> array = Yex.Doc.get_array(doc, "array")
iex> Yex.Array.push(array, "Hello")
iex> Yex.Array.push(array, "World")
iex> Yex.Array.push(array, Yex.ArrayPrelim.from([1, 2]))
iex> ["Hello", "World", %Yex.Array{}] = Yex.Array.to_list(array)

unshift(array, content)

Unshifts content to the beginning of the array. Returns :ok on success, :error on failure.

Parameters

  • array - The array to modify
  • content - The content to prepend