Hey! Well trying to find an alternative to ProfileService
, I stumbled across Lapis, and decided to use it because of its promise implementation, I’m trying to create a “custom service” for lapis, using Knit, but I can’t figure it out.
This (probably) isn’t the best way to organize things, nor use Knit (please point out any bad-practices I did, and how I could fix them)
Anyway, here’s my current script:
-- Services
local Players = game:GetService("Players")
local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit)
local Lapis = require(Knit.Util.Lapis)
local Signal = require(Knit.Util.Signal)
local t = require(Knit.Util.t)
-- Variables
local dataTemplate = {
coins = 100,
}
-- Data Service
local DataService = Knit.CreateService {
Name = "DataService",
Client = {}
}
-- Public Functions
function DataService:Set(player: Player, key: string, value)
local document = self.Documents[player]
if document then
local data = document:read()
data[key] = value
document:write(data)
else
warn("No document found for player " .. player.UserId)
end
end
function DataService:Update(player: Player, key: string, callback)
assert(type(callback) == "function", "Callback must be a function; got " .. type(callback))
local document = self.Documents[player]
if document then
local data = document:read()
data[key] = callback(data[key])
document:write(data)
else
warn("No document found for player " .. player.UserId)
end
end
function DataService:Get(player, key)
local document = self.Documents[player]
if document then
local data = document:read()
print(document)
return data[key]
else
warn("No document found for player " .. player.UserId)
return nil
end
end
-- Client Exposed Functions
function DataService.Client:Get(player, key)
return self.Server:Get(player, key)
end
-- Initialize
function DataService:KnitStart()
self.DataChanged = Signal.new()
self.Collection = Lapis.createCollection("PlayerData", {
defaultData = dataTemplate,
validate = t.strictInterface({coins = t.integer}),
})
self.Documents = {}
function self:PlayerAdded(player)
self.Collection
:load("Player" .. player.UserId, { player.UserId })
:andThen(function(document)
if player.Parent == nil then
document:close():catch(warn)
return
end
self.Documents[player] = document
end)
:catch(function(message)
warn("Player " .. player.Name .. "'s data failed to load: " .. message)
player:Kick("Data failed to load.")
end)
end
function self:PlayerRemoved(player)
local document = self.Documents[player]
if document then
document:close():catch(warn)
end
self.Documents[player] = nil
end
for _, quickJoiner in Players:GetPlayers() do
self:PlayerAdded(quickJoiner)
end
Players.PlayerAdded:Connect(function(player)
self:PlayerAdded(player)
end)
Players.PlayerRemoving:Connect(function(player)
self:PlayerRemoved(player)
end)
end
return DataService
Right now, when a client tried to use the :Get() method, like this:
Knit.GetService("DataService"):Get(game.Players.LocalPlayer, "coins")
It prints
Promise(Started)
and I can’t figure out how to get the actual value from there.
Is there a better way to handle the documents or properties?
Any help is appreciated!