Skip to main content

Store

This item is only intended to be used by the module's authors. Private

Coordinates Sessions and provides a safe, high-level API for interacting with persistent data stored in Roblox DataStores and MemoryStores.

Core Responsibilities:

  • Manages the lifecycle of Session objects for individual data keys (e.g., player IDs).
  • Provides methods for loading, reading (get), updating (update), and saving data.
  • Implements atomic multi-key transactions (tx).
  • Handles data validation, migrations, and optional legacy data import.
  • Abstracts away underlying complexities like data sharding (Files), distributed locking (Locks), and transaction coordination (Transactions).
  • Integrates with a configurable logging system (Log).

Usage Example:

local store = Store.createStore({
	name = "PlayerData",
	template = {
		coins = 0,
		items = {},
	},
	schema = function(data)
		return typeof(data.coins) == "number" and typeof(data.items) == "table",
		"Invalid data format"
	end,
	-- ... other config options
})

-- Load data for a player
store:load("player_1"):andThen(function()
	-- Get current data
	return store:get("player_1")
end):andThen(function(data)
	print(data.coins) -- 0

	-- Update data
	return store:update("player_1", function(data)
		data.coins += 100
		return true -- Must return true to commit changes
	end)
end)

Types

StoreConfig

interface StoreConfig {
namestring--

A unique name for this store (e.g., "PlayerDataProd"). Used for logging and deriving DataStore/MemoryStore keys.

templateT--

A deep copyable Luau table/value representing the default state for a new key.

schema(valueany) → (
boolean,
string?
)--

A validation function (e.g., created with t) that checks if data conforms to the expected structure. Returns true if valid, or false and an error message if invalid.

migrationSteps{Types.MigrationStep}?--

An optional ordered list of migration steps to apply to data loaded from the DataStore if its schema is older than the current version. See Migrations.luau.

importLegacyData((keystring) → any?)?--

An optional function to load data from a different, legacy storage system when a key is accessed for the first time and doesn't exist in this store.

dataStoreServiceDataStoreService?--

An optional override for the Roblox DataStoreService. Useful for testing or custom storage implementations. Defaults to game:GetService("DataStoreService").

memoryStoreServiceMemoryStoreService?--

An optional override for the Roblox MemoryStoreService. Useful for testing. Defaults to game:GetService("MemoryStoreService").

useMockboolean?--

If true (and running in Studio), uses mock in-memory implementations of DataStoreService and MemoryStoreService instead of the actual Roblox services. Useful for testing in a controlled environment. Defaults to false.

changedCallbacks{(
keystring,
newDataT,
oldDataT?
) → ()}?--

An optional list of functions called after data for a key has been successfully updated. Provides the key, the new data state, and the previous data state (if available).

logCallback((logMessageLog.LogMessage) → ())?--

A function to receive log messages generated by this Store instance and its components. If omitted, logs are discarded. See Log.

onLockLost((keystring) → ())?--

An optional callback function triggered if the distributed lock for a key's session is lost unexpectedly (e.g., due to expiration or external interference). This usually indicates the session is no longer safe to use.

}

Configuration options for creating a new Store instance using createStore.

Functions

createStore

Store.createStore(
configStoreConfig<T>--

Configuration options for the store.

) → Store<T>--

A new, initialized Store instance.

Factory function to create a new Store instance.

Initializes the store context, sets up DataStore and MemoryStore connections (real or mock), validates the template schema, and returns the configured Store object.

txInternal

Store.txInternal(
selfStore<T>,
keys{string},--

An array of keys involved in the transaction.

transformFunction((state{[string]any}) → boolean) | ((state{[string]any}) → {[string]any} | false),--

A function that receives the current state of all keys and, depending on immutable, either modifies it directly (mutable) and returns true to commit, or returns a new state (immutable) to commit. Must return false to abort the transaction.

immutableboolean
) → Promise--

Resolves with true if the transaction was successful, or false if it was aborted. Rejects on error.

Internal helper to perform transaction logic on multiple keys. Handles acquiring locks, validating state, and committing changes atomically via a two-phase commit process.

Supports both immutable and mutable transactions, where immutable controls whether the data passed to the transformFunction is a deep copy (mutable) or a reference to the canonical, frozen data (immutable).

Implementation Details:

  • Uses PromiseQueue.multiQueueAdd to ensure the transform function only runs when all involved session queues are ready.
  • Uses a temporary txLockPromise on sessions to block concurrent update calls while the transaction logic is executing.
  • Performs a two-phase commit using a transaction marker in the txStore:
    1. Write false to txStore under a unique txId.
    2. Update all primary recordStore entries with the new data and txId.
    3. If successful, remove the txId entry from txStore.
  • If any step fails, attempts to revert changes by rewriting records without the txId and removing the txId marker.
  • Uses JsonPatch to calculate differences for efficient storage in TxInfo.

Propagates DataStore errors encountered during the commit or revert phases.

Errors

TypeDescription
"Key not loaded"If any key in the `keys` array has not been loaded.
"Key is already locked by another transaction"If any key is already involved in an ongoing `tx`.
"Key is closed"If any involved session has been closed (e.g., due to lock loss).
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data for any key after transformation fails the schema check.
"Keys changed in transaction"If the `transformFunction` attempts to add or remove keys from the state table it receives.

