@rbxts/tether 1.0.6 → 1.0.8

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
@@ -69,10 +69,14 @@ import { MessageEmitter, BuiltinMiddlewares } from "@rbxts/tether";
69
69
 
70
70
  export const messaging = MessageEmitter.create<MessageData>();
71
71
  messaging.middleware
72
- .useUniversal(Message.Test, [BuiltinMiddlewares.rateLimit(5)]) // only allows requests every 5 seconds, drops any
73
- // requests that occur within 5 seconds of each other
74
- .useClient(Message.Test, [BuiltinMiddlewares.validateClient()]); // automatically validates that data sent through the remote
75
- // matches the data associated with the message at runtime
72
+ // only allows requests to the server every 5 seconds,
73
+ // drops any requests that occur within 5 seconds of each other
74
+ .useServer(Message.Test, [BuiltinMiddlewares.rateLimit(5)])
75
+ // automatically validates that data sent through the remote
76
+ // matches the data associated with the message at runtime
77
+ .useShared(Message.Test, [BuiltinMiddlewares.validateClient()])
78
+ // rate limit every server remote (global)
79
+ .useServerGlobal([BuiltinMiddlewares.rateLimit(1)]);
76
80
 
77
81
  export const enum Message {
78
82
  Test
@@ -1,5 +1,5 @@
1
1
  import { Modding } from "@flamework/core";
2
- import { type UniversalMiddleware, type ServerMiddleware, type ClientMiddleware } from "./middleware";
2
+ import { type SharedMiddleware, type ServerMiddleware, type ClientMiddleware } from "./middleware";
3
3
  type Guard<T> = (value: unknown) => value is T;
4
4
  export declare namespace BuiltinMiddlewares {
5
5
  /**
@@ -7,7 +7,7 @@ export declare namespace BuiltinMiddlewares {
7
7
  * @param interval The interval in seconds that the middleware should wait before allowing a new request.
8
8
  * @returns A middleware that will drop any message that occurs within the given interval.
9
9
  */
10
- function rateLimit(interval: number): UniversalMiddleware;
10
+ function rateLimit(interval: number): SharedMiddleware;
11
11
  /**
12
12
  * Creates a server middleware that validates the data with the given guard (or a generated guard if none was provided).
13
13
  * If the guard fails, the middleware will drop the message.
@@ -3,7 +3,7 @@ local TS = _G[script]
3
3
  local DropRequest = TS.import(script, script.Parent, "middleware").DropRequest
4
4
  local noOp = function() end
5
5
  local validationGuardGenerationFailed = function(context)
6
- return `[Tether]: Failed to generate guard for validate{context}<T> builtin middleware - skipping validation`
6
+ return `[@rbxts/tether]: Failed to generate guard for validate{context}<T> builtin middleware - skipping validation`
7
7
  end
8
8
  local BuiltinMiddlewares = {}
9
9
  do
@@ -89,7 +89,7 @@ do
89
89
  function MessageEmitter:create(metaForEachMessage)
90
90
  local emitter = MessageEmitter.new()
91
91
  if metaForEachMessage == nil then
92
- warn("[Tether]: Failed to generate serializer metadata for MessageEmitter")
92
+ warn("[@rbxts/tether]: Failed to generate serializer metadata for MessageEmitter")
93
93
  return emitter:initialize()
94
94
  end
95
95
  for kind, meta in pairs(metaForEachMessage) do
@@ -132,12 +132,16 @@ do
132
132
  if unreliable == nil then
133
133
  unreliable = false
134
134
  end
135
- if self.middleware ~= nil then
136
- for _, middleware in self.middleware:getServer(message) do
137
- local result = middleware(data)
138
- if result == DropRequest then
139
- return nil
140
- end
135
+ for _, middleware in self.middleware:getServerGlobal() do
136
+ local result = middleware(data)
137
+ if result == DropRequest then
138
+ return nil
139
+ end
140
+ end
141
+ for _, middleware in self.middleware:getServer(message) do
142
+ local result = middleware(data)
143
+ if result == DropRequest then
144
+ return nil
141
145
  end
142
146
  end
143
147
  local send = if unreliable then self.clientEvents.sendUnreliableServerMessage else self.clientEvents.sendServerMessage
@@ -147,12 +151,16 @@ do
147
151
  if unreliable == nil then
148
152
  unreliable = false
149
153
  end
150
- if self.middleware ~= nil then
151
- for _, middleware in self.middleware:getClient(message) do
152
- local result = middleware(player, data)
153
- if result == DropRequest then
154
- return nil
155
- end
154
+ for _, middleware in self.middleware:getClientGlobal() do
155
+ local result = middleware(player, data)
156
+ if result == DropRequest then
157
+ return nil
158
+ end
159
+ end
160
+ for _, middleware in self.middleware:getClient(message) do
161
+ local result = middleware(player, data)
162
+ if result == DropRequest then
163
+ return nil
156
164
  end
157
165
  end
158
166
  local send = if unreliable then self.serverEvents.sendUnreliableClientMessage else self.serverEvents.sendClientMessage
@@ -162,13 +170,19 @@ do
162
170
  if unreliable == nil then
163
171
  unreliable = false
164
172
  end
165
- if self.middleware ~= nil then
166
- for _, middleware in self.middleware:getClient(message) do
167
- for _1, player in Players:GetPlayers() do
168
- local result = middleware(player, data)
169
- if result == DropRequest then
170
- return nil
171
- end
173
+ for _, middleware in self.middleware:getClientGlobal() do
174
+ for _1, player in Players:GetPlayers() do
175
+ local result = middleware(player, data)
176
+ if result == DropRequest then
177
+ return nil
178
+ end
179
+ end
180
+ end
181
+ for _, middleware in self.middleware:getClient(message) do
182
+ for _1, player in Players:GetPlayers() do
183
+ local result = middleware(player, data)
184
+ if result == DropRequest then
185
+ return nil
172
186
  end
173
187
  end
174
188
  end
@@ -4,17 +4,26 @@ type DropRequestSymbol = symbol & {
4
4
  export declare const DropRequest: DropRequestSymbol;
5
5
  export type ClientMiddleware<Data = unknown> = (player: Player, data: Readonly<Data> | undefined) => DropRequestSymbol | void;
6
6
  export type ServerMiddleware<Data = unknown> = (data: Readonly<Data> | undefined) => DropRequestSymbol | void;
7
- export type UniversalMiddleware = () => DropRequestSymbol | void;
7
+ export type SharedMiddleware = () => DropRequestSymbol | void;
8
8
  export type Middleware<Data = unknown> = ServerMiddleware<Data> & ClientMiddleware<Data>;
9
9
  export declare class MiddlewareProvider<MessageData> {
10
+ private readonly clientGlobalMiddlewares;
11
+ private readonly serverGlobalMiddlewares;
10
12
  private readonly clientMiddlewares;
11
13
  private readonly serverMiddlewares;
12
14
  /** @hidden */
13
15
  getClient<Kind extends keyof MessageData>(message: Kind): ClientMiddleware<MessageData[Kind]>[];
14
16
  /** @hidden */
15
17
  getServer<Kind extends keyof MessageData>(message: Kind): ServerMiddleware<MessageData[Kind]>[];
16
- useClient<Kind extends keyof MessageData>(message: Kind, middlewares: ClientMiddleware<MessageData[Kind]> | ClientMiddleware<MessageData[Kind]>[], order?: number): this;
17
- useServer<Kind extends keyof MessageData>(message: Kind, middlewares: ServerMiddleware<MessageData[Kind]> | ServerMiddleware<MessageData[Kind]>[], order?: number): this;
18
- useUniversal<Kind extends keyof MessageData>(message: Kind, middlewares: UniversalMiddleware | UniversalMiddleware[], order?: number): this;
18
+ /** @hidden */
19
+ getClientGlobal<Data>(): ClientMiddleware<Data>[];
20
+ /** @hidden */
21
+ getServerGlobal<Data>(): ServerMiddleware<Data>[];
22
+ useClient<Kind extends keyof MessageData>(message: Kind, middlewares: ClientMiddleware<MessageData[Kind]> | readonly ClientMiddleware<MessageData[Kind]>[], order?: number): this;
23
+ useServer<Kind extends keyof MessageData>(message: Kind, middlewares: ServerMiddleware<MessageData[Kind]> | readonly ServerMiddleware<MessageData[Kind]>[], order?: number): this;
24
+ useShared<Kind extends keyof MessageData>(message: Kind, middlewares: SharedMiddleware | readonly SharedMiddleware[], order?: number): this;
25
+ useClientGlobal<Data>(middlewares: ClientMiddleware<Data> | readonly ClientMiddleware<Data>[], order?: number): this;
26
+ useServerGlobal<Data>(middlewares: ServerMiddleware<Data> | readonly ServerMiddleware<Data>[], order?: number): this;
27
+ useSharedGlobal(middlewares: SharedMiddleware | readonly SharedMiddleware[], order?: number): this;
19
28
  }
20
29
  export {};
@@ -13,6 +13,8 @@ do
13
13
  return self:constructor(...) or self
14
14
  end
15
15
  function MiddlewareProvider:constructor()
16
+ self.clientGlobalMiddlewares = {}
17
+ self.serverGlobalMiddlewares = {}
16
18
  self.clientMiddlewares = {}
17
19
  self.serverMiddlewares = {}
18
20
  end
@@ -28,6 +30,12 @@ do
28
30
  end
29
31
  return self.serverMiddlewares[message]
30
32
  end
33
+ function MiddlewareProvider:getClientGlobal()
34
+ return self.clientGlobalMiddlewares
35
+ end
36
+ function MiddlewareProvider:getServerGlobal()
37
+ return self.serverGlobalMiddlewares
38
+ end
31
39
  function MiddlewareProvider:useClient(message, middlewares, order)
32
40
  local messageMiddleware = self:getClient(message)
33
41
  local _middlewares = middlewares
@@ -40,7 +48,7 @@ do
40
48
  table.insert(messageMiddleware, _condition + 1, _middlewares_1)
41
49
  else
42
50
  for _, middleware in middlewares do
43
- self:useClient(message, middleware)
51
+ self:useClient(message, middleware, order)
44
52
  end
45
53
  end
46
54
  return self
@@ -57,16 +65,55 @@ do
57
65
  table.insert(messageMiddleware, _condition + 1, _middlewares_1)
58
66
  else
59
67
  for _, middleware in middlewares do
60
- self:useServer(message, middleware)
68
+ self:useServer(message, middleware, order)
61
69
  end
62
70
  end
63
71
  return self
64
72
  end
65
- function MiddlewareProvider:useUniversal(message, middlewares, order)
73
+ function MiddlewareProvider:useShared(message, middlewares, order)
66
74
  self:useClient(message, middlewares, order)
67
75
  self:useServer(message, middlewares, order)
68
76
  return self
69
77
  end
78
+ function MiddlewareProvider:useClientGlobal(middlewares, order)
79
+ local globalMiddleware = self:getClientGlobal()
80
+ local _middlewares = middlewares
81
+ if typeof(_middlewares) == "function" then
82
+ local _condition = order
83
+ if _condition == nil then
84
+ _condition = #globalMiddleware - 1
85
+ end
86
+ local _middlewares_1 = middlewares
87
+ table.insert(globalMiddleware, _condition + 1, _middlewares_1)
88
+ else
89
+ for _, middleware in middlewares do
90
+ self:useClientGlobal(middleware, order)
91
+ end
92
+ end
93
+ return self
94
+ end
95
+ function MiddlewareProvider:useServerGlobal(middlewares, order)
96
+ local globalMiddleware = self:getServerGlobal()
97
+ local _middlewares = middlewares
98
+ if typeof(_middlewares) == "function" then
99
+ local _condition = order
100
+ if _condition == nil then
101
+ _condition = #globalMiddleware - 1
102
+ end
103
+ local _middlewares_1 = middlewares
104
+ table.insert(globalMiddleware, _condition + 1, _middlewares_1)
105
+ else
106
+ for _, middleware in middlewares do
107
+ self:useServerGlobal(middleware, order)
108
+ end
109
+ end
110
+ return self
111
+ end
112
+ function MiddlewareProvider:useSharedGlobal(middlewares, order)
113
+ self:useClientGlobal(middlewares, order)
114
+ self:useServerGlobal(middlewares, order)
115
+ return self
116
+ end
70
117
  end
71
118
  return {
72
119
  DropRequest = DropRequest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/tether",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "main": "out/init.lua",
5
5
  "scripts": {
6
6
  "build": "rbxtsc",
@@ -11,7 +11,9 @@
11
11
  "roblox",
12
12
  "tether",
13
13
  "networking",
14
- "message"
14
+ "message",
15
+ "serialization",
16
+ "middleware"
15
17
  ],
16
18
  "repository": {
17
19
  "url": "git+https://github.com/R-unic/tether.git"