@rbxts/tether 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,42 +3,40 @@ A message-based networking solution for Roblox with automatic binary serializati
3
3
 
4
4
  ### In `shared/messaging.ts`
5
5
  ```ts
6
- import { DataType } from "@rbxts/flamework-binary-serializer";
6
+ import type { DataType } from "@rbxts/flamework-binary-serializer";
7
+ import { MessageEmitter } from "@rbxts/tether";
7
8
 
8
- export const messageEmitter = new MessageEmitter<Message, MessageData>;
9
- messageEmitter.initialize();
9
+ export const messaging = MessageEmitter.create<MessageData>();
10
10
 
11
11
  export const enum Message {
12
- TEST
12
+ Test
13
13
  }
14
14
 
15
15
  export interface MessageData {
16
- [Message.TEST]: {
16
+ [Message.Test]: {
17
17
  readonly foo: string;
18
18
  readonly n: DataType.u8;
19
19
  };
20
20
  }
21
-
22
- messageEmitter.addSerializer<Message.TEST>(Message.TEST);
23
21
  ```
24
22
 
25
23
  > [!CAUTION]
26
- > Every single message kind must implement an interface for it's data (in the example that would be the object with the `foo` and `bar` fields) as well as call `MessageEmitter.addSerializer()`. Messages will not work if you don't do this.
24
+ > Every single message kind must implement an interface for it's data (in the example that would be the object with the `foo` and `bar` fields). Message serialization (as well as your message itself) will not work if you don't do this.
27
25
 
28
26
  ### Server
29
27
  ```ts
30
- import { Message, messageEmitter } from "shared/messaging";
28
+ import { Message, messaging } from "shared/messaging";
31
29
 
32
- messageEmitter.onServerMessage(Message.TEST, (player, data) => {
30
+ messaging.onServerMessage(Message.TEST, (player, data) => {
33
31
  print(player, "sent data:", data);
34
32
  });
35
33
  ```
36
34
 
37
35
  ### Client
