Skip to main content

Store

This item only works when running on the server. Server

A store is a class that holds inner savable objects, Keep(s), from a datastore (DataStoreService:GetDataStore())

Types

StoreInfo

type StoreInfo = {
Namestring,
Scopestring?
}

Table format for a store's info in :GetStore()

Store

type Store = {
MockMockStore,
LoadKeep(
string,
) → Promise<Keep>,
ViewKeep(string) → Promise<Keep>,
PreSave(({any}) → {any}) → nil,
PreLoad(({any}) → {any}) → nil,
PostGlobalUpdate(
string,
(GlobalUpdates) → nil
) → Promise<void>,
IssueSignalSignal,
CriticalStateSignalSignal,
CriticalStateboolean
}

Stores are used to load and save Keeps from a DataStoreService:GetDataStore()

unreleasedHandler

type unreleasedHandler = (Keep.ActiveSession) → "ForceLoad" | "Cancel"

Used to determine how to handle an session locked Keep

Default: "ForceLoad"

"ForceLoad"

Steals the lock, releasing the previous session. It can take up to around 2 auto save cycles (1 on session that is requesting and 1 on session that already owns the lock) to release previous session and save new one if session is locked and up to around 10 minutes if session is in dead lock

"Cancel"

Cancels the load of the Keep

Properties

Wrapper

Store.Wrapper: {}

Wrapper functions that are inheritted by Keeps when they are loaded

info

Any wrapper changes post :GetStore() will not apply to that store but the next one.

Mock

Store.Mock: MockStore

A mock store that mirrors the real store, but doesn't save data

IssueSignal

Store.IssueSignal: Signal

Fired when an issue occurs, like a failed request

keepStore.IssueSignal:Connect(function(err)
	print("Issue!", err)
end)

CriticalStateSignal

Store.CriticalStateSignal: Signal

Fired when the store enters critical state. After it has failed many requests and maybe dangerous to proceed with purchases or other important actions

keepStore.CriticalStateSignal:Connect(function()
	print("Critical State!")
end)

CriticalState

Store.CriticalState: boolean

Whether the store is in critical state or not. See CriticalStateSignal

if keepStore.CriticalState then
	warn("Critical State!")
	return
end

-- process purchase

validate

Store.validate: (any) → true | (false&string)

Used to validate data before saving. Ex. type guards

keepStore.validate = function(data)
	for key, value in data do
		local dataTempVersion = dataTemplate[key]

		if typeof(data[key]) ~= typeof(dataTempVersion) then
			return false, "Invalid type for key " .. key
		end
	end

	return true
end

Functions

GetStore

Store.GetStore(
storeInfoStoreInfo | string,
dataTemplateany
) → Promise<Store>

Loads a store from a DataStoreService:GetDataStore() and returns a Store object

local keepStore = DataKeep.GetStore("TestStore", {
	Test = "Hello World!",
}):expect()

LoadKeep

Store:LoadKeep(
keystring,
unreleasedHandlerunreleasedHandler?
) → Promise<Keep>

Loads a Keep from the store and returns a Keep object

keepStore:LoadKeep(`Player_{player.UserId}`, function()
	return DataKeep.LoadMethods.ForceLoad
end)):andThen(function(keep)
	print(`Loaded {keep:Identify()}!`)
end)
info

Stores can be loaded multiple times as they are cached, that way you can call :LoadKeep() and get the same cached Keeps

ViewKeep

Store:ViewKeep(
keystring,
versionstring?
) → Promise<Keep>

Loads a Keep from the store and returns a Keep object, but doesn't save it

View only Keeps have the same functions as normal Keeps, but can not operate on data

keepStore:ViewKeep(`Player_{player.UserId}`):andThen(function(viewOnlyKeep)
	print(`Viewing {viewOnlyKeep:Identify()}!`)
end)

PreSave

Store:PreSave(callback({any}) → {anyany}) → ()

Runs before saving a Keep, allowing you to modify the data before, like compressing data

caution

Functions must return a new data table. Failure to do so will result in data loss.

warning

:PreSave() can only be set once

Compression example:

keepStore:PreSave(function(data)
	local newData = {}

	for key, value in data do
		newData[key] = HttpService:JSONEncode(value)
	end

	return newData
end)

PreLoad

Store:PreLoad(callback({any}) → {anyany}) → ()

Runs before loading a Keep, allowing you to modify the data before, like decompressing compressed data

caution

Functions must return a new data table. Failure to do so will result in data loss.

warning

:PreLoad() can only be set once

Decompression example:

