#core/storage

    Storage abstraction layer for persistence operations.

    #Storage Trait

    pub trait Storage {
    read(Self, String, StorageKind) -> Bytes raise IOError
    write(Self, String, Bytes, StorageKind) -> Unit raise IOError
    append(Self, String, Bytes, StorageKind) -> Unit raise IOError
    atomic_write(Self, String, Bytes, StorageKind) -> Unit raise IOError
    del(Self, String, StorageKind) -> Unit raise IOError
    exists(Self, String, StorageKind) -> Bool
    list(Self, StorageKind) -> Array[String]
    }

    #Implementations

    • MemoryStorage: In-memory storage for testing
    • CallbackStorage: Delegates to JS callbacks for custom backends

    #StorageKind

    Routes data to appropriate backends:
    • Config: Collection configuration files
    • Index: Index structures and manifests
    • Data: Vector data and segments

    AsyncStorage

    pub(open) trait AsyncStorage {
    fn async_read(Self, String, StorageKind, (Bytes) -> Unit, (String) -> Unit) -> Unit
    fn async_write(Self, String, Bytes, StorageKind, () -> Unit, (String) -> Unit) -> Unit
    fn async_atomic_write(Self, String, Bytes, StorageKind, () -> Unit, (String) -> Unit) -> Unit
    fn async_del(Self, String, StorageKind, () -> Unit, (String) -> Unit) -> Unit
    fn async_exists(Self, String, StorageKind, (Bool) -> Unit, (String) -> Unit) -> Unit
    fn async_list(Self, StorageKind, (Array[String]) -> Unit, (String) -> Unit) -> Unit
    }

    Async storage trait — all targets. All operations return results via MoonBit's async/await mechanism. Implementors must call the provided continuation when I/O completes.

    Storage

    pub trait Storage {
    fn read(Self, String, StorageKind) -> Bytes raise IOError
    fn write(Self, String, Bytes, StorageKind) -> Unit raise IOError
    fn append(Self, String, Bytes, StorageKind) -> Unit raise IOError
    fn atomic_write(Self, String, Bytes, StorageKind) -> Unit raise IOError
    fn del(Self, String, StorageKind) -> Unit raise IOError
    fn exists(Self, String, StorageKind) -> Bool
    fn list(Self, StorageKind) -> Array[String] raise IOError
    }

    Storage trait - abstraction for file-like storage operations kind parameter allows app to route different data types to different backends

    AsyncIOError

    pub(all) suberror AsyncIOError {
    AsyncIOFailed(String)
    }

    Error type for async storage operations.

    IOError

    pub(all) suberror IOError {
    NotFound(String)
    PermissionDenied(String)
    IoFailed(String)
    }

    IO Error types for storage operations

    KindAwareStorage

    pub struct KindAwareStorage {
    config : Map[String, Bytes]
    index : Map[String, Bytes]
    data : Map[String, Bytes]
    }

    Kind-aware memory storage — TEST UTILITY.

    Unlike MemoryStorage (which ignores kind), this stores data in separate maps per StorageKind, enabling tests to verify that operations route to the correct kind.

    Not intended for production use. Prefer MemoryStorage for general in-memory usage or CallbackStorage for external backends.

    KindAwareStorage::list_kind

    fn KindAwareStorage::list_kind(self : KindAwareStorage, kind : StorageKind) -> Array[String]

    List files stored under a specific kind

    KindAwareStorage::new

    MemoryStorage

    pub struct MemoryStorage {
    data : Map[String, Bytes]
    }

    Memory-based storage implementation for testing and in-memory use cases

    MemoryStorage::append

    fn MemoryStorage::append(self : MemoryStorage, path : String, data : Bytes) -> Unit

    Append data to file

    MemoryStorage::atomic_write

    fn MemoryStorage::atomic_write(self : MemoryStorage, path : String, data : Bytes) -> Unit

    Atomic write (same as write for in-memory implementation)

    MemoryStorage::clear

    fn MemoryStorage::clear(self : MemoryStorage) -> Unit

    Clear all files

    MemoryStorage::del

    fn MemoryStorage::del(self : MemoryStorage, path : String) -> Unit raise IOError

    Delete a file

    MemoryStorage::exists

    fn MemoryStorage::exists(self : MemoryStorage, path : String) -> Bool

    Check if a file exists

    MemoryStorage::list

    fn MemoryStorage::list(self : MemoryStorage) -> Array[String]

    List all files

    MemoryStorage::new

    Create a new empty MemoryStorage

    MemoryStorage::read

    fn MemoryStorage::read(self : MemoryStorage, path : String) -> Bytes raise IOError

    Read file contents

    MemoryStorage::write

    fn MemoryStorage::write(self : MemoryStorage, path : String, data : Bytes) -> Unit

    Write file contents (overwrites)

    NativeFileStorage

    pub struct NativeFileStorage {
    root_dir : String
    }

    NativeFileStorage::append

    fn NativeFileStorage::append(self : NativeFileStorage, path : String, data : Bytes, kind : StorageKind) -> Unit raise IOError

    NativeFileStorage::atomic_write

    fn NativeFileStorage::atomic_write(self : NativeFileStorage, path : String, data : Bytes, kind : StorageKind) -> Unit raise IOError

    NativeFileStorage::del

    fn NativeFileStorage::del(self : NativeFileStorage, path : String, kind : StorageKind) -> Unit raise IOError

    NativeFileStorage::exists

    fn NativeFileStorage::exists(self : NativeFileStorage, path : String, kind : StorageKind) -> Bool

    NativeFileStorage::list

    fn NativeFileStorage::list(self : NativeFileStorage, kind : StorageKind) -> Array[String] raise IOError

    NativeFileStorage::new

    fn NativeFileStorage::new(root_dir : String) -> NativeFileStorage

    NativeFileStorage::read

    fn NativeFileStorage::read(self : NativeFileStorage, path : String, kind : StorageKind) -> Bytes raise IOError

    NativeFileStorage::write

    fn NativeFileStorage::write(self : NativeFileStorage, path : String, data : Bytes, kind : StorageKind) -> Unit raise IOError

    ReplicatedStorage

    pub struct ReplicatedStorage[T] {
    primary : T
    replicas : Array[T]
    config : ReplicationConfig
    }

    Replicated storage backend.

    T is the underlying AsyncStorage implementation (e.g., JsAsyncCallbackStorage, MemoryStorage, NativeFileStorage).

    Invariants:
    • Primary always receives every operation.
    • Replicas receive write/del operations only.
    • Reads go to primary only (read-local semantics).
    • write_quorum <= 1 + replicas.length()

    ReplicatedStorage::backend_count

    fn[T] ReplicatedStorage::backend_count(self : ReplicatedStorage[T]) -> Int

    Number of total backends (primary + replicas).

    ReplicatedStorage::local_only

    fn[T] ReplicatedStorage::local_only(storage : T) -> ReplicatedStorage[T]

    Create a replicated storage with no replicas (passthrough).

    ReplicatedStorage::new

    fn[T] ReplicatedStorage::new(primary : T, replicas : Array[T], config? : ReplicationConfig) -> ReplicatedStorage[T]

    Create a replicated storage with replicas and custom config.

    ReplicatedStorage::with_all_ack

    fn[T] ReplicatedStorage::with_all_ack(primary : T, replicas : Array[T]) -> ReplicatedStorage[T]

    Create a replicated storage requiring all backends to ack.

    ReplicationConfig

    pub(all) struct ReplicationConfig {
    write_quorum : Int
    }

    Replication configuration for a single storage backend.

    ReplicationConfig::all

    fn ReplicationConfig::all(replica_count : Int) -> ReplicationConfig

    Create a strict replication config requiring all replicas to ack.

    ReplicationConfig::default

    ReplicationConfig::majority

    fn ReplicationConfig::majority(replica_count : Int) -> ReplicationConfig

    Create a majority quorum config.

    StorageKind

    pub(all) enum StorageKind {
    Config
    Index
    Data
    }

    Storage kind - tells app what type of data is being stored App uses this to route to appropriate backend (e.g., index→DynamoDB, data→S3)

    async_atomic_write

    async fn[S : AsyncStorage] async_atomic_write(storage : S, path : String, data : Bytes, kind : StorageKind) -> Unit

    async_del

    async fn[S : AsyncStorage] async_del(storage : S, path : String, kind : StorageKind) -> Unit

    async_exists

    async fn[S : AsyncStorage] async_exists(storage : S, path : String, kind : StorageKind) -> Bool

    async_list

    async fn[S : AsyncStorage] async_list(storage : S, kind : StorageKind) -> Array[String]

    async_read

    async fn[S : AsyncStorage] async_read(storage : S, path : String, kind : StorageKind) -> Bytes

    async_write

    async fn[S : AsyncStorage] async_write(storage : S, path : String, data : Bytes, kind : StorageKind) -> Unit

    collection_config_path

    fn collection_config_path(collection_name : String) -> String

    Path for collection config file

    collection_data_path

    fn collection_data_path(collection_name : String) -> String

    Path for collection data (non-distributed)

    collection_index_path

    fn collection_index_path(collection_name : String) -> String

    Path for collection index file (distributed)

    collection_manifest_path

    fn collection_manifest_path(collection_name : String) -> String

    Path for collection manifest file (distributed)

    collection_wal_path

    fn collection_wal_path(collection_name : String) -> String

    Path for collection WAL file

    ext_config

    let ext_config : String

    Config file extension (not part of binary format, defined here)

    ext_data

    let ext_data : String

    Data file extension (non-distributed, defined here)

    is_segment_path

    fn is_segment_path(path : String, base_name : String) -> Bool

    Check if a path is a segment file for a given collection

    segment_data_path

    fn segment_data_path(base : String, pg : Int, part : Int) -> String

    Path for data segment file