Skip to content

Commit

Permalink
Merge pull request #33 from nezuo/more-documentation
Browse files Browse the repository at this point in the history
Add more documentation
  • Loading branch information
nezuo authored Jan 9, 2024
2 parents fd2c14a + 10c5d78 commit af63927
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 9 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# Lapis
A Roblox DataStore abstraction that offers:
- Caching
- Session locking
- Validation (rejects incorrect data)
- Migrations
- Retries
- Throttling
- Promise based API
- Immutability
- **Session Locking** - Documents can only be accessed from one server at a time. This prevents some bugs and duping methods.
- **Validation** - Ensure your data is correct before saving it.
- **Migrations** - Update the structure of your data over time.
- **Retries** - Failed DataStore requests will be retried.
- **Throttling** - DataStore requests will never exceed their budget and throw an error.
- **Promise-based API** - Promises are used instead of yielding.
- **Immutability** - Documents must be updated immutably.
- **Save Batching** - Pending `Document:save()` and `Document:close()` calls are combined into one DataStore request when possible.
- **Auto Save** - Documents are automatically saved every 5 minutes.
- **BindToClose** - All documents are automatically closed when the game shuts down.

This library was inspired by [Quicksave](https://github.com/evaera/Quicksave).

Expand Down
58 changes: 58 additions & 0 deletions docs/Example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
sidebar_position: 2
---

# Example Usage
The following code is an example of how you would load and close player data:
```lua
local DEFAULT_DATA = { coins = 100 }

local collection = Lapis.createCollection("PlayerData", {
defaultData = DEFAULT_DATA,
-- You can use t by osyrisrblx to type check your data at runtime.
validate = t.strictInterface({ coins = t.integer }),
})
local documents = {}

local function onPlayerAdded(player)
-- The second argument associates the document with the player's UserId which is useful
-- for GDPR compliance.
collection
:load(`Player{player.UserId}`, { player.UserId })
:andThen(function(document)
if player.Parent == nil then
-- The player might have left before the document finished loading.
-- The document needs to be closed because PlayerRemoving won't fire at this point.
document:close():catch(warn)
else
documents[player] = document
end
end)
:catch(function(message)
warn(`Player {player.Name}'s data failed to load: {message}`)

-- Optionally, you can kick the player when their data fails to load:
player:Kick("Data failed to load.")
end)
end

local function onPlayerRemoving(player)
local document = documents[player]

-- The document won't be added to the dictionary if PlayerRemoving fires bofore it finishes loading.
if document ~= nil then
documents[player] = nil
document:close():catch(warn)
end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

for _, player in Players:GetPlayers() do
onPlayerAdded(player)
end
```
:::info
You do not need to handle `game:BindToClose` or auto saving. Lapis automatically does both of those.
:::
29 changes: 29 additions & 0 deletions docs/Migrations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
sidebar_position: 3
---

# Writing Migrations
Migrations allow you to update the structure of your data over time. You can add new keys, remove ones you no longer need, or change the way you store something.

Here is an example of a few migrations:
```lua
local MIGRATIONS = {
-- Migrate from version 1 to 2.
function(old)
return Dictionary.merge(old, {
coins = 0, -- Add a key called coins to the data.
})
end,
-- Migrate from version 2 to 3.
function(old)
-- We no longer need the playTime key, so we remove it.
return Dictionary.removeKey(old, "playTime")
end,
}

local collection = Lapis.createCollection("collection", {
migrations = MIGRATIONS,
validate = validate,
defaultData = DEFAULT_DATA,
})
```
17 changes: 17 additions & 0 deletions docs/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
sidebar_position: 1
---

# Introduction

## Features
- **Session Locking** - Documents can only be accessed from one server at a time. This prevents some bugs and duping methods.
- **Validation** - Ensure your data is correct before saving it.
- **Migrations** - Update the structure of your data over time.
- **Retries** - Failed DataStore requests will be retried.
- **Throttling** - DataStore requests will never exceed their budget and throw an error.
- **Promise-based API** - Promises are used instead of yielding.
- **Immutability** - Documents must be updated immutably.
- **Save Batching** - Pending `Document:save()` and `Document:close()` calls are combined into one DataStore request when possible.
- **Auto Save** - Documents are automatically saved every 5 minutes.
- **BindToClose** - All documents are automatically closed when the game shuts down.
2 changes: 1 addition & 1 deletion src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ end
@within Lapis
.validate (any) -> true | (false, string) -- Takes a document's data and returns true on success or false and an error on fail.
.defaultData any
.migrations { (any) -> any } -- Migrations take old data and return new data. Order is first to last.
.migrations { (any) -> any }? -- Migrations take old data and return new data. Order is first to last.
]=]

--[=[
Expand Down

0 comments on commit af63927

Please sign in to comment.