Grove.Schema (Grove v0.1.1)

View Source

DSL for defining node schemas with per-field CRDT types.

Schemas define the structure and conflict resolution strategy for node attributes. Each field can have a different CRDT type, enabling fine-grained control over how concurrent updates are merged.

Usage

defmodule MyApp.FormSchema do
  use Grove.Schema

  version 1

  node :dropdown do
    field :label, :lww_register, default: "Untitled"
    field :options, :rga_list, default: []
    field :tags, :or_set, default: MapSet.new()
  end

  node :text_field do
    field :label, :lww_register, default: ""
    field :placeholder, :lww_register, default: ""
  end
end

Generated Functions

The schema generates the following functions:

  • version/0 - Returns the schema version
  • node_types/0 - Returns list of defined node types
  • fields/1 - Returns field definitions for a node type
  • field_spec/2 - Returns a specific field's spec
  • new_node/3 - Creates a new node with ORMap attrs
  • read_node/1 - Extracts values from a node's attrs
  • update_field/4 - Updates a single field value

Supported Field Types

  • :lww_register - Last-writer-wins for scalar values
  • :mv_register - Multi-value register exposing conflicts
  • :or_set - Add-wins set for collections
  • :rga_list - Ordered list with concurrent inserts
  • :counter - Positive-negative counter

Schema Versioning

Schemas can be versioned for migrations:

defmodule MyApp.FormSchema do
  use Grove.Schema

  version 2

  node :dropdown do
    field :label, :lww_register
    field :required, :lww_register, default: false  # New in v2
  end

  migrate 1 do
    add_field :dropdown, :required, :lww_register, default: false
  end
end

Summary

Functions

Defines a field within a node.

Defines a migration from a previous version.

Defines a node type with its fields.

Removes a field in a migration.

Transforms a field value in a migration.

Sets the schema version.

Functions

add_field(node_type, field_name, type, opts \\ [])

(macro)

Adds a field in a migration.

field(name, type, opts \\ [])

(macro)

Defines a field within a node.

Options

  • :default - Default value when creating a new node

Example

field :label, :lww_register, default: ""
field :tags, :or_set

migrate(from_version, list)

(macro)

Defines a migration from a previous version.

Example

migrate 1 do
  add_field :dropdown, :required, :lww_register, default: false
  remove_field :dropdown, :deprecated_field
end

node(node_type, list)

(macro)

Defines a node type with its fields.

Example

node :dropdown do
  field :label, :lww_register, default: "Untitled"
  field :options, :rga_list, default: []
end

remove_field(node_type, field_name, opts \\ [])

(macro)

Removes a field in a migration.

transform_field(node_type, field_name, transform_fn)

(macro)

Transforms a field value in a migration.

version(v)

(macro)

Sets the schema version.

Example

version 2