Forest Logo
search
package_2

drop

By @wutwere

Roblox

Mirrored

Drop

A datastore library.

Quick start

Drop has two main types: schemas and stores. Let's make both.

local drop = require("@drop")

local schema = drop.schema({
	coins = 100,
	items = {} :: { [string]: true },
})

local store = drop.store({
	name = "players",
	schema = schema,
})

For Studio development and integration tests, you can swap in a mock datastore service instead of Roblox's live datastores.

local mock = drop.mockdatastoreservice.new()

local store = drop.store({
	name = "players",
	schema = schema,
	datastoreservice = mock,
})

If you just want an isolated in-memory backend for a store, you can also pass usemock = true.

Let's view jack's data. To view the data of any key, call drop.viewasync. This function yields and loads data directly from storage. If the data cannot be loaded for any reason, then this function will error.

local data = drop.viewasync(store, "jack")

Jack purchased a developer product for 1000 coins, so let's give that to him. To update data use drop.updateasync. This function yields while it attempts to apply the update directly to storage. If the update fails for any reason, then the function will error. This should be the function you use when you need to know if an update was successful.

local success = pcall(drop.updateasync, store, "jack", function(data)
	return {
		coins = data.coins + 1000,
		items = data.items,
	}
end)

if success then
	return Enum.ProductPurchaseDecision.PurchaseGranted
else
	return Enum.ProductPurchaseDecision.NotProcessedYet
end

[!TIP] drop.updateasync implements its own internal retry logic. Don't repeatedly call drop.updateasync if it errors.

We don't want to worry about catching errors, and we want updates to apply immediately. That means we're going to need to open a session. To start a session, call drop.startsession. This function does not yield, but the session will not be immediately available. To wait for the key's session to be available, call drop.waitforsession.

drop.startsession(store, "jack")
drop.waitforsession(store, "jack")

When your server is shutting down, call drop.closeasync(store) yourself during your shutdown sequence to flush and stop all active sessions for that store.

game:BindToClose(function()
	drop.closeasync(store)
end)

The session has been started, we can now view and update the data in the same way without yielding. Let's make a purchase item function. All updates passed to drop should be atomic and pure. Update functions may be called any number of times. To cancel an update, return nil.

local function purchase(key: string, item: string, cost: number)
	drop.update(store, key, function(data)
		if data.coins >= cost and not data.items[item] then
			local items = table.clone(data.items)
			items[item] = true
			
			return {
				coins = data.coins - cost,
				items = items,
			}
		else
			return nil
		end
	end)
end

Updates from drop.update apply immediately, but we want to see this data changing. For that, we can make an observer. Observers take functions that get called every time data updates. The data may be the same, or it may be different.

drop.observe(store, function(key, data)
	print(`{key} has {data.coins} coins!`)
end)

Marcus and Jack want to trade items. When an update needs to apply to multiple keys, transactions should be used.

drop.txasync(function(tx)
	tx(store, "jack", function(data)
		if not data.items["sword"] then
			return nil
		end

		local items = table.clone(data.items)
		items["sword"] = nil
		items["horn"] = true

		return {
			coins = data.coins,
			items = items,
		}
	end)

	tx(store, "marcus", function(data)
		if not data.items["horn"] then
			return nil
		end

		local items = table.clone(data.items)
		items["sword"] = true
		items["horn"] = nil

		return {
			coins = data.coins,
			items = items,
		}
	end)
end)

Help

You can ask questions and talk to maintainers either here on github, or in the Roblox OSS discord.

Package Details

Install command (Click to copy)


Version

1.1.4

License

MIT

check_circle

Safe for commercial use

infoThe package archive does not include its license text; the license is declared in its manifest metadata.

Automated license review — not legal advice.