module Sepia
Overview
Sepia is a simple, file-system-based serialization library for Crystal.
It provides two main modules: Sepia::Serializable and Sepia::Container.
⚠️ WARNING: UNSTABLE API AND STORAGE FORMAT
Sepia is currently in active development and does not have a stable API or storage format.
- The API is subject to change without notice
- Breaking changes may occur in any release
- The on-disk storage format is not stable - you will need to migrate your data stores when upgrading between versions
Use at your own risk in production. Ensure you have proper backup and migration strategies in place.
Disk Storage Strategy:
1. Individual Objects:
-
Sepia::Serializableobjects: Stored as individual files in a directory named after their class, using theirsepia_idas the filename.Example:
class MySerializable
include Sepia::Serializable
property value : String
def initialize(@value); end
def to_sepia
@value
end
def self.from_sepia(s)
new(s)
end
end
my_obj = MySerializable.new("hello")
my_obj.sepia_id = "my_obj_id"
my_obj.save
On-disk representation:
_data/
└── MySerializable/
└── my_obj_id
-
Sepia::Containerobjects: Stored as directories, also named after their class and using theirsepia_idas the directory name.Example:
class MyContainer
include Sepia::Container
end
my_container = MyContainer.new
my_container.sepia_id = "my_container_id"
my_container.save
On-disk representation:
_data/
└── MyContainer/
└── my_container_id/
2. Nested Objects within Containers:
-
Nested
Serializableobjects: Stored as symlinks to their canonicalSerializablefile.Example:
class MyContainer
include Sepia::Container
property nested_serializable : MySerializable
def initialize(@nested_serializable); end
end
my_serializable = MySerializable.new("nested")
my_serializable.sepia_id = "nested_serializable_id"
my_container = MyContainer.new(my_serializable)
my_container.sepia_id = "container_with_serializable"
my_container.save
On-disk representation:
_data/
├── MyContainer/
│ └── container_with_serializable/
│ └── nested_serializable -> ../../MySerializable/nested_serializable_id
└── MySerializable/
└── nested_serializable_id
-
Nested
Containerobjects: Stored as subdirectories, mirroring the object hierarchy on disk.Example:
class MyOuterContainer
include Sepia::Container
property inner_container : MyContainer
def initialize(@inner_container); end
end
class MyInnerContainer
include Sepia::Container
end
inner = MyInnerContainer.new
inner.sepia_id = "inner_container_id"
outer = MyOuterContainer.new(inner)
outer.sepia_id = "outer_container_id"
outer.save
On-disk representation:
_data/
└── MyOuterContainer/
└── outer_container_id/
└── inner_container/
3. Collections within Containers:
-
Arrays/Sets of
Serializableobjects: Stored in a subdirectory named after the collection's instance variable. Each serializable object is symlinked into that directory using its index as the filename.Example:
class MyContainerWithArray
include Sepia::Container
property serializables : Array(MySerializable)
def initialize(@serializables = [] of MySerializable); end
end
s1 = MySerializable.new("one"); s1.sepia_id = "s1_id"
s2 = MySerializable.new("two"); s2.sepia_id = "s2_id"
container = MyContainerWithArray.new([s1, s2])
container.sepia_id = "array_of_serializables"
container.save
On-disk representation:
_data/
├── MyContainerWithArray/
│ └── array_of_serializables/
│ └── serializables/
│ ├── 0 -> ../../../../MySerializable/s1_id
│ └── 1 -> ../../../../MySerializable/s2_id
└── MySerializable/
├── s1_id
└── s2_id
-
Arrays/Sets of
Containerobjects: Stored in a subdirectory named after the collection's instance variable. Each container object is stored as a subdirectory within that directory, using its index as the directory name.Example:
class MyContainerWithArrayOfContainers
include Sepia::Container
property containers : Array(MyContainer)
def initialize(@containers = [] of MyContainer); end
end
c1 = MyContainer.new; c1.sepia_id = "c1_id"
c2 = MyContainer.new; c2.sepia_id = "c2_id"
container = MyContainerWithArrayOfContainers.new([c1, c2])
container.sepia_id = "array_of_containers"
container.save
On-disk representation:
_data/
├── MyContainerWithArrayOfContainers/
│ └── array_of_containers/
│ └── containers/
│ ├── 0/
│ └── 1/
└── MyContainer/
├── c1_id/
└── c2_id/
-
Hashes (String keys) of
Serializablevalues: Stored in a subdirectory named after the hash's instance variable. Each serializable object is symlinked into that directory using its key as the filename.Example:
class MyContainerWithHash include Sepia::Container property serializables_hash : Hash(String, MySerializable)
def initialize(@serializables_hash = {} of String => MySerializable); end end
s1 = MySerializable.new("alpha"); s1.sepia_id = "alpha_id" s2 = MySerializable.new("beta"); s2.sepia_id = "beta_id" container = MyContainerWithHash.new({"a" => s1, "b" => s2}) container.sepia_id = "hash_of_serializables" container.save
On-disk representation:
```text
_data/
├── MyContainerWithHash/
│ └── hash_of_serializables/
│ └── serializables_hash/
│ ├── a -> ../../../../MySerializable/alpha_id
│ └── b -> ../../../../MySerializable/beta_id
└── MySerializable/
├── alpha_id
└── beta_id
-
Hashes (String keys) of
Containervalues: Stored in a subdirectory named after the hash's instance variable. Each container object is stored as a subdirectory within that directory, using its key as the directory name.Example:
class MyContainerWithHashOfContainers
include Sepia::Container
property containers_hash : Hash(String, MyContainer)
def initialize(@containers_hash = {} of String => MyContainer); end
end
c1 = MyContainer.new; c1.sepia_id = "hash_c1_id"
c2 = MyContainer.new; c2.sepia_id = "hash_c2_id"
container = MyContainerWithHashOfContainers.new({"x" => c1, "y" => c2})
container.sepia_id = "hash_of_containers"
container.save
On-disk representation:
_data/
├── MyContainerWithHashOfContainers/
│ └── hash_of_containers/
│ └── containers_hash/
│ ├── x/
│ └── y/
└── MyContainer/
├── hash_c1_id/
└── hash_c2_id/
Defined in:
sepia.crsepia/cache_manager.cr
sepia/container.cr
sepia/event.cr
sepia/event_logger.cr
sepia/file_storage.cr
sepia/generation_info.cr
sepia/in_memory_storage.cr
sepia/memory_limiter.cr
sepia/object.cr
sepia/path_resolver.cr
sepia/serializable.cr
sepia/storage.cr
sepia/storage_backend.cr
sepia/watcher.cr
sepia/weak_cache.cr
Constant Summary
-
VERSION =
"0.1.0"