load

Store:load(
keystring,--

The unique identifier for the data to load (e.g., "player_123").

userIds{number}?--

Optional list of UserIDs for DataStore key tagging.

) → Promise--

Resolves when the data is successfully loaded and the session is ready, or rejects on error.

Acquires a distributed lock, loads data for the given key into memory, and establishes a Session object to manage the key's state.

This must be called before performing operations like get, update, or save on the key. It handles concurrent load attempts and waits for any ongoing unload operations to complete first.

Propagates errors from Session.load (e.g., lock acquisition failure, DataStore errors).

Errors

TypeDescription
"Load already in progress"If `load` is called again for the same key while a previous load is still running.
"Store is closed"If the store instance has been closed via `close()`.

loadAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:loadAsync(
keystring,--

The unique identifier for the data to load.

userIds{number}?--

Optional list of UserIDs for DataStore key tagging.

) → ()

Synchronous wrapper for Store:load. Waits for the Promise to settle. Throws an error if the load fails or is cancelled.

Errors

TypeDescription
anyThrows any error encountered during the load process.

unload

Store:unload(
keystring--

The unique identifier for the data to unload.

) → Promise--

Resolves when the data is successfully unloaded, or rejects on error.

Unloads data for the given key from memory, saves any pending changes, releases the distributed lock, and ends the session.

Propagates errors from Session:unload (e.g., save failures).

Errors

TypeDescription
"Store is closed"If the store instance has been closed.

unloadAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:unloadAsync(
keystring--

The unique identifier for the data to unload.

) → ()

Synchronous wrapper for Store:unload. Waits for the Promise to settle. Throws an error if the unload fails.

Errors

TypeDescription
anyThrows any error encountered during the unload process.

get

Store:get(
keystring--

The key whose data to retrieve.

) → Promise<T>--

Resolves with the current data object (potentially a deep copy).

Gets the current, in-memory data state for the given key. Requires the key to be loaded first via load(). If the key is still loading, this will wait for it to finish.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store has been closed.

getAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:getAsync(
keystring--

The key whose data to retrieve.

) → T--

The current data object.

Synchronous wrapper for Store:get. Waits for the Promise to settle. Throws an error if getting the data fails.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store has been closed.

update

Store:update(
keystring,--

The key whose data to update.

transformFunction(dataT) → boolean--

A function that receives the current data and returns true to commit changes or false to abort.

) → Promise<boolean>--

Resolves with true if the transform function returned true and the update was successfully queued, or false if the transform function returned false. Rejects on errors like key not loaded, store closed, or schema validation failure after transformation.

Applies changes to the data for a given key using a transform function.

The transformFunction receives the current data and can modify it directly. It must return true to indicate that changes were made and should be saved, or false to abort the update without saving.

Changes are applied optimistically to the in-memory state first and then queued for saving to the DataStore.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data returned by `transformFunction` does not pass the store's schema check.

updateAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:updateAsync(
keystring,--

The key whose data to update.

transformFunction(dataT) → boolean--

The transformation function.

) → boolean--

Returns the boolean value returned by the transformFunction.

Synchronous wrapper for Store:update. Waits for the Promise to settle. Throws an error if the update fails.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data returned by `transformFunction` does not pass the store's schema check.

updateImmutable

Store:updateImmutable(
keystring,--

The key whose data to update.

transformFunction(dataT) → T | false--

A function that receives the current data and returns a new copy of the data with changes to commit changes, or false to abort.

) → Promise<boolean>--

Resolves with true if the transform function committed and the update was successfully queued, or false if the transform function returned false. Rejects on errors like key not loaded, store closed, or schema validation failure after transformation.

Applies changes to the data for a given key using a transform function, with immutable copy-on-write semantics.

The transformFunction receives the current data but frozen (immutable), and cannot modify it directly. Instead, it should return new data that reflects the desired changes. Otherwise it should return false to abort the update without saving.

Changes are applied optimistically to the in-memory state first and then queued for saving to the DataStore.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data returned by `transformFunction` does not pass the store's schema check.

updateImmutableAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:updateImmutableAsync(
keystring,--

The key whose data to update.

transformFunction(dataT) → T | false--

The transformation function.

) → boolean--

Returns true if the update was successful, or false if the transform function returned false.

Synchronous wrapper for Store:updateImmutable. Waits for the Promise to settle. Throws an error if the update fails.

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data returned by `transformFunction` does not pass the store's schema check.

tx

Store:tx(
keys{string},--

An array of keys involved in the transaction.

transformFunction(state{[string]T}) → boolean--

The transformation function.

) → Promise<boolean>--

Resolves with true if the transaction was successful, or false if it was aborted. Rejects on error.

Performs an atomic transaction across multiple keys.

Requires the keys to be loaded first via load(). The transformFunction is called with the current state of all involved keys and must return true to commit changes or false to abort.

Propagates errors from the transaction process, including DataStore errors, schema validation failures, and key loading issues.

Errors

