Is there a working module pattern?

Basically, the built in exports return ‘export not found in resource xyz’ so I try an alternative with events and find out it doesn’t work on the client or preserve the import/export order.

local MODULES = {}
local REQUIRE = function (m) return m  end

local function Import (name, ...)
    local module
    
    -- Citizen.Wait(1)
    
    module = MODULES[name]
    
    return (module.require or REQUIRE)(module.exports, ...)   
end

local function Export (name, exports, consume)
    local module = { 
        exports = exports, 
        require = consume
    }

    MODULES[name] = module

    return exports  
end

AddEventHandler('MODULE', function (cb) cb(Import, Export) end)


Also TriggerEvent('MODULE', function (Import, Export) end) noops unless u wrap it inside CreateThread.

EDIT: And the types get messed up

Citizen.CreateThread(function()
    function val () print('ACTUAL TYPE:', type(val)) end
    
    TriggerEvent('MODULE', function (get, set)
        local foo = set('foo', val)
        local bar = get('foo')
        local typ = type(bar)
        
        val()
        assert(typ == 'function', 'TYPE WAS: ' .. typ)
    end)
end)