local k=require(script.Parent.DataLayer)local d={}function d._unpack(k,d)k=k or{generation=#d;data=nil}local N=k.data local y=k.generation if y<#d then for k=y+1,#d,1 do N.data=d[k](N.data)end end return N end function d._pack(k,d)return{data=k,generation=#d}end function d.update(N,y,u,h)local n k.update(N,y,function(k)n=u(d._unpack(k,h))if n~=nil then return d._pack(n,h)else return nil end end)return n end function d.read(N,y,u)return d._unpack(k.read(N,y),u)end return d
local DataLayer = require(script.Parent.DataLayer)

local MigrationLayer = {}

function MigrationLayer._unpack(value, migrations)
	value = value or {
		generation = #migrations;
		data = nil;
	}

	local data = value.data
	local generation = value.generation

	if generation < #migrations then
		for i = generation + 1, #migrations do
			data.data = migrations[i](data.data)
		end
	end

	return data
end

function MigrationLayer._pack(value, migrations)
	return {
		data = value;
		generation = #migrations;
	}
end

function MigrationLayer.update(collection, key, callback, migrations)
	local migrated

	DataLayer.update(collection, key, function(value)
		migrated = callback(MigrationLayer._unpack(value, migrations))

		if migrated ~= nil then
			return MigrationLayer._pack(migrated, migrations)
		else
			return nil
		end
	end)

	return migrated
end

function MigrationLayer.read(collection, key, migrations)
	return MigrationLayer._unpack(DataLayer.read(collection, key), migrations)
end

return MigrationLayer