local Y=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local w=game:GetService("\072\116\116\112\083\101\114\118\105\099\101")local T=Y("\067\104\117\110\107\085\116\105\108\115")local t=Y("\068\097\116\097\083\116\111\114\101\080\114\111\109\105\115\101\115")local M=Y("\080\114\111\109\105\115\101")local p=Y("\080\114\111\109\105\115\101\085\116\105\108\115")local f=1000 local y={}y.ClassName="\067\104\117\110\107\068\097\116\097\083\116\111\114\101"y.__index=y function y.new(Y)local w=setmetatable({},y)w._datastore=Y or error("\078\111 \100\097\116\097\115\116\111\114\101")return w end function y.WriteEntry(M,Y)local y={}local u={}for Y in T.chunkStr(Y,f)do local T=w:GenerateGUID(false)table.insert(u,T)table.insert(y,t.SetAsync(M._datastore,T,Y))end return(p.all(y)):Then(function(...)return{EntryVersion=1,FileSize=#Y;Keys=u}end)end function y.LoadEntry(w,Y)assert(type(Y)=="\116\097\098\108\101")assert(type(Y.EntryVersion)=="\110\117\109\098\101\114")assert(type(Y.FileSize)=="\110\117\109\098\101\114")assert(type(Y.Keys)=="\116\097\098\108\101")return(w:_loadChunks(Y.Keys)):Then(function(T)return w:_decodeChunksToStr(T,Y.FileSize)end)end function y._loadChunks(w,Y)local T={}for Y,t in pairs(Y)do table.insert(T,w:_loadChunk(t))end return(p.all(T)):Then(function(...)return{...}end)end function y._decodeChunksToStr(T,Y,w)return M.new(function(T,t)for Y,w in pairs(Y)do if type(w)~="\115\116\114\105\110\103"then t("\070\097\105\108\101\100 \116\111 \108\111\097\100 \099\104\117\110\107 \035"..Y)return end end local M=table.concat(Y,"")if#M~=w then t(("\067\111\109\098\105\110\101\100 \099\104\117\110\107\115 \105\115 \037\100\044 \101\120\112\101\099\116\100 \037\100"):format(#M,w))return end T(M)return end)end function y._loadChunk(w,Y)if type(Y)~="\115\116\114\105\110\103"then return M.rejected("\075\101\121 \105\115 \110\111\116 \097 \115\116\114\105\110\103")end return t.GetAsync(w._datastore,Y)end return y
--- Stores very large strings into the datastore
-- @classmod ChunkDataStore

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local HttpService = game:GetService("HttpService")

local ChunkUtils = require("ChunkUtils")
local DataStorePromises = require("DataStorePromises")
local Promise = require("Promise")
local PromiseUtils = require("PromiseUtils")

local CHUNK_SIZE = 1000 -- 260000 - 100

local ChunkDataStore = {}
ChunkDataStore.ClassName = "ChunkDataStore"
ChunkDataStore.__index = ChunkDataStore

function ChunkDataStore.new(datastore)
	local self = setmetatable({}, ChunkDataStore)

	self._datastore = datastore or error("No datastore")

	return self
end

function ChunkDataStore:WriteEntry(largeString)
	local promises = {}
	local keys = {}

	for chunk in ChunkUtils.chunkStr(largeString, CHUNK_SIZE) do
		local key = HttpService:GenerateGUID(false)
		table.insert(keys, key)
		table.insert(promises, DataStorePromises.SetAsync(self._datastore, key, chunk))
	end

	return PromiseUtils.all(promises):Then(function(...)
		return {
			EntryVersion = 1;
			FileSize = #largeString;
			Keys = keys;
		}
	end)
end

function ChunkDataStore:LoadEntry(entry)
	assert(type(entry) == "table")
	assert(type(entry.EntryVersion) == "number")
	assert(type(entry.FileSize) == "number")
	assert(type(entry.Keys) == "table")

	return self:_loadChunks(entry.Keys):Then(function(chunks)
		return self:_decodeChunksToStr(chunks, entry.FileSize)
	end)
end

function ChunkDataStore:_loadChunks(keys)
	local promises = {}
	for _, item in pairs(keys) do
		table.insert(promises, self:_loadChunk(item))
	end

	return PromiseUtils.all(promises):Then(function(...)
		return {...}
	end)
end

function ChunkDataStore:_decodeChunksToStr(chunks, expectedSize)
	return Promise.new(function(resolve, reject)
		for index, item in pairs(chunks) do
			if type(item) ~= "string" then
				reject("Failed to load chunk #" .. index)
				return
			end
		end

		local total = table.concat(chunks, "")

		if #total ~= expectedSize then
			reject(("Combined chunks is %d, expectd %d"):format(#total, expectedSize))
			return
		end

		resolve(total)
		return
	end)
end

function ChunkDataStore:_loadChunk(key)
	if type(key) ~= "string" then
		return Promise.rejected("Key is not a string")
	end

	return DataStorePromises.GetAsync(self._datastore, key)
end

return ChunkDataStore