{"id":"z13ak/omnistore","name":"omnistore","scope":"z13ak","platform":"roblox","description":"Typed, game-agnostic Roblox persistence with leases, migrations, and safe mutation APIs","version":"0.2.0-rc.3","latest":"0.2.0-rc.3","versions":["0.2.0-rc.3"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"f1cffd7a1d60d1944710a1106a93bd375742c0b9f045972b898278a35962b9f5","likes":0,"downloads":0,"install":"forest install z13ak/omnistore","url":"https://forest.dev/p/roblox/z13ak/omnistore","files":"https://api.forest.dev/ai/package/roblox/z13ak/omnistore/files","readme":"<p align=\"center\">\r\n  <img src=\"assets/github-banner.png\" alt=\"OmniStore — Typed Persistence for Roblox\" width=\"100%\">\n</p>\r\n\r\n<p align=\"center\">\r\n  <a href=\"https://github.com/z13ak/OmniStore/actions/workflows/ci.yml\"><img alt=\"CI\" src=\"https://github.com/z13ak/OmniStore/actions/workflows/ci.yml/badge.svg\"></a>\n  <a href=\"https://github.com/z13ak/OmniStore/releases\"><img alt=\"Release\" src=\"https://img.shields.io/github/v/release/z13ak/OmniStore?include_prereleases&sort=semver\"></a>\n  <a href=\"LICENSE\"><img alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-22c55e.svg\"></a>\n</p>\n\nOmniStore is a typed persistence library for Roblox:\n\r\n`OmniStore -> Store -> Record -> Data`\r\n\r\nA record key can represent any durable entity: a player, server, guild, world, plot, or something\nspecific to your game. Stores add schemas, migrations, session leases, autosave, and safe mutation\nhelpers on top of Roblox DataStores. Read-only client replication is optional.\n\r\n> **Status:** `0.2.0-rc.3` is a public release candidate. Complete Studio API-services testing in a\r\n> separate universe before using it with production data.\r\n\r\n## Quick start\r\n\r\n```lua\r\nlocal Players = game:GetService(\"Players\")\r\nlocal OmniStore = require(game.ReplicatedStorage.Packages.OmniStore)\r\n\r\nlocal data = OmniStore.new({ namespace = \"MyGame\" })\nlocal profiles = data:GetStore(\"Profiles\", {\n    template = {\r\n        Coins = 0,\r\n        Inventory = {},\r\n        Settings = { Music = true },\r\n    },\r\n    schemaVersion = 1,\r\n})\r\n\r\nPlayers.PlayerAdded:Connect(function(player)\n    local loaded = profiles:LoadAsync(player.UserId)\n    if not loaded.ok then\n        warn(\"Profile load failed\", player.UserId, loaded.error.code)\n        player:Kick(\"Your data could not be loaded. Please rejoin.\")\n        return\n    end\n\n    local profile = loaded.value\n    profile:Increment(\"Coins\", 25)\n    profile:Insert(\"Inventory\", { Id = \"WoodenSword\" })\nend)\n\nPlayers.PlayerRemoving:Connect(function(player)\n    local closed = profiles:CloseRecordAsync(player.UserId, 10)\n    if not closed.ok then\n        warn(\"Profile close failed\", player.UserId, closed.error.code)\n    end\nend)\n```\n\r\nEvery operation that can fail returns `{ ok = true, value = ... }` or\r\n`{ ok = false, error = ... }`. Data reads return defensive copies; mutations must go through the\r\nrecord API so dirty tracking and validation cannot be bypassed accidentally.\r\n\r\n## How writes behave\n\r\n- `UpdateAsync`-oriented writes and atomic per-key lease checks.\r\n- A live lease is never intentionally overwritten; expired leases can be recovered.\r\n- Serialization and optional schema validation run before writes.\r\n- Retryable adapter failures use bounded exponential backoff with jitter.\n- Concurrent save calls coalesce, while mutations made during a save remain dirty.\r\n- `CloseAsync` saves and releases the lease in the same atomic update.\r\n- In-memory transactions use isolated drafts and publish changes only after a successful commit.\r\n- Replication is server-authoritative and exposes only explicitly allowed paths.\r\n\r\n## Important limits\r\n\r\nOmniStore cannot provide database-wide ACID transactions, guaranteed shutdown saves, protection\r\nfrom a compromised server, or immunity to Roblox outages and platform limits. A transaction is\r\natomic only in local memory until a later single-record save. Roblox `UpdateAsync` supplies the\r\natomic compare/transform behavior for one key; operations across keys are not atomic. See\r\n[failure semantics](docs/FAILURE_SEMANTICS.md) and [security](docs/SECURITY.md).\r\n\r\n## Documentation\n\nStart with the [API reference](docs/API.md), [configuration guide](docs/CONFIGURATION.md), and\n[examples](examples). The focused guides cover:\n\n- Data integrity: [failure semantics](docs/FAILURE_SEMANTICS.md),\n  [sessions](docs/SESSIONS.md), [migrations](docs/MIGRATIONS.md), and\n  [transactions](docs/TRANSACTIONS.md).\n- Data shape: [schemas, models, and codecs](docs/SCHEMAS_MODELS_CODECS.md).\n- Operations: [reliability](docs/RELIABILITY.md), [performance](docs/PERFORMANCE.md),\n  [testing](docs/TESTING.md), and [incident response](docs/INCIDENT_RESPONSE.md).\n- Project internals: [architecture](docs/ARCHITECTURE.md),\n  [replication](docs/REPLICATION.md), [security](docs/SECURITY.md), and\n  [compatibility](docs/COMPATIBILITY.md).\n\r\n## Installation\r\n\r\nAdd OmniStore to your `wally.toml`:\r\n\r\n```toml\r\n[dependencies]\r\nOmniStore = \"z13ak/omnistore@0.2.0-rc.3\"\r\n```\r\n\r\nThen run `wally install`. Prebuilt files are also available from the\r\n[GitHub releases](https://github.com/z13ak/OmniStore/releases).\r\n\r\n## Development\r\n\r\nWith [Rokit](https://github.com/rojo-rbx/rokit) installed:\r\n\r\n```sh\r\nrokit install\r\nwally install\r\nrojo build default.project.json -o OmniStore.rbxm\r\nrojo build dev.project.json -o OmniStoreDevelopment.rbxlx\r\nrojo serve test.project.json\r\nstylua --check src tests examples\r\nselene src tests examples\r\n```\r\n\r\nOn Windows, `./scripts/verify.ps1` runs the local format, lint, build, and package checks.\n\r\nAfter `wally install`, connect Studio to `test.project.json`; `tests/init.server.lua` runs the\r\nTestEZ suite. DataStore testing requires a\r\npublished test place with **Enable Studio Access to API Services** enabled; use a separate test\r\nuniverse, never a production universe.\r\n\r\nPull requests run formatting, linting, all Rojo builds, and Wally package inspection in CI. Studio\r\nTestEZ and isolated-universe DataStore smoke tests remain explicit runtime release gates.\r\n\r\n## License\r\n\r\nMIT. See [LICENSE](LICENSE).\r\n","readmeTruncated":false}