TypeDescription
"Key not loaded"If any key in the `keys` array has not been loaded.
"Key is already locked by another transaction"If any key is already involved in an ongoing `tx`.
"Key is closed"If any involved session has been closed (e.g., due to lock loss).
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data for any key after transformation fails the schema check.
"Keys changed in transaction"If the `transformFunction` attempts to add or remove keys from the state table it receives.

txAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:txAsync(
keys{string},--

An array of keys involved in the transaction.

transformFunction(state{[string]T}) → boolean--

The transformation function.

) → ()

Synchronous wrapper for Store:tx. Waits for the Promise to settle. Throws an error if the transaction fails or is aborted.

Errors

TypeDescription
anyThrows any error encountered during the transaction.

txImmutable

Store:txImmutable(
keys{string},--

An array of keys involved in the transaction.

transformFunction(state{[string]T}) → {[string]T} | false--

The transformation function.

) → Promise<boolean>--

Resolves with true if the transaction was successful, or false if it was aborted. Rejects on error.

Performs an atomic transaction across multiple keys with immutable, copy-on-write semantics.

The data passed to the function is frozen and cannot be modified directly. Instead, the function should return a new table with the desired changes.

Requires the keys to be loaded first via load(). The transformFunction is called with the current state of all involved keys and must return the new state to commit or false to abort.

Propagates errors from the transaction process, including DataStore errors, schema validation failures, and key loading issues.

Errors

TypeDescription
"Key not loaded"If any key in the `keys` array has not been loaded.
"Key is already locked by another transaction"If any key is already involved in an ongoing `tx`.
"Key is closed"If any involved session has been closed (e.g., due to lock loss).
"Store is closed"If the store instance has been closed.
"Schema validation failed"If the data for any key after transformation fails the schema check.
"Keys changed in transaction"If the `transformFunction` attempts to add or remove keys from the state table it receives.

txImmutableAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:txImmutableAsync(
keys{string},--

An array of keys involved in the transaction.

transformFunction(state{[string]T}) → {[string]T} | false--

The transformation function.

) → boolean

Synchronous wrapper for Store:txImmutable. Waits for the Promise to settle. Throws an error if the transaction fails or is aborted.

Errors

TypeDescription
anyThrows any error encountered during the transaction.

save

Store:save(
keystring--

The key whose data to save.

) → Promise--

Resolves when the save operation completes successfully, rejects on error.

Forces an immediate save of the given key's current in-memory data state to the DataStore.

NOTE

Data is automatically saved periodically by the Session's autosave mechanism. Manual saves are typically only needed in specific scenarios like processing developer product purchases (MarketplaceService.ProcessReceipt) where immediate persistence is crucial before granting benefits.

Propagates errors from Session:save (e.g., DataStore write errors).

Errors

TypeDescription
"Key not loaded"If `load()` has not been successfully called for this key.
"Store is closed"If the store instance has been closed.

saveAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:saveAsync(
keystring--

The key whose data to save.

) → ()

Synchronous wrapper for Store:save. Waits for the Promise to settle. Throws an error if the save fails.

Errors

TypeDescription
anyThrows any error encountered during the save operation.

close

Store:close() → Promise--

Resolves when all sessions have attempted to unload, or rejects if any session encountered an error during its unload process (errors are aggregated).

Closes the store, gracefully unloading all active sessions.

Attempts to save any pending changes for all loaded keys before releasing locks and removing sessions from memory. The store instance becomes unusable as soon as this is called.

closeAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:closeAsync() → ()

Synchronous wrapper for Store:close. Waits for the Promise to settle. Throws an error if closing fails (i.e., if any session failed to unload).

Errors

TypeDescription
anyThrows an error (potentially a table of errors) if closing fails.

peek

Store:peek(
keystring--

The key whose data to peek at.

) → Promise<T?>--

Resolves with the data object, or nil if the key doesn't exist. Rejects on DataStore errors.

Reads the current data for the given key directly from the DataStore, bypassing the session cache and locking mechanism.

This provides a snapshot of the last saved state but does not load the key into an active session. Useful for inspecting data without acquiring a lock. Handles potential sharding and transaction status automatically.

Propagates DataStore errors from underlying reads.

peekAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:peekAsync(
keystring--

The key whose data to peek at.

) → T?--

The data object, or nil if the key doesn't exist.

Synchronous wrapper for Store:peek. Waits for the Promise to settle. Returns the data for the key if it exists. Throws on any errors from underlying DataStore operations.

Errors

TypeDescription
anyMay throw errors from underlying DataStore operations.

probeLockActive

Store:probeLockActive(
keystring--

The key to check the lock status for.

) → Promise<boolean>--

Resolves with true if a lock is active, false otherwise. Rejects on MemoryStore errors.

Checks if a distributed lock is currently active for the given key in MemoryStore.

Propagates errors from Locks.probeLockActive.

probeLockActiveAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:probeLockActiveAsync(
keystring--

The key to check the lock status for.

) → boolean--

true if a lock is active, false otherwise.

Synchronous wrapper for Store:probeLockActive. Waits for the Promise to settle. Throws an error if the check fails.

Errors

TypeDescription
anyThrows any error encountered during the probe operation.