38
36
  ```ts
39
- import { Message, messageEmitter } from "shared/messaging";
37
+ import { Message, messaging } from "shared/messaging";
40
38
 
41
- messageEmitter.emitServer(Message.TEST, {
39
+ messaging.emitServer(Message.TEST, {
42
40
  foo: "bar",
43
41
  n: 69
44
42
  });
@@ -0,0 +1,4 @@
1
+ import { Middleware } from "./middleware";
2
+ export declare namespace BuiltinMiddlewares {
3
+ function rateLimit<Data>(interval: number): Middleware<Data>;
4
+ }
@@ -0,0 +1,20 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local DropRequest = TS.import(script, script.Parent, "middleware").DropRequest
4
+ local BuiltinMiddlewares = {}
5
+ do
6
+ local _container = BuiltinMiddlewares
7
+ local function rateLimit(interval)
8
+ local lastRequest = 0
9
+ return function()
10
+ if os.clock() - lastRequest < interval then
11
+ return DropRequest
12
+ end
13
+ lastRequest = os.clock()
14
+ end
15
+ end
16
+ _container.rateLimit = rateLimit
17
+ end
18
+ return {
19
+ BuiltinMiddlewares = BuiltinMiddlewares,
20
+ }
package/out/index.d.ts CHANGED
@@ -1,29 +1,3 @@
1
- import { Modding } from "@flamework/core";
2
- import { type SerializerMetadata } from "@rbxts/flamework-binary-serializer";
3
- type ClientMessageCallback<T = unknown> = (data: T) => void;
4
- type ServerMessageCallback<T = unknown> = (player: Player, data: T) => void;
5
- /** @metadata macro */
6
- export declare function createMessageEmitter<MessageData>(metaForEachMessage?: Modding.Many<{
7
- [Kind in keyof MessageData]: Modding.Many<SerializerMetadata<MessageData[Kind]>>;
8
- }>): MessageEmitter<MessageData> | undefined;
9
- declare class MessageEmitter<MessageData> {
10
- private readonly clientCallbacks;
11
- private readonly serverCallbacks;
12
- private readonly serializers;
13
- private readonly serverEvents;
14
- private readonly clientEvents;
15
- constructor();
16
- /** @metadata macro */
17
- addSerializer<Kind extends keyof MessageData>(message: Kind, meta?: Modding.Many<SerializerMetadata<MessageData[Kind]>>): void;
18
- initialize(): RBXScriptConnection;
19
- onServerMessage<Kind extends keyof MessageData>(message: Kind, callback: ServerMessageCallback<MessageData[Kind]>): () => void;
20
- onClientMessage<Kind extends keyof MessageData>(message: Kind, callback: ClientMessageCallback<MessageData[Kind]>): () => void;
21
- emitServer<Kind extends keyof MessageData>(message: Kind, data: MessageData[Kind], unreliable?: boolean): void;
22
- emitClient<Kind extends keyof MessageData>(player: Player, message: Kind, data: MessageData[Kind], unreliable?: boolean): void;
23
- emitAllClients<Kind extends keyof MessageData>(message: Kind, data: MessageData[Kind], unreliable?: boolean): void;
24
- private getPacket;
25
- /** @metadata macro */
26
- private createMessageSerializer;
27
- private getSerializer;
28
- }
29
- export {};
1
+ export { MessageEmitter } from "./message-emitter";
2
+ export { BuiltinMiddlewares } from "./builtin-middlewares";
3
+ export { MiddlewareProvider, DropRequest, type ClientMiddleware, type ServerMiddleware, type Middleware } from "./middleware";
package/out/init.luau CHANGED
@@ -1,166 +1,9 @@
1
1
  -- Compiled with roblox-ts v3.0.0
2
2
  local TS = _G[script]
3
- local Networking = TS.import(script, TS.getModule(script, "@flamework", "networking").out).Networking
4
- local createBinarySerializer = TS.import(script, TS.getModule(script, "@rbxts", "flamework-binary-serializer").out).createBinarySerializer
5
- local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
6
- local GlobalEvents = Networking.createEvent()
7
- --* @metadata macro
8
- local MessageEmitter
9
- local function createMessageEmitter(metaForEachMessage)
10
- if metaForEachMessage == nil then
11
- return nil
12
- end
13
- local emitter = MessageEmitter.new()
14
- for kind, meta in pairs(metaForEachMessage) do
15
- emitter:addSerializer(kind, meta)
16
- end
17
- end
18
- do
19
- MessageEmitter = setmetatable({}, {
20
- __tostring = function()
21
- return "MessageEmitter"
22
- end,
23
- })
24
- MessageEmitter.__index = MessageEmitter
25
- function MessageEmitter.new(...)
26
- local self = setmetatable({}, MessageEmitter)
27
- return self:constructor(...) or self
28
- end
29
- function MessageEmitter:constructor()
30
- self.clientCallbacks = {}
31
- self.serverCallbacks = {}
32
- self.serializers = {}
33
- if RunService:IsServer() then
34
- self.serverEvents = GlobalEvents:createServer({})
35
- else
36
- self.clientEvents = GlobalEvents:createClient({})
37
- end
38
- end
39
- function MessageEmitter:addSerializer(message, meta)
40
- self.serializers[message] = self:createMessageSerializer(meta)
41
- end
42
- function MessageEmitter:initialize()
43
- if RunService:IsClient() then
44
- return self.clientEvents.sendClientMessage:connect(function(sentMessage, _param)
45
- local buffer = _param.buffer
46
- local blobs = _param.blobs
47
- local _clientCallbacks = self.clientCallbacks
48
- local _sentMessage = sentMessage
49
- local _condition = _clientCallbacks[_sentMessage]
50
- if _condition == nil then
51
- _condition = {}
52
- end
53
- local messageCallbacks = _condition
54
- if #messageCallbacks == 0 then
55
- return nil
56
- end
57
- local serializer = self:getSerializer(sentMessage)
58
- local data = serializer.deserialize(buffer, blobs)
59
- for _, callback in messageCallbacks do
60
- callback(data)
61
- end
62
- end)
63
- else
64
- return self.serverEvents.sendServerMessage:connect(function(player, sentMessage, _param)
65
- local buffer = _param.buffer
66
- local blobs = _param.blobs
67
- local _serverCallbacks = self.serverCallbacks
68
- local _sentMessage = sentMessage
69
- local _condition = _serverCallbacks[_sentMessage]
70
- if _condition == nil then
71
- _condition = {}
72
- end
73
- local messageCallbacks = _condition
74
- if #messageCallbacks == 0 then
75
- return nil
76
- end
77
- local serializer = self:getSerializer(sentMessage)
78
- local data = serializer.deserialize(buffer, blobs)
79
- for _, callback in messageCallbacks do
80
- callback(player, data)
81
- end
82
- end)
83
- end
84
- end
85
- function MessageEmitter:onServerMessage(message, callback)
86
- local _serverCallbacks = self.serverCallbacks
87
- local _message = message
88
- if not (_serverCallbacks[_message] ~= nil) then
89
- local _serverCallbacks_1 = self.serverCallbacks
90
- local _message_1 = message
91
- _serverCallbacks_1[_message_1] = {}
92
- end
93
- local _serverCallbacks_1 = self.serverCallbacks
94
- local _message_1 = message
95
- local callbacks = _serverCallbacks_1[_message_1]
96
- local _callback = callback
97
- table.insert(callbacks, _callback)
98
- local _serverCallbacks_2 = self.serverCallbacks
99
- local _message_2 = message
100
- _serverCallbacks_2[_message_2] = callbacks
101
- return function()
102
- local _callback_1 = callback
103
- local _arg0 = (table.find(callbacks, _callback_1) or 0) - 1
104
- return table.remove(callbacks, _arg0 + 1)
105
- end
106
- end
107
- function MessageEmitter:onClientMessage(message, callback)
108
- local _clientCallbacks = self.clientCallbacks
109
- local _message = message
110
- if not (_clientCallbacks[_message] ~= nil) then
111
- local _clientCallbacks_1 = self.clientCallbacks
112
- local _message_1 = message
113
- _clientCallbacks_1[_message_1] = {}
114
- end
115
- local _clientCallbacks_1 = self.clientCallbacks
116
- local _message_1 = message
117
- local callbacks = _clientCallbacks_1[_message_1]
118
- local _callback = callback
119
- table.insert(callbacks, _callback)
120
- local _clientCallbacks_2 = self.clientCallbacks
121
- local _message_2 = message
122
- _clientCallbacks_2[_message_2] = callbacks
123
- return function()
124
- local _callback_1 = callback
125
- local _arg0 = (table.find(callbacks, _callback_1) or 0) - 1
126
- return table.remove(callbacks, _arg0 + 1)
127
- end
128
- end
129
- function MessageEmitter:emitServer(message, data, unreliable)
130
- if unreliable == nil then
131
- unreliable = false
132
- end
133
- local send = if unreliable then self.clientEvents.sendUnreliableServerMessage else self.clientEvents.sendServerMessage
134
- send(message, self:getPacket(message, data))
135
- end
136
- function MessageEmitter:emitClient(player, message, data, unreliable)
137
- if unreliable == nil then
138
- unreliable = false
139
- end
140
- local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
141
- send(player, message, self:getPacket(message, data))
142
- end
143
- function MessageEmitter:emitAllClients(message, data, unreliable)
144
- if unreliable == nil then
145
- unreliable = false
146
- end
147
- local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
148
- send:broadcast(message, self:getPacket(message, data))
149
- end
150
- function MessageEmitter:getPacket(message, data, unreliable)
151
- if unreliable == nil then
152
- unreliable = false
153
- end
154
- local serializer = self:getSerializer(message)
155
- return serializer.serialize(data)
156
- end
157
- function MessageEmitter:createMessageSerializer(meta)
158
- return createBinarySerializer(meta)
159
- end
160
- function MessageEmitter:getSerializer(message)
161
- return self.serializers[message]
162
- end
163
- end
164
- return {
165
- createMessageEmitter = createMessageEmitter,
166
- }
3
+ local exports = {}
4
+ exports.MessageEmitter = TS.import(script, script, "message-emitter").MessageEmitter
5
+ exports.BuiltinMiddlewares = TS.import(script, script, "builtin-middlewares").BuiltinMiddlewares
6
+ local _middleware = TS.import(script, script, "middleware")
7
+ exports.MiddlewareProvider = _middleware.MiddlewareProvider
8
+ exports.DropRequest = _middleware.DropRequest
9
+ return exports
@@ -0,0 +1,59 @@
1
+ import { Modding } from "@flamework/core";
2
+ import { type SerializerMetadata } from "@rbxts/flamework-binary-serializer";
3
+ import Destroyable from "@rbxts/destroyable";
4
+ import { MiddlewareProvider } from "./middleware";
5
+ import type { ClientMessageCallback, ServerMessageCallback } from "./structs";
6
+ export declare class MessageEmitter<MessageData> extends Destroyable {
7
+ private readonly middleware?;
8
+ private readonly clientCallbacks;
9
+ private readonly serverCallbacks;
10
+ private serializers;
11
+ private serverEvents;
12
+ private clientEvents;
13
+ /** @metadata macro */
14
+ static create<MessageData>(middleware?: MiddlewareProvider<MessageData>, metaForEachMessage?: Modding.Many<{
15
+ [Kind in keyof MessageData]: MessageData[Kind] extends undefined ? undefined : Modding.Many<SerializerMetadata<MessageData[Kind]>>;
16
+ }>): MessageEmitter<MessageData>;
17
+ private constructor();
18
+ /**.
19
+ * @returns A destructor function that disconnects the callback from the message
20
+ */
21
+ onServerMessage<Kind extends keyof MessageData>(message: Kind, callback: ServerMessageCallback<MessageData[Kind]>): () => void;
22
+ /**.
23
+ * @returns A destructor function that disconnects the callback from the message
24
+ */
25
+ onClientMessage<Kind extends keyof MessageData>(message: Kind, callback: ClientMessageCallback<MessageData[Kind]>): () => void;
26
+ private on;
27
+ /**
28
+ * Emits a message to all connected clients.
29
+ *
30
+ * @param message - The message kind to be sent.
31
+ * @param data - The data associated with the message.
32
+ * @param unreliable - Optional flag indicating if the message should be sent unreliably.
33
+ */
34
+ emitServer<Kind extends keyof MessageData>(message: Kind, data?: MessageData[Kind], unreliable?: boolean): void;
35
+ /**
36
+ * Emits a message to a specific client.
37
+ *
38
+ * @param player - The player to whom the message is sent.
39
+ * @param message - The message kind to be sent.
40
+ * @param data - The data associated with the message.
41
+ * @param unreliable - Optional flag indicating if the message should be sent unreliably.
42
+ */
43
+ emitClient<Kind extends keyof MessageData>(player: Player, message: Kind, data?: MessageData[Kind], unreliable?: boolean): void;
44
+ /**
45
+ * Emits a message to all connected clients.
46
+ *
47
+ * @param message - The message kind to be sent.
48
+ * @param data - The data associated with the message.
49
+ * @param unreliable - Optional flag indicating if the message should be sent unreliably.
50
+ */
51
+ emitAllClients<Kind extends keyof MessageData>(message: Kind, data?: MessageData[Kind], unreliable?: boolean): void;
52
+ private initialize;
53
+ private getPacket;
54
+ /** @metadata macro */
55
+ private addSerializer;
56
+ /** @metadata macro */
57
+ private createMessageSerializer;
58
+ private getSerializer;
59
+ }
@@ -0,0 +1,244 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local t = TS.import(script, TS.getModule(script, "@rbxts", "t").lib.ts).t
4
+ local Networking = TS.import(script, TS.getModule(script, "@flamework", "networking").out).Networking
5
+ local createBinarySerializer = TS.import(script, TS.getModule(script, "@rbxts", "flamework-binary-serializer").out).createBinarySerializer
6
+ local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
7
+ local Players = _services.Players
8
+ local RunService = _services.RunService
9
+ local Destroyable = TS.import(script, TS.getModule(script, "@rbxts", "destroyable").out).default
10
+ local DropRequest = TS.import(script, script.Parent, "middleware").DropRequest
11
+ local GlobalEvents = Networking.createEvent("@rbxts/tether:message-emitter@GlobalEvents")
12
+ local MessageEmitter
13
+ do
14
+ local super = Destroyable
15
+ MessageEmitter = setmetatable({}, {
16
+ __tostring = function()
17
+ return "MessageEmitter"
18
+ end,
19
+ __index = super,
20
+ })
21
+ MessageEmitter.__index = MessageEmitter
22
+ function MessageEmitter.new(...)
23
+ local self = setmetatable({}, MessageEmitter)
24
+ return self:constructor(...) or self
25
+ end
26
+ function MessageEmitter:constructor(middleware)
27
+ super.constructor(self)
28
+ self.middleware = middleware
29
+ self.clientCallbacks = {}
30
+ self.serverCallbacks = {}
31
+ self.serializers = {}
32
+ self.janitor:Add(function()
33
+ table.clear(self.clientCallbacks)
34
+ table.clear(self.serverCallbacks)
35
+ self.serializers = nil
36
+ self.serverEvents = nil
37
+ self.clientEvents = nil
38
+ end)
39
+ if RunService:IsServer() then
40
+ self.serverEvents = GlobalEvents:createServer({}, {
41
+ incomingIds = { "sendServerMessage", "sendUnreliableServerMessage" },
42
+ incoming = {
43
+ sendServerMessage = { { t.union(t.string, t.number), t.optional(t.interface({
44
+ buffer = t.typeof("buffer"),
45
+ blobs = t.array(t.any),
46
+ })) }, nil },
47
+ sendUnreliableServerMessage = { { t.union(t.string, t.number), t.optional(t.interface({
48
+ buffer = t.typeof("buffer"),
49
+ blobs = t.array(t.any),
50
+ })) }, nil },
51
+ },
52
+ incomingUnreliable = {
53
+ sendUnreliableServerMessage = true,
54
+ },
55
+ outgoingIds = { "sendClientMessage", "sendUnreliableClientMessage" },
56
+ outgoingUnreliable = {
57
+ sendUnreliableClientMessage = true,
58
+ },
59
+ namespaceIds = {},
60
+ namespaces = {},
61
+ })
62
+ else
63
+ self.clientEvents = GlobalEvents:createClient({}, {
64
+ incomingIds = { "sendClientMessage", "sendUnreliableClientMessage" },
65
+ incoming = {
66
+ sendClientMessage = { { t.union(t.string, t.number), t.optional(t.interface({
67
+ buffer = t.typeof("buffer"),
68
+ blobs = t.array(t.any),
69
+ })) }, nil },
70
+ sendUnreliableClientMessage = { { t.union(t.string, t.number), t.optional(t.interface({
71
+ buffer = t.typeof("buffer"),
72
+ blobs = t.array(t.any),
73
+ })) }, nil },
74
+ },
75
+ incomingUnreliable = {
76
+ sendUnreliableClientMessage = true,
77
+ },
78
+ outgoingIds = { "sendServerMessage", "sendUnreliableServerMessage" },
79
+ outgoingUnreliable = {
80
+ sendUnreliableServerMessage = true,
81
+ },
82
+ namespaceIds = {},
83
+ namespaces = {},
84
+ })
85
+ end
86
+ end
87
+ function MessageEmitter:create(middleware, metaForEachMessage)
88
+ local emitter = MessageEmitter.new(middleware)
89
+ if metaForEachMessage == nil then
90
+ warn("[Tether]: Failed to generate serializer metadata for MessageEmitter")
91
+ return emitter:initialize()
92
+ end
93
+ for kind, meta in pairs(metaForEachMessage) do
94
+ if meta == nil then
95
+ continue
96
+ end
97
+ emitter:addSerializer(kind, meta)
98
+ end
99
+ return emitter:initialize()
100
+ end
101
+ function MessageEmitter:onServerMessage(message, callback)
102
+ return self:on(message, callback)
103
+ end
104
+ function MessageEmitter:onClientMessage(message, callback)
105
+ return self:on(message, callback)
106
+ end
107
+ function MessageEmitter:on(message, callback)
108
+ local callbacksMap = if RunService:IsServer() then self.serverCallbacks else self.clientCallbacks
109
+ local _message = message
110
+ if not (callbacksMap[_message] ~= nil) then
111
+ local _message_1 = message
112
+ callbacksMap[_message_1] = {}
113
+ end
114
+ local _message_1 = message
115
+ local callbacks = callbacksMap[_message_1]
116
+ local _callback = callback
117
+ callbacks[_callback] = true
118
+ local _message_2 = message
119
+ callbacksMap[_message_2] = callbacks
120
+ return function()
121
+ local _callback_1 = callback
122
+ -- ▼ Set.delete ▼
123
+ local _valueExisted = callbacks[_callback_1] ~= nil
124
+ callbacks[_callback_1] = nil
125
+ -- ▲ Set.delete ▲
126
+ return _valueExisted
127
+ end
128
+ end
129
+ function MessageEmitter:emitServer(message, data, unreliable)
130
+ if unreliable == nil then
131
+ unreliable = false
132
+ end
133
+ if self.middleware ~= nil then
134
+ for _, middleware in self.middleware:getServer(message) do
135
+ local result = middleware(data)
136
+ if result == DropRequest then
137
+ return nil
138
+ end
139
+ end
140
+ end
141
+ local send = if unreliable then self.clientEvents.sendUnreliableServerMessage else self.clientEvents.sendServerMessage
142
+ send(message, self:getPacket(message, data))
143
+ end
144
+ function MessageEmitter:emitClient(player, message, data, unreliable)
145
+ if unreliable == nil then
146
+ unreliable = false
147
+ end
148
+ if self.middleware ~= nil then
149
+ for _, middleware in self.middleware:getClient(message) do
150
+ local result = middleware(player, data)
151
+ if result == DropRequest then
152
+ return nil
153
+ end
154
+ end
155
+ end
156
+ local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
157
+ send(player, message, self:getPacket(message, data))
158
+ end
159
+ function MessageEmitter:emitAllClients(message, data, unreliable)
160
+ if unreliable == nil then
161
+ unreliable = false
162
+ end
163
+ if self.middleware ~= nil then
164
+ for _, middleware in self.middleware:getClient(message) do
165
+ for _1, player in Players:GetPlayers() do
166
+ local result = middleware(player, data)
167
+ if result == DropRequest then
168
+ return nil
169
+ end
170
+ end
171
+ end
172
+ end
173
+ local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
174
+ send:broadcast(message, self:getPacket(message, data))
175
+ end
176
+ function MessageEmitter:initialize()
177
+ if RunService:IsClient() then
178
+ self.janitor:Add(self.clientEvents.sendClientMessage:connect(function(sentMessage, packet)
179
+ local _clientCallbacks = self.clientCallbacks
180
+ local _sentMessage = sentMessage
181
+ local _condition = _clientCallbacks[_sentMessage]
182
+ if _condition == nil then
183
+ _condition = {}
184
+ end
185
+ local messageCallbacks = _condition
186
+ -- ▼ ReadonlySet.size ▼
187
+ local _size = 0
188
+ for _ in messageCallbacks do
189
+ _size += 1
190
+ end
191
+ -- ▲ ReadonlySet.size ▲
192
+ if _size == 0 then
193
+ return nil
194
+ end
195
+ local serializer = self:getSerializer(sentMessage)
196
+ local data = if packet ~= nil then serializer.deserialize(packet.buffer, packet.blobs) else nil
197
+ for callback in messageCallbacks do
198
+ callback(data)
199
+ end
200
+ end))
201
+ else
202
+ self.janitor:Add(self.serverEvents.sendServerMessage:connect(function(player, sentMessage, packet)
203
+ local _serverCallbacks = self.serverCallbacks
204
+ local _sentMessage = sentMessage
205
+ local _condition = _serverCallbacks[_sentMessage]
206
+ if _condition == nil then
207
+ _condition = {}
208
+ end
209
+ local messageCallbacks = _condition
210
+ -- ▼ ReadonlySet.size ▼
211
+ local _size = 0
212
+ for _ in messageCallbacks do
213
+ _size += 1
214
+ end
215
+ -- ▲ ReadonlySet.size ▲
216
+ if _size == 0 then
217
+ return nil
218
+ end
219
+ local serializer = self:getSerializer(sentMessage)
220
+ local data = if packet ~= nil then serializer.deserialize(packet.buffer, packet.blobs) else nil
221
+ for callback in messageCallbacks do
222
+ callback(player, data)
223
+ end
224
+ end))
225
+ end
226
+ return self
227
+ end
228
+ function MessageEmitter:getPacket(message, data)
229
+ local serializer = self:getSerializer(message)
230
+ return if data == nil then nil else serializer.serialize(data)
231
+ end
232
+ function MessageEmitter:addSerializer(message, meta)
233
+ self.serializers[message] = self:createMessageSerializer(meta)
234
+ end
235
+ function MessageEmitter:createMessageSerializer(meta)
236
+ return createBinarySerializer(meta)
237
+ end
238
+ function MessageEmitter:getSerializer(message)
239
+ return self.serializers[tostring(message)]
240
+ end
241
+ end
242
+ return {
243
+ MessageEmitter = MessageEmitter,
244
+ }
@@ -0,0 +1,18 @@
1
+ type DropRequestSymbol = symbol & {
2
+ _skip_middleware?: undefined;
3
+ };
4
+ export declare const DropRequest: DropRequestSymbol;
5
+ export type ClientMiddleware<Data = unknown> = (player: Player, data: Data | undefined) => DropRequestSymbol | void;
6
+ export type ServerMiddleware<Data = unknown> = (data: Data | undefined) => DropRequestSymbol | void;
7
+ export type Middleware<Data = unknown> = ServerMiddleware<Data> & ClientMiddleware<Data>;
8
+ export declare class MiddlewareProvider<MessageData> {
9
+ private readonly clientMiddlewares;
10
+ private readonly serverMiddlewares;
11
+ /** @hidden */
12
+ getClient<Kind extends keyof MessageData>(message: Kind): ClientMiddleware<MessageData[Kind]>[];
13
+ /** @hidden */
14
+ getServer<Kind extends keyof MessageData>(message: Kind): ServerMiddleware<MessageData[Kind]>[];
15
+ useClient<Kind extends keyof MessageData>(message: Kind, middlewares: ClientMiddleware<MessageData[Kind]> | ClientMiddleware<MessageData[Kind]>[], order?: number): this;
16
+ useServer<Kind extends keyof MessageData>(message: Kind, middlewares: ServerMiddleware<MessageData[Kind]> | ServerMiddleware<MessageData[Kind]>[], order?: number): this;
17
+ }
18
+ export {};
@@ -0,0 +1,77 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local function createSymbol(name)
3
+ local symbol = newproxy(true)
4
+ local mt = getmetatable(symbol)
5
+ mt.__tostring = function()
6
+ return name
7
+ end
8
+ return symbol
9
+ end
10
+ local DropRequest = createSymbol("DropRequest")
11
+ local MiddlewareProvider
12
+ do
13
+ MiddlewareProvider = setmetatable({}, {
14
+ __tostring = function()
15
+ return "MiddlewareProvider"
16
+ end,
17
+ })
18
+ MiddlewareProvider.__index = MiddlewareProvider
19
+ function MiddlewareProvider.new(...)
20
+ local self = setmetatable({}, MiddlewareProvider)
21
+ return self:constructor(...) or self
22
+ end
23
+ function MiddlewareProvider:constructor()
24
+ self.clientMiddlewares = {}
25
+ self.serverMiddlewares = {}
26
+ end
27
+ function MiddlewareProvider:getClient(message)
28
+ if self.clientMiddlewares[message] == nil then
29
+ self.clientMiddlewares[message] = {}
30
+ end
31
+ return self.clientMiddlewares[message]
32
+ end
33
+ function MiddlewareProvider:getServer(message)
34
+ if self.serverMiddlewares[message] == nil then
35
+ self.serverMiddlewares[message] = {}
36
+ end
37
+ return self.serverMiddlewares[message]
38
+ end
39
+ function MiddlewareProvider:useClient(message, middlewares, order)
40
+ local messageMiddleware = self:getClient(message)
41
+ local _middlewares = middlewares
42
+ if typeof(_middlewares) == "function" then
43
+ local _condition = order
44
+ if _condition == nil then
45
+ _condition = #messageMiddleware - 1
46
+ end
47
+ local _middlewares_1 = middlewares
48
+ table.insert(messageMiddleware, _condition + 1, _middlewares_1)
49
+ else
50
+ for _, middleware in middlewares do
51
+ self:useClient(message, middleware)
52
+ end
53
+ end
54
+ return self
55
+ end
56
+ function MiddlewareProvider:useServer(message, middlewares, order)
57
+ local messageMiddleware = self:getServer(message)
58
+ local _middlewares = middlewares
59
+ if typeof(_middlewares) == "function" then
60
+ local _condition = order
61
+ if _condition == nil then
62
+ _condition = #messageMiddleware - 1
63
+ end
64
+ local _middlewares_1 = middlewares
65
+ table.insert(messageMiddleware, _condition + 1, _middlewares_1)
66
+ else
67
+ for _, middleware in middlewares do
68
+ self:useServer(message, middleware)
69
+ end
70
+ end
71
+ return self
72
+ end
73
+ end
74
+ return {
75
+ DropRequest = DropRequest,
76
+ MiddlewareProvider = MiddlewareProvider,
77
+ }
@@ -0,0 +1,19 @@
1
+ import type { Networking } from "@flamework/networking";
2
+ export type MessageCallback<T = unknown> = ServerMessageCallback<T> | ClientMessageCallback<T>;
3
+ export type ClientMessageCallback<T = unknown> = (data: T) => void;
4
+ export type ServerMessageCallback<T = unknown> = (player: Player, data: T) => void;
5
+ export type BaseMessage = number | string | symbol;
6
+ export interface SerializedPacket {
7
+ readonly buffer: buffer;
8
+ readonly blobs: defined[];
9
+ }
10
+ export type MessageEvent = (kind: BaseMessage, packet?: SerializedPacket) => void;
11
+ export type UnreliableMessageEvent = Networking.Unreliable<MessageEvent>;
12
+ export interface ServerEvents {
13
+ sendServerMessage: MessageEvent;
14
+ sendUnreliableServerMessage: UnreliableMessageEvent;
15
+ }
16
+ export interface ClientEvents {
17
+ sendClientMessage: MessageEvent;
18
+ sendUnreliableClientMessage: UnreliableMessageEvent;
19
+ }
@@ -0,0 +1,2 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ return nil
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/tether",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "main": "out/init.lua",
5
5
  "scripts": {
6
6
  "build": "rbxtsc",
@@ -14,7 +14,7 @@
14
14
  "message"
15
15
  ],
16
16
  "repository": {
17
- "url": "https://github.com/R-unic/tether.git"
17
+ "url": "git+https://github.com/R-unic/tether.git"
18
18
  },
19
19
  "author": "runicly",
20
20
  "license": "ISC",
@@ -30,12 +30,14 @@
30
30
  "devDependencies": {
31
31
  "@rbxts/compiler-types": "^3.0.0-types.0",
32
32
  "@rbxts/types": "^1.0.835",
33
+ "rbxts-transformer-flamework": "latest",
33
34
  "roblox-ts": "^3.0.0",
34
- "typescript": "^5.7.3"
35
+ "typescript": "^5.5.3"
35
36
  },
36
37
  "dependencies": {
37
38
  "@flamework/core": "^1.2.3",
38
39
  "@flamework/networking": "^1.2.3",
40
+ "@rbxts/destroyable": "^1.0.1",
39
41
  "@rbxts/flamework-binary-serializer": "^0.6.0",
40
42
  "@rbxts/services": "^1.5.5"
41
43
  }