This commit is contained in:
EternityDev 2024-05-29 16:58:20 +07:00
parent 77de85b6b8
commit 064075fbd9
11 changed files with 183 additions and 22 deletions

BIN
Warp.rbxm

Binary file not shown.

View file

@ -33,6 +33,7 @@ function side() {
text: 'Feature', text: 'Feature',
items: [ items: [
{ text: 'Rate Limit', link: '/api/1.0/ratelimit' }, { text: 'Rate Limit', link: '/api/1.0/ratelimit' },
{ text: 'Middleware', link: '/api/1.0/middleware' },
] ]
}, },
{ {

View file

@ -0,0 +1,64 @@
# Middleware <Badge type="tip" text="feature" />
::: code-group
```lua [Server]
local Event1 = Warp.Server("Remote1")
local storeC = Event1:Connect(function(player: Player, arg1: string, arg2: number, arg3: boolean)
print(player, arg1, arg2, arg3)
end):middleware(function(player: Player, arg1: string, arg2: number, arg3: boolean)
assert(type(player) == "userdata" and player:IsA("Player"), "player must be a Player.")
assert(typeof(arg1) == "string", "arg1 must be a string.")
assert(typeof(arg2) == "number", "arg2 must be a number.")
assert(typeof(arg3) == "boolean", "arg3 must be a boolean.")
end)
print(storeC:key())
task.delay(15, function()
Event1:Disconnect(storeC:key())
end)
for _=1,5 do
print("send incorrect values")
Event1:Fires(true, 1e9, "hello world!")
task.wait(0.5)
end
for _=1,5 do
print("send correct values")
Event1:Fires(true, "hello world!", 1e9)
task.wait(0.5)
end
```
```lua [Client]
local Event1 = Warp.Client("Remote1")
local storeC = Event1:Connect(function(arg1: boolean, arg2: string, arg3: number)
print(arg1, arg2, arg3)
end):middleware(function(arg1: boolean, arg2: string, arg3: number)
assert(typeof(arg1) == "boolean", "arg1 must be a boolean.")
assert(typeof(arg2) == "string", "arg2 must be a string.")
assert(typeof(arg3) == "number", "arg3 must be a number.")
end)
print(storeC:key())
task.delay(15, function()
Event1:Disconnect(storeC:key())
end)
for _=1,5 do
print("send incorrect values")
Event1:Fires("hello world!", false, 1e9)
task.wait(0.5)
end
for _=1,5 do
print("send correct values")
Event1:Fires("hello world!", 1e9, false)
task.wait(0.5)
end
```
:::

View file

@ -68,3 +68,4 @@ Pong:Destroy()
-- Yay Done! -- Yay Done!
``` ```
:::

View file

@ -8,7 +8,7 @@
::: code-group ::: code-group
```toml [wally.toml] ```toml [wally.toml]
[dependencies] [dependencies]
warp = "imezx/warp@1.0.11" warp = "imezx/warp@1.0.12"
``` ```
3. Run `wally install` in command. 3. Run `wally install` in command.

View file

@ -13,6 +13,7 @@ local Assert = require(Util.Assert)
local Key = require(Util.Key) local Key = require(Util.Key)
local Serdes = require(Util.Serdes) local Serdes = require(Util.Serdes)
local Buffer = require(Util.Buffer) local Buffer = require(Util.Buffer)
local Middleware = require(Util.Middleware)
function Client.new(Identifier: string, conf: Type.ClientConf?) function Client.new(Identifier: string, conf: Type.ClientConf?)
local self = setmetatable({}, Client) local self = setmetatable({}, Client)
@ -21,6 +22,7 @@ function Client.new(Identifier: string, conf: Type.ClientConf?)
self._buffer:wu8(Serdes(Identifier, conf and conf.yieldWait)) self._buffer:wu8(Serdes(Identifier, conf and conf.yieldWait))
self.id = Buffer.convert(self._buffer:build()) self.id = Buffer.convert(self._buffer:build())
self.fn = {} self.fn = {}
self.middleware = {}
self._conf = table.freeze(conf or {}) self._conf = table.freeze(conf or {})
self.IsConnected = false self.IsConnected = false
@ -43,23 +45,39 @@ function Client:Invoke(timeout: number, ...: any): any
return ClientProcess.insertRequest(self.id, timeout, ...) return ClientProcess.insertRequest(self.id, timeout, ...)
end end
function Client:Connect(callback: (args: any) -> ()): string function Client:Connect(callback: (args: any) -> ())
local key = tostring(Key()) local key = tostring(Key())
local _middleware = Middleware(key)
table.insert(self.fn, key) table.insert(self.fn, key)
self.middleware[key] = _middleware
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
ClientProcess.addCallback(self.id, key, callback) ClientProcess.addCallback(self.id, key, function(...)
return key if _middleware.bridge(...) then
return callback(...)
end
return nil
end)
return _middleware
end end
function Client:Once(callback: (args: any) -> ()): string function Client:Once(callback: (args: any) -> ())
local key = tostring(Key()) local key = tostring(Key())
local _middleware = Middleware(key)
table.insert(self.fn, key) table.insert(self.fn, key)
self.middleware[key] = _middleware
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
ClientProcess.addCallback(self.id, key, function(...) ClientProcess.addCallback(self.id, key, function(...)
self:Disconnect(key) self:Disconnect(key)
task.spawn(callback, ...) if _middleware.bridge(...) then
return callback(...)
end
return nil
end) end)
return key return _middleware
end end
function Client:Wait() function Client:Wait()
@ -76,12 +94,15 @@ function Client:DisconnectAll()
end end
end end
function Client:Disconnect(key: string): boolean function Client:Disconnect(key: string)
Assert(typeof(key) == "string", "Key must be a string type.") Assert(typeof(key) == "string", "Key must be a string type.")
ClientProcess.removeCallback(self.id, key) ClientProcess.removeCallback(self.id, key)
table.remove(self.fn, table.find(self.fn, key)) table.remove(self.fn, table.find(self.fn, key))
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
return table.find(self.fn, key) == nil if self.middleware[key] then
self.middleware[key]:destroy()
self.middleware[key] = nil
end
end end
function Client:Destroy() function Client:Destroy()

View file

@ -13,6 +13,7 @@ local Assert = require(Util.Assert)
local Key = require(Util.Key) local Key = require(Util.Key)
local Serdes = require(Util.Serdes) local Serdes = require(Util.Serdes)
local Buffer = require(Util.Buffer) local Buffer = require(Util.Buffer)
local Middleware = require(Util.Middleware)
function Server.new(Identifier: string, conf: Type.ServerConf?) function Server.new(Identifier: string, conf: Type.ServerConf?)
local self = setmetatable({}, Server) local self = setmetatable({}, Server)
@ -21,6 +22,7 @@ function Server.new(Identifier: string, conf: Type.ServerConf?)
self._buffer:wu8(Serdes(Identifier)) self._buffer:wu8(Serdes(Identifier))
self.id = Buffer.convert(self._buffer:build()) self.id = Buffer.convert(self._buffer:build())
self.fn = {} self.fn = {}
self.middleware = {}
self._conf = table.freeze(conf or {}) self._conf = table.freeze(conf or {})
self.IsConnected = false self.IsConnected = false
@ -63,23 +65,39 @@ function Server:Invoke(timeout: number, player: Player, ...: any): any
return ServerProcess.insertRequest(self.id, timeout, player, ...) return ServerProcess.insertRequest(self.id, timeout, player, ...)
end end
function Server:Connect(callback: (plyer: Player, args: any) -> ()): string function Server:Connect(callback: (plyer: Player, args: any) -> ())
local key = tostring(Key()) local key = tostring(Key())
local _middleware = Middleware(key)
table.insert(self.fn, key) table.insert(self.fn, key)
ServerProcess.addCallback(self.id, key, callback) self.middleware[key] = _middleware
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
return key ServerProcess.addCallback(self.id, key, function(...)
if _middleware.bridge(...) then
return callback(...)
end
return nil
end)
return _middleware
end end
function Server:Once(callback: (plyer: Player, args: any) -> ()): string function Server:Once(callback: (plyer: Player, args: any) -> ())
local key = tostring(Key()) local key = tostring(Key())
local _middleware = Middleware(key)
table.insert(self.fn, key) table.insert(self.fn, key)
self.middleware[key] = _middleware
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
ServerProcess.addCallback(self.id, key, function(...) ServerProcess.addCallback(self.id, key, function(...)
self:Disconnect(key) self:Disconnect(key)
task.spawn(callback, ...) if _middleware.bridge(...) then
return callback(...)
end
return nil
end) end)
return key return _middleware
end end
function Server:Wait() function Server:Wait()
@ -101,6 +119,10 @@ function Server:Disconnect(key: string): boolean
ServerProcess.removeCallback(self.id, key) ServerProcess.removeCallback(self.id, key)
table.remove(self.fn, table.find(self.fn, key)) table.remove(self.fn, table.find(self.fn, key))
self.IsConnected = #self.fn > 0 self.IsConnected = #self.fn > 0
if self.middleware[key] then
self.middleware[key]:destroy()
self.middleware[key] = nil
end
return table.find(self.fn, key) == nil return table.find(self.fn, key) == nil
end end

View file

@ -19,11 +19,17 @@ export type ClientConf = {
logging: logging?, logging: logging?,
} }
export type Middleware = {
middleware: (self: Middleware, middleware: (...any) -> (...any)) -> (),
key: (self: Middleware) -> string,
destroy: (self: Middleware) -> (),
}
export type Client = { export type Client = {
Fire: (self: Client, reliable: boolean, ...any) -> (), Fire: (self: Client, reliable: boolean, ...any) -> (),
Invoke: (self: Client, timeout: number, ...any) -> any, Invoke: (self: Client, timeout: number, ...any) -> any,
Connect: (self: Client, callback: (...any) -> ()) -> string, Connect: (self: Client, callback: (...any) -> ()) -> Middleware,
Once: (self: Client, callback: (player: Player, ...any) -> ()) -> string, Once: (self: Client, callback: (player: Player, ...any) -> ()) -> Middleware,
Disconnect: (self: Client, key: string) -> (), Disconnect: (self: Client, key: string) -> (),
DisconnectAll: (self: Client) -> (), DisconnectAll: (self: Client) -> (),
Wait: (self: Client) -> number, Wait: (self: Client) -> number,
@ -35,8 +41,8 @@ export type Server = {
Fire: (self: Server, reliable: boolean, player: Player, ...any) -> (), Fire: (self: Server, reliable: boolean, player: Player, ...any) -> (),
Fires: (self: Server, reliable: boolean, ...any) -> (), Fires: (self: Server, reliable: boolean, ...any) -> (),
Invoke: (self: Server, timeout: number, player: Player, ...any) -> any, Invoke: (self: Server, timeout: number, player: Player, ...any) -> any,
Connect: (self: Server, callback: (player: Player, ...any) -> ()) -> string, Connect: (self: Server, callback: (player: Player, ...any) -> ()) -> Middleware,
Once: (self: Server, callback: (player: Player, ...any) -> ()) -> string, Once: (self: Server, callback: (player: Player, ...any) -> ()) -> Middleware,
Disconnect: (self: Server, key: string) -> (), Disconnect: (self: Server, key: string) -> (),
DisconnectAll: (self: Server) -> (), DisconnectAll: (self: Server) -> (),
Wait: (self: Server) -> number, Wait: (self: Server) -> number,

View file

@ -0,0 +1,46 @@
--!strict
--!native
--!optimize 2
local Middleware = {}
Middleware.__index = Middleware
local function wrap(middleware: (...any) -> (...any)): (...any) -> boolean
return function(...): boolean
local obj: any = { ... }
local s, r = pcall(function()
return middleware(table.unpack(obj))
end)
if not s and r then
warn(r)
r = nil
table.clear(obj)
obj = nil
end
return s
end
end
function Middleware.new(key: string)
return setmetatable({
root = key,
bridge = function(...: any?): any?
return true
end,
}, Middleware)
end
function Middleware:middleware(middleware: (...any) -> (...any))
self.bridge = wrap(middleware)
return self
end
function Middleware:key(): string
return self.root
end
function Middleware:destroy()
table.clear(self)
setmetatable(self, nil)
end
return Middleware.new :: typeof(Middleware.new)

View file

@ -1,5 +1,5 @@
-- Warp Library (@Eternity_Devs) -- Warp Library (@Eternity_Devs)
-- version 1.0.11 -- version 1.0.12
--!strict --!strict
--!native --!native
--!optimize 2 --!optimize 2

View file

@ -1,6 +1,6 @@
[package] [package]
name = "imezx/warp" name = "imezx/warp"
version = "1.0.11" version = "1.0.12"
registry = "https://github.com/UpliftGames/wally-index" registry = "https://github.com/UpliftGames/wally-index"
realm = "shared" realm = "shared"
license = "MIT" license = "MIT"