# YGleam
Gleam bindings to [Yjs](https://github.com/yjs/yjs)
## Library state
The bidnings to YDoc, YMap, YArray, YUndoManager and their event listeners are
solid. They are used in production daily at [Nestful](https://nestful.app).
Other parts of the code were written on a best-effort basis and are untested, as
we currently do not use them in Nestful. PRs welcome.
## API state
This library binds from a functional, immutable, type-safe language (Gleam), to
a dynamic JavaScript API. This proves challenging. We are fairly close to a 1.0,
with a nice, ergonomic, as close to riding-on-a-cloud as possible, but not quite
there yet. Expect breaking changes.
Do open an issue if you have an API suggestion.
## Usage
Currently this library is almost a one-to-one FFI to Yjs, so first please
consult their respective docs at [https://yjs.dev](https://yjs.dev).
Here's an example for saving some Pets:
```gleam
import gleam/dynamic/decode.{type Dynamic}
import ygleam/y
import ygleam/y_doc
import ygleam/y_map
import ygleam/y_array
type Pet {
Pet(name: String, species: String)
}
fn encode_pet(pet: Pet) -> y.Value {
let ymap = y_map.new()
ymap
|> y_map.set("name", y.string(pet.name))
|> y_map.set("species", y.string(pet.species))
|> y.map
}
fn pet_decoder() {
use name <- decode.field("name", decode.string)
use species <- decode.field("species", decode.string)
}
fn decode_pet(dyn_pet: Dynamic) {
decode.run(dyn_pet, y_map.decoder())
|> result.map(y_map.to_json)
|> result.then(decode.run(_, pet_decoder()))
}
fn decode_pet_name(dyn_pet: Dynamic) -> String {
decode.run(dyn_pet, y_map.decoder())
|> result.map(y_map.get("species"))
|> result.then(decode.run(_, decode.string))
}
let ydoc = y_doc.new()
let pets = y_doc.get_array(ydoc, "pets")
[
Pet(name: "Doggo", species: "Dog"),
Pet(name: "Catto", species: "Cat")
]
|> list.map(encode_pet)
|> y_array.push(pets)
get(pets, 0)
|> decode_pet
|> echo
get(pets, 1)
|> decode_pet_name
|> echo
```