keepStore:PreLoad(function(data)
	local newData = {}

	for key, value in data do
		newData[key] = HttpService:JSONDecode(value)
	end

	return newData
end)

PostGlobalUpdate

Store:PostGlobalUpdate(
keystring,
updateHandler(GlobalUpdates) → nil
) → Promise<void>

Posts a global update to a Keep

updateHandler reveals globalUpdates to the API

keepStore:PostGlobalUpdate(`Player_{player.UserId}`, function(globalUpdates)
	globalUpdates:AddGlobalUpdate({
		Hello = "World!",
	}):andThen(function(updateId)
		print("Added Global Update!")
	end)
end)
Show raw api
{
    "functions": [
        {
            "name": "GetStore",
            "desc": "Loads a store from a ```DataStoreService:GetDataStore()``` and returns a Store object\n\n```lua\nlocal keepStore = DataKeep.GetStore(\"TestStore\", {\n\tTest = \"Hello World!\",\n}):expect()\n```",
            "params": [
                {
                    "name": "storeInfo",
                    "desc": "",
                    "lua_type": "StoreInfo | string"
                },
                {
                    "name": "dataTemplate",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<Store>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 381,
                "path": "src/init.lua"
            }
        },
        {
            "name": "LoadKeep",
            "desc": "Loads a Keep from the store and returns a Keep object\n\n```lua\nkeepStore:LoadKeep(`Player_{player.UserId}`, function()\n\treturn DataKeep.LoadMethods.ForceLoad\nend)):andThen(function(keep)\n\tprint(`Loaded {keep:Identify()}!`)\nend)\n```\n\n:::info\nStores can be loaded multiple times as they are cached, that way you can call ```:LoadKeep()``` and get the same cached Keeps\n:::info",
            "params": [
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "unreleasedHandler",
                    "desc": "",
                    "lua_type": "unreleasedHandler?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<Keep>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 492,
                "path": "src/init.lua"
            }
        },
        {
            "name": "ViewKeep",
            "desc": "Loads a Keep from the store and returns a Keep object, but doesn't save it\n\nView only Keeps have the same functions as normal Keeps, but can not operate on data\n\n```lua\nkeepStore:ViewKeep(`Player_{player.UserId}`):andThen(function(viewOnlyKeep)\n\tprint(`Viewing {viewOnlyKeep:Identify()}!`)\nend)\n```",
            "params": [
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "version",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<Keep>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 599,
                "path": "src/init.lua"
            }
        },
        {
            "name": "PreSave",
            "desc": "Runs before saving a Keep, allowing you to modify the data before, like compressing data\n\n:::caution\nFunctions **must** return a new data table. Failure to do so will result in data loss.\n:::caution\n\n:::warning\n```:PreSave()``` can only be set once\n:::warning\n\nCompression example:\n\n```lua\nkeepStore:PreSave(function(data)\n\tlocal newData = {}\n\n\tfor key, value in data do\n\t\tnewData[key] = HttpService:JSONEncode(value)\n\tend\n\n\treturn newData\nend)\n```",
            "params": [
                {
                    "name": "callback",
                    "desc": "",
                    "lua_type": "({ any }) -> { any: any }"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 681,
                "path": "src/init.lua"
            }
        },
        {
            "name": "PreLoad",
            "desc": "Runs before loading a Keep, allowing you to modify the data before, like decompressing compressed data\n\n:::caution\nFunctions **must** return a new data table. Failure to do so will result in data loss.\n:::caution\n\n:::warning\n```:PreLoad()``` can only be set once\n:::warning\n\nDecompression example:\n\n```lua\nkeepStore:PreLoad(function(data)\n\tlocal newData = {}\n\n\tfor key, value in data do\n\t\tnewData[key] = HttpService:JSONDecode(value)\n\tend\n\n\treturn newData\nend)\n```",
            "params": [
                {
                    "name": "callback",
                    "desc": "",
                    "lua_type": "({ any }) -> { any: any }"
                }
            ],
            "returns": [],
            "function_type": "method",
            "source": {
                "line": 719,
                "path": "src/init.lua"
            }
        },
        {
            "name": "PostGlobalUpdate",
            "desc": "Posts a global update to a Keep\n\n```updateHandler``` reveals globalUpdates to the API\n\n```lua\nkeepStore:PostGlobalUpdate(`Player_{player.UserId}`, function(globalUpdates)\n\tglobalUpdates:AddGlobalUpdate({\n\t\tHello = \"World!\",\n\t}):andThen(function(updateId)\n\t\tprint(\"Added Global Update!\")\n\tend)\nend)\n```",
            "params": [
                {
                    "name": "key",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "updateHandler",
                    "desc": "",
                    "lua_type": "(GlobalUpdates) -> nil"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Promise<void>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 750,
                "path": "src/init.lua"
            }
        }
    ],
    "properties": [
        {
            "name": "Wrapper",
            "desc": "Wrapper functions that are inheritted by Keeps when they are loaded\n\n:::info\nAny wrapper changes post ```:GetStore()``` will not apply to that store but the next one.\n:::info",
            "lua_type": "{}",
            "source": {
                "line": 95,
                "path": "src/init.lua"
            }
        },
        {
            "name": "Mock",
            "desc": "A mock store that mirrors the real store, but doesn't save data",
            "lua_type": "MockStore",
            "source": {
                "line": 102,
                "path": "src/init.lua"
            }
        },
        {
            "name": "IssueSignal",
            "desc": "Fired when an issue occurs, like a failed request\n\n```lua\nkeepStore.IssueSignal:Connect(function(err)\n\tprint(\"Issue!\", err)\nend)\n```",
            "lua_type": "Signal",
            "source": {
                "line": 115,
                "path": "src/init.lua"
            }
        },
        {
            "name": "CriticalStateSignal",
            "desc": "Fired when the store enters critical state. After it has failed many requests and maybe dangerous to proceed with purchases or other important actions\n\n```lua\nkeepStore.CriticalStateSignal:Connect(function()\n\tprint(\"Critical State!\")\nend)\n```",
            "lua_type": "Signal",
            "source": {
                "line": 128,
                "path": "src/init.lua"
            }
        },
        {
            "name": "CriticalState",
            "desc": "Whether the store is in critical state or not. See ```CriticalStateSignal```\n\n```lua\nif keepStore.CriticalState then\n\twarn(\"Critical State!\")\n\treturn\nend\n\n-- process purchase\n```",
            "lua_type": "boolean",
            "source": {
                "line": 144,
                "path": "src/init.lua"
            }
        },
        {
            "name": "validate",
            "desc": "Used to validate data before saving. Ex. type guards\n\n```lua\nkeepStore.validate = function(data)\n\tfor key, value in data do\n\t\tlocal dataTempVersion = dataTemplate[key]\n\n\t\tif typeof(data[key]) ~= typeof(dataTempVersion) then\n\t\t\treturn false, \"Invalid type for key \" .. key\n\t\tend\n\tend\n\n\treturn true\nend\n```",
            "lua_type": "(any) -> true | (false & string)",
            "source": {
                "line": 165,
                "path": "src/init.lua"
            }
        }
    ],
    "types": [
        {
            "name": "StoreInfo",
            "desc": "Table format for a store's info in ```:GetStore()```",
            "lua_type": "{Name: string, Scope: string?}",
            "source": {
                "line": 67,
                "path": "src/init.lua"
            }
        },
        {
            "name": "Store",
            "desc": "Stores are used to load and save Keeps from a ```DataStoreService:GetDataStore()```",
            "lua_type": "{Mock: MockStore, LoadKeep: (string, unreleasedHandler?) -> Promise<Keep>, ViewKeep: (string) -> Promise<Keep>, PreSave: (({any}) -> {any}) -> nil, PreLoad: (({any}) -> {any}) -> nil, PostGlobalUpdate: (string, (GlobalUpdates) -> nil) -> Promise<void>, IssueSignal: Signal, CriticalStateSignal: Signal, CriticalState: boolean}",
            "source": {
                "line": 84,
                "path": "src/init.lua"
            }
        },
        {
            "name": "unreleasedHandler",
            "desc": "Used to determine how to handle an session locked Keep\n\n### Default: \"ForceLoad\"\n\n\n### \"ForceLoad\"\n\nSteals the lock, releasing the previous session. It can take up to around 2 auto save cycles (1 on session that is requesting and 1 on session that already owns the lock) to release previous session and save new one if session is locked and up to around 10 minutes if session is in dead lock\n\n\n### \"Cancel\"\n\nCancels the load of the Keep",
            "lua_type": "(Keep.ActiveSession) -> \"ForceLoad\" | \"Cancel\"",
            "source": {
                "line": 201,
                "path": "src/init.lua"
            }
        }
    ],
    "name": "Store",
    "desc": "A store is a class that holds inner savable objects, Keep(s), from a datastore (DataStoreService:GetDataStore())",
    "realm": [
        "Server"
    ],
    "source": {
        "line": 24,
        "path": "src/init.lua"
    }
}