function DataStore.Get(V,c,f)if f then return V.value end local Y=0 if not V.haveValue then while not V.haveValue do local c,f=(V:_GetRaw()):await()if not c then if V.backupRetries then Y=Y+1 if Y>=V.backupRetries then V.backup=true V.haveValue=true V.value=V.backupValue break end end V:Debug("\071\101\116 \114\101\116\117\114\110\101\100 \101\114\114\111\114\058",f)end end if V.value~=nil then for c,f in ipairs(V.beforeInitialGet)do V.value=f(V.value,V)end end end local W if V.value==nil and c~=nil then W=c else W=V.value end W=clone(W)V.value=W return W end function DataStore.GetAsync(c,...)return(Promise.promisify(function(...)return c:Get(...)end))(...)end function DataStore.GetTable(f,c,...)local V,Y=(f:GetTableAsync(c,...)):await()if not V then error(Y)end return Y end function DataStore.GetTableAsync(f,c,...)assert(c~=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(f:GetAsync(c,...)):andThen(function(V)local Y=false assert(typeof(V)=="\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 c,f in pairs(c)do if V[c]==nil then V[c]=f Y=true end end if Y then f:Set(V)end return V end)end function DataStore.Set(V,c,f)V.value=clone(c)V:_Update(f)end function DataStore.Update(f,c)f.value=c(f.value)f:_Update()end function DataStore.Increment(V,c,f)V:Set(V:Get(f)+c)end function DataStore.IncrementAsync(V,c,f)return(V:GetAsync(f)):andThen(function(f)return(Promise.promisify(function()V:Set(f+c)end))()end)end function DataStore.OnUpdate(f,c)table.insert(f.callbacks,c)end function DataStore.BeforeInitialGet(f,c)table.insert(f.beforeInitialGet,c)end function DataStore.BeforeSave(f,c)f.beforeSave=c end function DataStore.AfterSave(f,c)table.insert(f.afterSave,c)end


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
