tunescotty/datum_serde
v0.1.6 ·
Type-safe data serialization, migration, and versioning for Roblox
datum-serde
Type-safe data serialization, migration, and versioning for Roblox.
Features
- Type-safe schemas for structured data with full Luau typing
- JSON serialization with deterministic encoding (binary in v0.2)
- Versioned migrations with DAG-based planning and deterministic transforms
- Validation with precise error paths (e.g.,
/inventory/3/name: expected string, got number) - Opt-in strict schemas (
strictArray,strictObject) and discriminated unions (taggedUnion) - Robust error handling with detailed failure reasons
- Example adapters for DataStore and ProfileStore integration
Installation
Wally
Add to your wally.toml:
[dependencies]
DatumSerde = "tunescotty/datum-serde@0.1.6"
Then run:
wally install
pesde
Run:
pesde add tunescotty/datum_serde
Then run:
pesde install
Quick Start
local DatumSerde = require(ReplicatedStorage.Packages.DatumSerde)
local S = DatumSerde.schema
local Serde = DatumSerde.serde
local JSON = DatumSerde.codec.json
local M = DatumSerde.migrate
-- Define schemas
local V1 = S.object({
version = S.literal("1"),
coins = S.number(),
inventory = S.array(S.string())
})
local V2 = S.object({
version = S.literal("2"),
coins = S.number(),
inventory = S.array(S.string()),
flags = S.map(S.string(), S.boolean())
})
-- Create migration plan
local plan = M.plan()
plan:add("1", "2", function(v)
if type(v) ~= "table" or v.version ~= "1" then
return false, "bad v1"
end
v.version = "2"
v.flags = {}
return true, v
end)
-- Load, migrate, save
local ok, v1 = Serde.decode(V1, oldPayload, JSON)
if not ok then error(v1) end
local okM, v2 = M.apply(plan, v1, "1", "2")
if not okM then error(v2) end
local okE, newPayload = Serde.encode(V2, v2, JSON)
if not okE then error(newPayload) end
Documentation
See public/docs/Design.md for architecture details.
License
MIT