listVersions

Store:listVersions(
paramsListVersionParams--

Parameters specifying the key, sorting, date range, and page size.

) → Promise<DataStoreVersionPages>--

Resolves with an iterator object (DataStoreVersionPages) that can be used to fetch pages of version history. Rejects on DataStore errors.

Lists historical versions of the data for a given key using DataStore versioning.

Propagates errors from DataStore:ListVersionsAsync.

listVersionsAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:listVersionsAsync(
paramsListVersionParams--

Parameters for listing versions.

) → DataStoreVersionPages--

An iterator for version history.

Synchronous wrapper for Store:listVersions. Waits for the Promise to settle. Throws an error if listing versions fails.

Errors

TypeDescription
anyThrows any error encountered during the list operation.

readVersion

Store:readVersion(
keystring,--

The key whose version to read.

versionstring--

The specific version ID (obtained from listVersions).

) → Promise<(
T,
)>--

Resolves with the data object (T) and the DataStoreKeyInfo for that version. Rejects if the version doesn't exist or on DataStore/read errors.

Reads the data content of a specific historical version for a given key.

Propagates DataStore errors from underlying reads.

Errors

TypeDescription
"Record not found"If the specified version doesn't exist.

readVersionAsync

This is a yielding function. When called, it will pause the Lua thread that called the function until a result is ready to be returned, without interrupting other scripts. Yields
Store:readVersionAsync(
keystring,--

The key whose version to read.

versionstring--

The specific version ID.

) → (
T,--

The data object for the specified version.

DataStoreKeyInfo--

The key info for the specified version.

)

Synchronous wrapper for Store:readVersion. Waits for the Promise to settle. Throws an error if reading the version fails.

Errors

