Nothing
## -----------------------------------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
## -----------------------------------------------------------------------------
# # From R-universe
# install.packages("automerge", repos = "https://posit-dev.r-universe.dev")
#
# # From GitHub
# pak::pak("posit-dev/automerge-r")
## -----------------------------------------------------------------------------
library(automerge)
## -----------------------------------------------------------------------------
doc <- am_create()
print(doc)
## -----------------------------------------------------------------------------
am_put(doc, AM_ROOT, "name", "Alice")
am_put(doc, AM_ROOT, "age", 30L)
am_put(doc, AM_ROOT, "active", TRUE)
am_commit(doc, "Initial data")
am_get(doc, AM_ROOT, "name")
am_get(doc, AM_ROOT, "age")
## -----------------------------------------------------------------------------
doc[["email"]] <- "alice@example.com"
doc[["score"]] <- 95.5
doc[["name"]]
doc[["age"]]
# List all keys
names(doc)
## -----------------------------------------------------------------------------
doc2 <- am_create() |>
am_put(AM_ROOT, "name", "Bob") |>
am_put(AM_ROOT, "age", 25L) |>
am_put(AM_ROOT, "active", TRUE) |>
am_commit("Initial setup")
doc2 |> am_get(AM_ROOT, "name")
am_close(doc2)
## -----------------------------------------------------------------------------
# Create document with nested structure in one call
doc3 <- am_create() |>
am_put(
AM_ROOT,
"company",
list(
name = "Acme Corp",
founded = 2020L,
employees = list(
list(name = "Alice", role = "Engineer"),
list(name = "Bob", role = "Designer")
),
office = list(
address = list(
street = "123 Main St",
city = "Boston",
zip = 02101L
),
size = 5000.5
)
)
) |>
am_commit("Add company data")
# Access nested data (verbose way)
company <- doc3[["company"]]
office <- am_get(doc3, company, "office")
address <- am_get(doc3, office, "address")
am_get(doc3, address, "city")
## -----------------------------------------------------------------------------
# Much simpler - use path-based access
am_get_path(doc3, c("company", "office", "address", "city"))
# Create deep structure using paths
doc4 <- am_create()
am_put_path(doc4, c("config", "database", "host"), "localhost")
am_put_path(doc4, c("config", "database", "port"), 5432L)
am_put_path(doc4, c("config", "cache", "enabled"), TRUE)
am_put_path(doc4, c("config", "cache", "ttl"), 3600L)
# Retrieve values with paths
am_get_path(doc4, c("config", "database", "host"))
am_close(doc3)
am_close(doc4)
## -----------------------------------------------------------------------------
# Your existing R data
config_data <- list(
app_name = "MyApp",
version = "1.0.0",
database = list(
host = "localhost",
port = 5432L,
credentials = list(
user = "admin",
password_hash = "..."
)
),
features = list("auth", "api", "websocket")
)
# Convert to Automerge document
doc5 <- as_automerge(config_data)
am_commit(doc5, "Initial configuration")
# Easy access with paths
am_get_path(doc5, c("database", "port"))
am_close(doc5)
## -----------------------------------------------------------------------------
# Create a document with a list
doc6 <- am_create()
am_put(doc6, AM_ROOT, "items", AM_OBJ_TYPE_LIST)
items <- am_get(doc6, AM_ROOT, "items")
# Insert items
am_insert(doc6, items, 1, "first") # Insert at index 1
am_insert(doc6, items, 2, "second") # Insert at index 2
am_insert(doc6, items, 3, "third") # Insert at index 3
# Or use the "end" marker to append
am_insert(doc6, items, "end", "fourth")
am_put(doc6, items, "end", "fifth")
# Get list length
am_length(doc6, items)
# Access by index
am_get(doc6, items, 1)
am_get(doc6, items, 2)
am_close(doc6)
## -----------------------------------------------------------------------------
doc7 <- am_create()
# Regular string (last-write-wins)
am_put(doc7, AM_ROOT, "title", "My Document")
# Text object (CRDT - supports collaborative editing)
am_put(doc7, AM_ROOT, "content", am_text("Initial content"))
text_obj <- am_get(doc7, AM_ROOT, "content")
# Text supports character-level operations
# For the text "Hello":
# H e l l o
# 0 1 2 3 4 5 <- positions (0-based, between characters)
am_text_splice(text_obj, 8, 0, "amazing ") # Insert at position 8
am_text_content(text_obj)
# For collaborative editors, use am_text_update() which computes
# and applies the minimal diff in one step:
old_text <- am_text_content(text_obj)
am_text_update(text_obj, old_text, "New content from user input")
am_text_content(text_obj)
am_close(doc7)
## -----------------------------------------------------------------------------
doc8 <- am_create()
# Create a counter
am_put(doc8, AM_ROOT, "score", am_counter(0))
am_counter_increment(doc8, AM_ROOT, "score", 10)
am_counter_increment(doc8, AM_ROOT, "score", 5)
am_counter_increment(doc8, AM_ROOT, "score", -3)
doc8[["score"]]
am_close(doc8)
## -----------------------------------------------------------------------------
doc9 <- am_create()
am_put(doc9, AM_ROOT, "created_at", Sys.time())
am_put(doc9, AM_ROOT, "updated_at", Sys.time())
doc9[["created_at"]]
am_close(doc9)
## -----------------------------------------------------------------------------
# Save to binary format
bytes <- am_save(doc)
# Save to file
temp_file <- tempfile(fileext = ".automerge")
writeBin(bytes, temp_file)
# Load from binary
doc_loaded <- am_load(bytes)
# Or load from file
doc_from_file <- am_load(readBin(temp_file, "raw", 1e6))
# Verify data persisted
doc_from_file[["name"]]
am_close(doc)
am_close(doc_loaded)
am_close(doc_from_file)
## -----------------------------------------------------------------------------
doc10 <- am_create()
# Make changes
doc10[["x"]] <- 1
doc10[["y"]] <- 2
# Commit with message
am_commit(doc10, "Add x and y coordinates")
# Make more changes
doc10[["z"]] <- 3
am_commit(doc10, "Add z coordinate")
## -----------------------------------------------------------------------------
doc11 <- am_fork(doc10)
# Changes to fork don't affect original
doc11[["w"]] <- 4
doc10[["w"]] # NULL - not in original
am_close(doc10)
am_close(doc11)
## -----------------------------------------------------------------------------
# Create two documents
doc12 <- am_create()
doc12[["source"]] <- "doc12"
doc12[["value1"]] <- 100
doc13 <- am_create()
doc13[["source"]] <- "doc13"
doc13[["value2"]] <- 200
# Merge doc13 into doc12
am_merge(doc12, doc13)
# doc12 now has both values
doc12[["value1"]]
doc12[["value2"]]
doc12[["source"]] # One value wins deterministically for conflicting keys
am_close(doc12)
am_close(doc13)
## -----------------------------------------------------------------------------
# Create two peers
peer1 <- am_create()
peer1[["edited_by"]] <- "peer1"
peer1[["data1"]] <- 100
am_commit(peer1)
peer2 <- am_create()
peer2[["edited_by"]] <- "peer2"
peer2[["data2"]] <- 200
am_commit(peer2)
# Bidirectional sync (documents modified in place)
rounds <- am_sync(peer1, peer2)
rounds
# Both documents now have all data
peer1[["data1"]]
peer1[["data2"]]
peer2[["data1"]]
peer2[["data2"]]
am_close(peer1)
am_close(peer2)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.