tunescotty/datum_serde
v0.1.5 ·
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) - Robust error handling with detailed failure reasons
- Example adapters for DataStore and ProfileStore integration
Installation
Wally
Add to your wally.toml:
[dependencies]
DatumSerde = "tunescotty/[email protected]"
Then run:
wally install
pesde
Run:
pesde add tunescotty/datum_serde
Then run:
pesde install
Quick Start
local S = require(ReplicatedStorage.Packages.DatumSerde.schema)
local Serde = require(ReplicatedStorage.Packages.DatumSerde.serde)
local JSON = require(ReplicatedStorage.Packages.DatumSerde.codec.json)
local M = require(ReplicatedStorage.Packages.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 docs/Design.md for architecture details.
License
MIT