TypeDescription
anyThrows any error encountered during the read operation.
Show raw api
{
    "functions": [
        {
            "name": "createStore",
            "desc": "Factory function to create a new Store instance.\n\nInitializes the store context, sets up DataStore and MemoryStore connections\n(real or mock), validates the template schema, and returns the configured Store object.",
            "params": [
                {
                    "name": "config",
                    "desc": "Configuration options for the store.",
                    "lua_type": "StoreConfig<T>"
                }
            ],
            "returns": [
                {
                    "desc": "A new, initialized Store instance.",
                    "lua_type": "Store<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 217,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "load",
            "desc": "Acquires a distributed lock, loads data for the given key into memory, \nand establishes a `Session` object to manage the key's state.\n\nThis must be called before performing operations like `get`, `update`, or `save`\non the key. It handles concurrent load attempts and waits for any ongoing unload\noperations to complete first.\n\nPropagates errors from `Session.load` (e.g., lock acquisition failure, DataStore errors).",
            "params": [
                {
                    "name": "key",
                    "desc": "The unique identifier for the data to load (e.g., \"player_123\").",
                    "lua_type": "string"
                },
                {
                    "name": "userIds",
                    "desc": "Optional list of UserIDs for DataStore key tagging.",
                    "lua_type": "{number}?"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves when the data is successfully loaded and the session is ready, or rejects on error.",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Load already in progress\"",
                    "desc": "If `load` is called again for the same key while a previous load is still running."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed via `close()`."
                }
            ],
            "source": {
                "line": 351,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "loadAsync",
            "desc": "Synchronous wrapper for [Store:load]. Waits for the Promise to settle.\nThrows an error if the load fails or is cancelled.",
            "params": [
                {
                    "name": "key",
                    "desc": "The unique identifier for the data to load.",
                    "lua_type": "string"
                },
                {
                    "name": "userIds",
                    "desc": "Optional list of UserIDs for DataStore key tagging.",
                    "lua_type": "{number}?"
                }
            ],
            "returns": [],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the load process."
                }
            ],
            "yields": true,
            "source": {
                "line": 460,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "unload",
            "desc": "Unloads data for the given key from memory, saves any pending changes,\nreleases the distributed lock, and ends the session.\n\nPropagates errors from `Session:unload` (e.g., save failures).",
            "params": [
                {
                    "name": "key",
                    "desc": "The unique identifier for the data to unload.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves when the data is successfully unloaded, or rejects on error.",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                }
            ],
            "source": {
                "line": 475,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "unloadAsync",
            "desc": "Synchronous wrapper for [Store:unload]. Waits for the Promise to settle.\nThrows an error if the unload fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The unique identifier for the data to unload.",
                    "lua_type": "string"
                }
            ],
            "returns": [],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the unload process."
                }
            ],
            "yields": true,
            "source": {
                "line": 529,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "_withSession",
            "desc": "Internal helper function to safely access the session for a given key.\nHandles waiting for load/unload operations and checks store/session state.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose session is needed.",
                    "lua_type": "string"
                },
                {
                    "name": "callback",
                    "desc": "The function to execute with the session object.",
                    "lua_type": "(session: Session.Session<any>) -> any"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with the return value of the callback, or rejects if the session cannot be accessed (e.g., not loaded, store closed, load cancelled).",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "private": true,
            "source": {
                "line": 543,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "_getKeyInfo",
            "desc": "Internal helper to get the DataStoreKeyInfo for a loaded key's session.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose info is needed.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with the key info object, or nil if the session doesn't have key info (shouldn't normally happen for loaded sessions). Rejects if the session cannot be accessed.",
                    "lua_type": "Promise<DataStoreKeyInfo?>"
                }
            ],
            "function_type": "method",
            "private": true,
            "source": {
                "line": 596,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "get",
            "desc": "Gets the current, in-memory data state for the given key.\nRequires the key to be loaded first via `load()`.\nIf the key is still loading, this will wait for it to finish.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to retrieve.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with the current data object (potentially a deep copy).",
                    "lua_type": "Promise<T>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store has been closed."
                }
            ],
            "source": {
                "line": 614,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "getAsync",
            "desc": "Synchronous wrapper for [Store:get]. Waits for the Promise to settle.\nThrows an error if getting the data fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to retrieve.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "The current data object.",
                    "lua_type": "T"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store has been closed."
                }
            ],
            "yields": true,
            "source": {
                "line": 633,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "update",
            "desc": "Applies changes to the data for a given key using a transform function.\n\nThe `transformFunction` receives the current data and can modify it directly.\nIt **must** return `true` to indicate that changes were made and should be\nsaved, or `false` to abort the update without saving.\n\nChanges are applied optimistically to the in-memory state first and then queued\nfor saving to the DataStore.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to update.",
                    "lua_type": "string"
                },
                {
                    "name": "transformFunction",
                    "desc": "A function that receives the current data and returns `true` to commit changes or `false` to abort.",
                    "lua_type": "(data: T) -> boolean"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if the transform function returned `true` and the update was successfully queued, or `false` if the transform function returned `false`. Rejects on errors like key not loaded, store closed, or schema validation failure after transformation.",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data returned by `transformFunction` does not pass the store's schema check."
                }
            ],
            "source": {
                "line": 655,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "updateAsync",
            "desc": "Synchronous wrapper for [Store:update]. Waits for the Promise to settle.\nThrows an error if the update fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to update.",
                    "lua_type": "string"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(data: T) -> boolean"
                }
            ],
            "returns": [
                {
                    "desc": "Returns the boolean value returned by the `transformFunction`.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data returned by `transformFunction` does not pass the store's schema check."
                }
            ],
            "yields": true,
            "source": {
                "line": 678,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "updateImmutable",
            "desc": "Applies changes to the data for a given key using a transform function,\nwith immutable copy-on-write semantics.\n\nThe `transformFunction` receives the current data but frozen (immutable),\nand cannot modify it directly. Instead, it should return new data that\nreflects the desired changes. Otherwise it should return `false` to abort\nthe update without saving.\n\nChanges are applied optimistically to the in-memory state first and then queued\nfor saving to the DataStore.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to update.",
                    "lua_type": "string"
                },
                {
                    "name": "transformFunction",
                    "desc": "A function that receives the current data and returns a new copy of the data with changes to commit changes, or `false` to abort.",
                    "lua_type": "(data: T) -> T | false"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if the transform function committed and the update was successfully queued, or `false` if the transform function returned `false`. Rejects on errors like key not loaded, store closed, or schema validation failure after transformation.",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data returned by `transformFunction` does not pass the store's schema check."
                }
            ],
            "source": {
                "line": 702,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "updateImmutableAsync",
            "desc": "Synchronous wrapper for [Store:updateImmutable]. Waits for the Promise to settle.\nThrows an error if the update fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to update.",
                    "lua_type": "string"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(data: T) -> T | false"
                }
            ],
            "returns": [
                {
                    "desc": "Returns `true` if the update was successful, or `false` if the transform function returned `false`.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data returned by `transformFunction` does not pass the store's schema check."
                }
            ],
            "yields": true,
            "source": {
                "line": 725,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "txInternal",
            "desc": "Internal helper to perform transaction logic on multiple keys.\nHandles acquiring locks, validating state, and committing changes atomically\nvia a two-phase commit process.\n\nSupports both immutable and mutable transactions, where `immutable` controls\nwhether the data passed to the `transformFunction` is a deep copy (mutable)\nor a reference to the canonical, frozen data (immutable).\n\n**Implementation Details:**\n- Uses `PromiseQueue.multiQueueAdd` to ensure the transform function only runs\n  when all involved session queues are ready.\n- Uses a temporary `txLockPromise` on sessions to block concurrent `update` calls\n  while the transaction logic is executing.\n- Performs a two-phase commit using a transaction marker in the `txStore`:\n\t1. Write `false` to `txStore` under a unique `txId`.\n\t2. Update all primary `recordStore` entries with the new data and `txId`.\n\t3. If successful, remove the `txId` entry from `txStore`.\n- If any step fails, attempts to revert changes by rewriting records without the `txId`\n  and removing the `txId` marker.\n- Uses `JsonPatch` to calculate differences for efficient storage in `TxInfo`.\n\nPropagates DataStore errors encountered during the commit or revert phases.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Store<T>"
                },
                {
                    "name": "keys",
                    "desc": "An array of keys involved in the transaction.",
                    "lua_type": "{string}"
                },
                {
                    "name": "transformFunction",
                    "desc": "A function that receives the current state of all keys and, depending on `immutable`, either modifies it directly (mutable) and returns `true` to commit, or returns a new state (immutable) to commit. Must return `false` to abort the transaction.",
                    "lua_type": "((state: { [string]: any }) -> boolean) | ((state: { [string]: any }) -> { [string]: any } | false)"
                },
                {
                    "name": "immutable",
                    "desc": "",
                    "lua_type": "boolean\n"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if the transaction was successful, or `false` if it was aborted. Rejects on error.",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "static",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If any key in the `keys` array has not been loaded."
                },
                {
                    "lua_type": "\"Key is already locked by another transaction\"",
                    "desc": "If any key is already involved in an ongoing `tx`."
                },
                {
                    "lua_type": "\"Key is closed\"",
                    "desc": "If any involved session has been closed (e.g., due to lock loss)."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data for any key after transformation fails the schema check."
                },
                {
                    "lua_type": "\"Keys changed in transaction\"",
                    "desc": "If the `transformFunction` attempts to add or remove keys from the state table it receives."
                }
            ],
            "source": {
                "line": 764,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "tx",
            "desc": "Performs an atomic transaction across multiple keys.\n\nRequires the keys to be loaded first via `load()`. The `transformFunction`\nis called with the current state of all involved keys and must return `true`\nto commit changes or `false` to abort.\n\nPropagates errors from the transaction process, including DataStore errors,\nschema validation failures, and key loading issues.",
            "params": [
                {
                    "name": "keys",
                    "desc": "An array of keys involved in the transaction.",
                    "lua_type": "{string}"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(state: { [string]: T }) -> boolean"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if the transaction was successful, or `false` if it was aborted. Rejects on error.",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If any key in the `keys` array has not been loaded."
                },
                {
                    "lua_type": "\"Key is already locked by another transaction\"",
                    "desc": "If any key is already involved in an ongoing `tx`."
                },
                {
                    "lua_type": "\"Key is closed\"",
                    "desc": "If any involved session has been closed (e.g., due to lock loss)."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data for any key after transformation fails the schema check."
                },
                {
                    "lua_type": "\"Keys changed in transaction\"",
                    "desc": "If the `transformFunction` attempts to add or remove keys from the state table it receives."
                }
            ],
            "source": {
                "line": 1087,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "txAsync",
            "desc": "Synchronous wrapper for [Store:tx]. Waits for the Promise to settle.\nThrows an error if the transaction fails or is aborted.",
            "params": [
                {
                    "name": "keys",
                    "desc": "An array of keys involved in the transaction.",
                    "lua_type": "{string}"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(state: { [string]: T }) -> boolean"
                }
            ],
            "returns": [],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the transaction."
                }
            ],
            "yields": true,
            "source": {
                "line": 1104,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "txImmutable",
            "desc": "Performs an atomic transaction across multiple keys with immutable, copy-on-write semantics.\n\nThe data passed to the function is frozen and cannot be modified directly.\nInstead, the function should return a new table with the desired changes.\n\nRequires the keys to be loaded first via `load()`. The `transformFunction`\nis called with the current state of all involved keys and must return the\nnew state to commit or `false` to abort.\n\nPropagates errors from the transaction process, including DataStore errors,\nschema validation failures, and key loading issues.",
            "params": [
                {
                    "name": "keys",
                    "desc": "An array of keys involved in the transaction.",
                    "lua_type": "{string}"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(state: { [string]: T }) -> { [string]: T } | false"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if the transaction was successful, or `false` if it was aborted. Rejects on error.",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If any key in the `keys` array has not been loaded."
                },
                {
                    "lua_type": "\"Key is already locked by another transaction\"",
                    "desc": "If any key is already involved in an ongoing `tx`."
                },
                {
                    "lua_type": "\"Key is closed\"",
                    "desc": "If any involved session has been closed (e.g., due to lock loss)."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                },
                {
                    "lua_type": "\"Schema validation failed\"",
                    "desc": "If the data for any key after transformation fails the schema check."
                },
                {
                    "lua_type": "\"Keys changed in transaction\"",
                    "desc": "If the `transformFunction` attempts to add or remove keys from the state table it receives."
                }
            ],
            "source": {
                "line": 1132,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "txImmutableAsync",
            "desc": "Synchronous wrapper for [Store:txImmutable]. Waits for the Promise to settle.\nThrows an error if the transaction fails or is aborted.",
            "params": [
                {
                    "name": "keys",
                    "desc": "An array of keys involved in the transaction.",
                    "lua_type": "{string}"
                },
                {
                    "name": "transformFunction",
                    "desc": "The transformation function.",
                    "lua_type": "(state: { [string]: T }) -> { [string]: T } | false"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean\n"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the transaction."
                }
            ],
            "yields": true,
            "source": {
                "line": 1152,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "save",
            "desc": "Forces an immediate save of the given key's current in-memory data state\nto the DataStore.\n\n:::note\nData is automatically saved periodically by the Session's autosave mechanism.\nManual saves are typically only needed in specific scenarios like processing\ndeveloper product purchases (`MarketplaceService.ProcessReceipt`) where immediate\npersistence is crucial before granting benefits.\n:::\n\nPropagates errors from `Session:save` (e.g., DataStore write errors).",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to save.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves when the save operation completes successfully, rejects on error.",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Key not loaded\"",
                    "desc": "If `load()` has not been successfully called for this key."
                },
                {
                    "lua_type": "\"Store is closed\"",
                    "desc": "If the store instance has been closed."
                }
            ],
            "source": {
                "line": 1178,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "saveAsync",
            "desc": "Synchronous wrapper for [Store:save]. Waits for the Promise to settle.\nThrows an error if the save fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to save.",
                    "lua_type": "string"
                }
            ],
            "returns": [],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the save operation."
                }
            ],
            "yields": true,
            "source": {
                "line": 1195,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "close",
            "desc": "Closes the store, gracefully unloading all active sessions.\n\nAttempts to save any pending changes for all loaded keys before releasing locks\nand removing sessions from memory. The store instance becomes unusable as soon as this is called.",
            "params": [],
            "returns": [
                {
                    "desc": "Resolves when all sessions have attempted to unload, or rejects if any session encountered an error during its unload process (errors are aggregated).",
                    "lua_type": "Promise"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 1208,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "closeAsync",
            "desc": "Synchronous wrapper for [Store:close]. Waits for the Promise to settle.\nThrows an error if closing fails (i.e., if any session failed to unload).",
            "params": [],
            "returns": [],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws an error (potentially a table of errors) if closing fails."
                }
            ],
            "yields": true,
            "source": {
                "line": 1261,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "peek",
            "desc": "Reads the current data for the given key directly from the DataStore,\nbypassing the session cache and locking mechanism.\n\nThis provides a snapshot of the last saved state but does not load the key\ninto an active session. Useful for inspecting data without acquiring a lock.\nHandles potential sharding and transaction status automatically.\n\nPropagates DataStore errors from underlying reads.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to peek at.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with the data object, or `nil` if the key doesn't exist. Rejects on DataStore errors.",
                    "lua_type": "Promise<T?>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 1279,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "peekAsync",
            "desc": "Synchronous wrapper for [Store:peek]. Waits for the Promise to settle.\nReturns the data for the key if it exists. Throws on any errors from underlying DataStore operations.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose data to peek at.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "The data object, or `nil` if the key doesn't exist.",
                    "lua_type": "T?"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "May throw errors from underlying DataStore operations."
                }
            ],
            "yields": true,
            "source": {
                "line": 1327,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "probeLockActive",
            "desc": "Checks if a distributed lock is currently active for the given key in MemoryStore.\n\nPropagates errors from `Locks.probeLockActive`.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key to check the lock status for.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with `true` if a lock is active, `false` otherwise. Rejects on MemoryStore errors.",
                    "lua_type": "Promise<boolean>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 1340,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "probeLockActiveAsync",
            "desc": "Synchronous wrapper for [Store:probeLockActive]. Waits for the Promise to settle.\nThrows an error if the check fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key to check the lock status for.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "`true` if a lock is active, `false` otherwise.",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the probe operation."
                }
            ],
            "yields": true,
            "source": {
                "line": 1358,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "listVersions",
            "desc": "Lists historical versions of the data for a given key using DataStore versioning.\n\nPropagates errors from `DataStore:ListVersionsAsync`.",
            "params": [
                {
                    "name": "params",
                    "desc": "Parameters specifying the key, sorting, date range, and page size.",
                    "lua_type": "ListVersionParams"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with an iterator object (`DataStoreVersionPages`) that can be used to fetch pages of version history. Rejects on DataStore errors.",
                    "lua_type": "Promise<DataStoreVersionPages>"
                }
            ],
            "function_type": "method",
            "source": {
                "line": 1371,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "listVersionsAsync",
            "desc": "Synchronous wrapper for [Store:listVersions]. Waits for the Promise to settle.\nThrows an error if listing versions fails.",
            "params": [
                {
                    "name": "params",
                    "desc": "Parameters for listing versions.",
                    "lua_type": "ListVersionParams"
                }
            ],
            "returns": [
                {
                    "desc": "An iterator for version history.",
                    "lua_type": "DataStoreVersionPages"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the list operation."
                }
            ],
            "yields": true,
            "source": {
                "line": 1394,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "readVersion",
            "desc": "Reads the data content of a specific historical version for a given key.\n\nPropagates DataStore errors from underlying reads.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose version to read.",
                    "lua_type": "string"
                },
                {
                    "name": "version",
                    "desc": "The specific version ID (obtained from `listVersions`).",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "Resolves with the data object (`T`) and the `DataStoreKeyInfo` for that version. Rejects if the version doesn't exist or on DataStore/read errors.",
                    "lua_type": "Promise<(T, DataStoreKeyInfo)>"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "\"Record not found\"",
                    "desc": "If the specified version doesn't exist."
                }
            ],
            "source": {
                "line": 1409,
                "path": "src/Store.luau"
            }
        },
        {
            "name": "readVersionAsync",
            "desc": "Synchronous wrapper for [Store:readVersion]. Waits for the Promise to settle.\nThrows an error if reading the version fails.",
            "params": [
                {
                    "name": "key",
                    "desc": "The key whose version to read.",
                    "lua_type": "string"
                },
                {
                    "name": "version",
                    "desc": "The specific version ID.",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "The data object for the specified version.",
                    "lua_type": "T"
                },
                {
                    "desc": "The key info for the specified version.",
                    "lua_type": "DataStoreKeyInfo"
                }
            ],
            "function_type": "method",
            "errors": [
                {
                    "lua_type": "any",
                    "desc": "Throws any error encountered during the read operation."
                }
            ],
            "yields": true,
            "source": {
                "line": 1453,
                "path": "src/Store.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "StoreConfig",
            "desc": "Configuration options for creating a new Store instance using `createStore`.",
            "fields": [
                {
                    "name": "name",
                    "lua_type": "string",
                    "desc": "A unique name for this store (e.g., \"PlayerDataProd\"). Used for logging and deriving DataStore/MemoryStore keys."
                },
                {
                    "name": "template",
                    "lua_type": "T",
                    "desc": "A deep copyable Luau table/value representing the default state for a new key."
                },
                {
                    "name": "schema",
                    "lua_type": "(value: any) -> (boolean, string?)",
                    "desc": "A validation function (e.g., created with `t`) that checks if data conforms to the expected structure. Returns `true` if valid, or `false` and an error message if invalid."
                },
                {
                    "name": "migrationSteps",
                    "lua_type": "{Types.MigrationStep}?",
                    "desc": "An optional ordered list of migration steps to apply to data loaded from the DataStore if its schema is older than the current version. See `Migrations.luau`."
                },
                {
                    "name": "importLegacyData",
                    "lua_type": "((key: string) -> any?)?",
                    "desc": "An optional function to load data from a different, legacy storage system when a key is accessed for the first time and doesn't exist in this store."
                },
                {
                    "name": "dataStoreService",
                    "lua_type": "DataStoreService?",
                    "desc": "An optional override for the Roblox DataStoreService. Useful for testing or custom storage implementations. Defaults to `game:GetService(\"DataStoreService\")`."
                },
                {
                    "name": "memoryStoreService",
                    "lua_type": "MemoryStoreService?",
                    "desc": "An optional override for the Roblox MemoryStoreService. Useful for testing. Defaults to `game:GetService(\"MemoryStoreService\")`."
                },
                {
                    "name": "useMock",
                    "lua_type": "boolean?",
                    "desc": "If true (and running in Studio), uses mock in-memory implementations of DataStoreService and MemoryStoreService instead of the actual Roblox services. Useful for testing in a controlled environment. Defaults to `false`."
                },
                {
                    "name": "changedCallbacks",
                    "lua_type": "{ (key: string, newData: T, oldData: T?) -> () }?",
                    "desc": "An optional list of functions called *after* data for a key has been successfully updated. Provides the key, the new data state, and the previous data state (if available)."
                },
                {
                    "name": "logCallback",
                    "lua_type": "((logMessage: Log.LogMessage) -> ())?",
                    "desc": "A function to receive log messages generated by this Store instance and its components. If omitted, logs are discarded. See [Log]."
                },
                {
                    "name": "onLockLost",
                    "lua_type": "((key: string) -> ())?",
                    "desc": "An optional callback function triggered if the distributed lock for a key's session is lost unexpectedly (e.g., due to expiration or external interference). This usually indicates the session is no longer safe to use."
                }
            ],
            "source": {
                "line": 97,
                "path": "src/Store.luau"
            }
        }
    ],
    "name": "Store",
    "desc": "Coordinates Sessions and provides a safe, high-level API for interacting with\npersistent data stored in Roblox DataStores and MemoryStores.\n\n**Core Responsibilities:**\n- Manages the lifecycle of `Session` objects for individual data keys (e.g., player IDs).\n- Provides methods for loading, reading (`get`), updating (`update`), and saving data.\n- Implements atomic multi-key transactions (`tx`).\n- Handles data validation, migrations, and optional legacy data import.\n- Abstracts away underlying complexities like data sharding (`Files`), distributed\n  locking (`Locks`), and transaction coordination (`Transactions`).\n- Integrates with a configurable logging system (`Log`).\n\n**Usage Example:**\n```lua\nlocal store = Store.createStore({\n\tname = \"PlayerData\",\n\ttemplate = {\n\t\tcoins = 0,\n\t\titems = {},\n\t},\n\tschema = function(data)\n\t\treturn typeof(data.coins) == \"number\" and typeof(data.items) == \"table\",\n\t\t\"Invalid data format\"\n\tend,\n\t-- ... other config options\n})\n\n-- Load data for a player\nstore:load(\"player_1\"):andThen(function()\n\t-- Get current data\n\treturn store:get(\"player_1\")\nend):andThen(function(data)\n\tprint(data.coins) -- 0\n\n\t-- Update data\n\treturn store:update(\"player_1\", function(data)\n\t\tdata.coins += 100\n\t\treturn true -- Must return true to commit changes\n\tend)\nend)\n```",
    "private": true,
    "source": {
        "line": 47,
        "path": "src/Store.luau"
    }
}