function DataStore.Get(h,j,Z)if Z then return h.value end local n=0 if not h.haveValue then while not h.haveValue do local j,Z=(h:_GetRaw()):await()if not j then if h.backupRetries then n=n+1 if n>=h.backupRetries then h.backup=true h.haveValue=true h.value=h.backupValue break end end h:Debug("\071\101\116 \114\101\116\117\114\110\101\100 \101\114\114\111\114\058",Z)end end if h.value~=nil then for j,Z in ipairs(h.beforeInitialGet)do h.value=Z(h.value,h)end end end local W if h.value==nil and j~=nil then W=j else W=h.value end W=clone(W)h.value=W return W end function DataStore.GetAsync(j,...)return(Promise.promisify(function(...)return j:Get(...)end))(...)end function DataStore.GetTable(Z,j,...)local h,n=(Z:GetTableAsync(j,...)):await()if not h then error(n)end return n end function DataStore.GetTableAsync(Z,j,...)assert(j~=nil,"\089\111\117 \109\117\115\116 \112\114\111\118\105\100\101 \097 \100\101\102\097\117\108\116 \118\097\108\117\101\046")return(Z:GetAsync(j,...)):andThen(function(h)local n=false assert(typeof(h)=="\116\097\098\108\101","\058\071\101\116\084\097\098\108\101\047\058\071\101\116\084\097\098\108\101\065\115\121\110\099 \119\097\115 \117\115\101\100 \119\104\101\110 \116\104\101 \118\097\108\117\101 \105\110 \116\104\101 \100\097\116\097 \115\116\111\114\101 \105\115\110\'\116 \097 \116\097\098\108\101\046")for j,Z in pairs(j)do if h[j]==nil then h[j]=Z n=true end end if n then Z:Set(h)end return h end)end function DataStore.Set(h,j,Z)h.value=clone(j)h:_Update(Z)end function DataStore.Update(Z,j)Z.value=j(Z.value)Z:_Update()end function DataStore.Increment(h,j,Z)h:Set(h:Get(Z)+j)end function DataStore.IncrementAsync(h,j,Z)return(h:GetAsync(Z)):andThen(function(Z)return(Promise.promisify(function()h:Set(Z+j)end))()end)end function DataStore.OnUpdate(Z,j)table.insert(Z.callbacks,j)end function DataStore.BeforeInitialGet(Z,j)table.insert(Z.beforeInitialGet,j)end function DataStore.BeforeSave(Z,j)Z.beforeSave=j end function DataStore.AfterSave(Z,j)table.insert(Z.afterSave,j)end
--Public functions

function DataStore:Get(defaultValue, dontAttemptGet)
	if dontAttemptGet then
		return self.value
	end

	local backupCount = 0

	if not self.haveValue then
		while not self.haveValue do
			local success, error = self:_GetRaw():await()

			if not success then
				if self.backupRetries then
					backupCount = backupCount + 1

					if backupCount >= self.backupRetries then
						self.backup = true
						self.haveValue = true
						self.value = self.backupValue
						break
					end
				end

				self:Debug("Get returned error:", error)
			end
		end

		if self.value ~= nil then
			for _, modifier in ipairs(self.beforeInitialGet) do
				self.value = modifier(self.value, self)
			end
		end
	end

	local value

	if self.value == nil and defaultValue ~= nil then --not using "not" because false is a possible value
		value = defaultValue
	else
		value = self.value
	end

	value = clone(value)

	self.value = value

	return value
end

function DataStore:GetAsync(...)
	return Promise.promisify(function(...)
		return self:Get(...)
	end)(...)
end

function DataStore:GetTable(default, ...)
	local success, result = self:GetTableAsync(default, ...):await()
	if not success then
		error(result)
	end
	return result
end

function DataStore:GetTableAsync(default, ...)
	assert(default ~= nil, "You must provide a default value.")

	return self:GetAsync(default, ...):andThen(function(result)
		local changed = false
		assert(
			typeof(result) == "table",
			":GetTable/:GetTableAsync was used when the value in the data store isn't a table."
		)

		for defaultKey, defaultValue in pairs(default) do
			if result[defaultKey] == nil then
				result[defaultKey] = defaultValue
				changed = true
			end
		end

		if changed then
			self:Set(result)
		end

		return result
	end)
end

function DataStore:Set(value, _dontCallOnUpdate)
	self.value = clone(value)
	self:_Update(_dontCallOnUpdate)
end

function DataStore:Update(updateFunc)
	self.value = updateFunc(self.value)
	self:_Update()
end

function DataStore:Increment(value, defaultValue)
	self:Set(self:Get(defaultValue) + value)
end

function DataStore:IncrementAsync(add, defaultValue)
	return self:GetAsync(defaultValue):andThen(function(value)
		return Promise.promisify(function()
			self:Set(value + add)
		end)()
	end)
end

function DataStore:OnUpdate(callback)
	table.insert(self.callbacks, callback)
end

function DataStore:BeforeInitialGet(modifier)
	table.insert(self.beforeInitialGet, modifier)
end

function DataStore:BeforeSave(modifier)
	self.beforeSave = modifier
end

function DataStore:AfterSave(callback)
	table.insert(self.afterSave, callback)
end
