Event/Function Framework Code Reveiw Request

I’m looking for a review on my API module, which is part of a framework I’m developing. For purposes of this module, an API is just defined as a folder full of remote/bindable events/functions (hereinafter “mediators” because I don’t want to type that out every time) all used by one system.

This module intends to simplify handling mediators. It works by using metatables to abstract methods and, in result, cut out a lot of the typing for the scripter and get the script closer to plain english.

Knowing my luck, it’s not unlikely that I’ve failed to take into account some serious perfomance issue or something, so I am inviting other scripters to have a look at the system’s guts (under “Framework Code”) and tell me what I’ve done wrong.

Vanilla LuaU vs. My Framework Comparison

These two bits of code perform the exact same function:

-- Vanilla LuaU
local API = SomePath

API.OnSomeEvent.OnServerEvent:Connect(function(Player)
    API.OnOtherEvent:FireClient(Player)
end)

API.SomeFunction.OnServerInvoke = function(Player)
    return SomeBindableFunction:Invoke(Blah)
end

-- Avid API Module
local API = APIsModule.SomeAPIName

API.OnSomeEvent(function(Player) -- Using _call metamethod
    API.OnOtherEvent.Fire(Player) -- No need to specify client or server, handles automatically.
end)

API.SomeFunction.Hook(function(Player)
    return API.SomeBindableFunction(Blah)
end
Framework Code

--[[
	
	Avid API Module
	
	kiloe2 11/19/2022
	
	MEDIATOR (n.) - BindableEvent, BindableFunction, RemoteEvent, RemoteFunction.
		Term exists solely for the purposes of variable naming.
	
]]--

-- Variables
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

local ReplicatedAPIs = ReplicatedStorage.APIs
local ServerAPIs

local IsServer = RunService:IsServer()

local MediatorMetatables = {}

if IsServer then ServerAPIs = ServerStorage.APIs end

-- Mediator metatables
MediatorMetatables.BindableEvent = {
	__call = function(Mediator, Callback) -- Mediator will be a table with the mediator inside of it.
		return Mediator[1].Event:Connect(Callback)
	end,
	__index = function(Mediator, Index)
		assert(Index == "Fire", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
		
		return function(...)
			Mediator[1]:Fire(...)
		end
	end
}

MediatorMetatables.BindableFunction = {
	__call = function(Mediator, ...)
		return Mediator[1]:Invoke(...)
	end,
	__index = function(Mediator, Index)
		assert(Index == "Hook", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
		
		return function(Callback)
			Mediator[1].OnInvoke = Callback
		end
	end
}

if IsServer then
	MediatorMetatables.RemoteEvent = {
		__call = function(Mediator, Callback)
			return Mediator[1].OnServerEvent:Connect(Callback)
		end,
		__index = function(Mediator, Index)
			assert(Index == "Fire", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
			
			return function(...)
				Mediator[1]:FireClient(...)
			end
		end,
	}
	
	MediatorMetatables.RemoteFunction = {
		__call = function(Mediator, ...)
			error("Woah! You tried to invoke the client with "..Mediator[1].Name.."\". Restructure your code, please!")
		end,
		__index = function(Mediator, Index)
			assert(Index == "Hook", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
			
			return function(Callback)
				Mediator[1].OnServerInvoke = Callback
			end
		end
	}
else
	MediatorMetatables.RemoteEvent = {
		__call = function(Mediator, Callback)
			return Mediator[1].OnClientEvent:Connect(Callback)
		end,
		__index = function(Mediator, Index)
			assert(Index == "Fire", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
			
			return function(...)
				Mediator[1]:FireServer(...)
			end
		end,
	}

	MediatorMetatables.RemoteFunction = {
		__call = function(Mediator, ...)
			return Mediator[1]:InvokeServer(...)
		end,
		__index = function(Mediator, Index)
			assert(Index == "Hook", "\""..Index.."\" is not a method of mediator \""..Mediator[1].Name.."\"!")
			
			error("Woah! You tried to hook on the client with "..Mediator[1].Name.."\". Restructure your code, please!")
		end
	}
end

-- Functions
local function GetAPI(APIFolder, Name) -- APIFolder will be a table because GetAPI is a metamethod.
	local API = APIFolder[1]:FindFirstChild(Name)
	
	assert(API, "API \""..Name.."\" not found!")
	
	return setmetatable({}, {__index = function(Table, Index)
		local Mediator = API:FindFirstChild(Index)
		
		assert(Mediator, "Mediator \""..Index.."\" does not exist under API \""..Name.."\"!")
		
		local Metatable = MediatorMetatables[Mediator.ClassName]
		
		assert(Metatable, "Mediator \""..Index.."\" is a "..Mediator.ClassName.." and not a valid mediator!")
		
		return setmetatable({Mediator}, Metatable)
	end})
end

-- Module
return {
	Replicated = setmetatable({ReplicatedAPIs}, {__index = GetAPI}),
	Server = setmetatable({ServerAPIs}, {__index = GetAPI})
}