@flamework-experimental/networking 2.0.0-alpha.0

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.
Files changed (48) hide show
  1. package/README.md +66 -0
  2. package/flamework.build +7 -0
  3. package/out/event/createEvent.d.ts +59 -0
  4. package/out/event/createEvent.luau +114 -0
  5. package/out/event/createRemoteInstance.d.ts +1 -0
  6. package/out/event/createRemoteInstance.luau +58 -0
  7. package/out/events/createClientMethod.d.ts +5 -0
  8. package/out/events/createClientMethod.luau +30 -0
  9. package/out/events/createGenericHandler.d.ts +5 -0
  10. package/out/events/createGenericHandler.luau +102 -0
  11. package/out/events/createNetworkingEvent.d.ts +2 -0
  12. package/out/events/createNetworkingEvent.luau +60 -0
  13. package/out/events/createServerMethod.d.ts +13 -0
  14. package/out/events/createServerMethod.luau +63 -0
  15. package/out/events/types.d.ts +220 -0
  16. package/out/function/createFunctionReceiver.d.ts +52 -0
  17. package/out/function/createFunctionReceiver.luau +118 -0
  18. package/out/function/createFunctionSender.d.ts +45 -0
  19. package/out/function/createFunctionSender.luau +135 -0
  20. package/out/function/errors.d.ts +10 -0
  21. package/out/function/errors.luau +25 -0
  22. package/out/functions/createClientMethod.d.ts +15 -0
  23. package/out/functions/createClientMethod.luau +52 -0
  24. package/out/functions/createGenericHandler.d.ts +7 -0
  25. package/out/functions/createGenericHandler.luau +140 -0
  26. package/out/functions/createNetworkingFunction.d.ts +2 -0
  27. package/out/functions/createNetworkingFunction.luau +68 -0
  28. package/out/functions/createServerMethod.d.ts +15 -0
  29. package/out/functions/createServerMethod.luau +52 -0
  30. package/out/functions/types.d.ts +289 -0
  31. package/out/handlers.d.ts +36 -0
  32. package/out/index.d.ts +55 -0
  33. package/out/init.luau +78 -0
  34. package/out/middleware/createGuardMiddleware.d.ts +6 -0
  35. package/out/middleware/createGuardMiddleware.luau +44 -0
  36. package/out/middleware/createMiddlewareProcessor.d.ts +3 -0
  37. package/out/middleware/createMiddlewareProcessor.luau +24 -0
  38. package/out/middleware/skip.d.ts +8 -0
  39. package/out/middleware/skip.luau +22 -0
  40. package/out/middleware/types.d.ts +15 -0
  41. package/out/types.d.ts +78 -0
  42. package/out/util/createSignalContainer.d.ts +5 -0
  43. package/out/util/createSignalContainer.luau +30 -0
  44. package/out/util/getNamespaceConfig.d.ts +10 -0
  45. package/out/util/getNamespaceConfig.luau +15 -0
  46. package/out/util/timeoutPromise.d.ts +1 -0
  47. package/out/util/timeoutPromise.luau +10 -0
  48. package/package.json +32 -0
@@ -0,0 +1,140 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local NetworkingFunctionError = TS.import(script, script.Parent.Parent, "function", "errors").NetworkingFunctionError
4
+ local SkipBadRequest = TS.import(script, script.Parent.Parent, "middleware", "skip").SkipBadRequest
5
+ local createFunctionReceiver = TS.import(script, script.Parent.Parent, "function", "createFunctionReceiver").createFunctionReceiver
6
+ local createFunctionSender = TS.import(script, script.Parent.Parent, "function", "createFunctionSender").createFunctionSender
7
+ local createGuardMiddleware = TS.import(script, script.Parent.Parent, "middleware", "createGuardMiddleware").createGuardMiddleware
8
+ local Players = TS.import(script, TS.getModule(script, "@rbxts", "services")).Players
9
+ local getNamespaceConfig = TS.import(script, script.Parent.Parent, "util", "getNamespaceConfig").getNamespaceConfig
10
+ local function createGenericHandler(globalName, namespaceName, receiverPrefix, senderPrefix, metadata, config, signals, createMethod)
11
+ local handler = {}
12
+ local _set = {}
13
+ for _, _v in metadata.incomingIds do
14
+ _set[_v] = true
15
+ end
16
+ local receiverNameSet = _set
17
+ local _set_1 = {}
18
+ for _, _v in metadata.outgoingIds do
19
+ _set_1[_v] = true
20
+ end
21
+ local senderNameSet = _set_1
22
+ local _set_2 = {}
23
+ local _array = {}
24
+ local _length = #_array
25
+ local _array_1 = metadata.incomingIds
26
+ local _Length = #_array_1
27
+ table.move(_array_1, 1, _Length, _length + 1, _array)
28
+ _length += _Length
29
+ local _array_2 = metadata.outgoingIds
30
+ table.move(_array_2, 1, #_array_2, _length + 1, _array)
31
+ for _, _v in _array do
32
+ _set_2[_v] = true
33
+ end
34
+ for name in _set_2 do
35
+ local configMiddleware = config.middleware[name]
36
+ local incomingMiddleware = if configMiddleware ~= nil then table.clone(configMiddleware) else {}
37
+ local isReceiver = receiverNameSet[name] ~= nil
38
+ local isSender = senderNameSet[name] ~= nil
39
+ local effectiveName = if namespaceName ~= nil then `{namespaceName}/{name}` else name
40
+ local networkInfo = {
41
+ eventType = "Function",
42
+ name = effectiveName,
43
+ globalName = globalName,
44
+ }
45
+ if not config.disableIncomingGuards and isReceiver then
46
+ local guards = metadata.incoming[name]
47
+ assert(guards)
48
+ local _arg0 = createGuardMiddleware(name, guards[1], guards[2], networkInfo, config.warnOnInvalidGuards, signals, SkipBadRequest)
49
+ table.insert(incomingMiddleware, 1, _arg0)
50
+ end
51
+ -- A malformed serialized payload is reported like a failed guard, with no argument index.
52
+ local onMalformed = function(player, message)
53
+ if config.warnOnInvalidGuards then
54
+ local sender = if player ~= nil then `'{player}'` else "Server"
55
+ warn(`{sender} sent a malformed payload for function '{name}': {message}`)
56
+ end
57
+ signals:fire("onBadRequest", player or Players.LocalPlayer, {
58
+ networkInfo = networkInfo,
59
+ argIndex = -1,
60
+ argValue = message,
61
+ })
62
+ end
63
+ local _result
64
+ if isReceiver then
65
+ local _object = {
66
+ namespace = globalName,
67
+ debugName = name,
68
+ id = if isSender then `{receiverPrefix}{effectiveName}` else effectiveName,
69
+ networkInfo = networkInfo,
70
+ incomingMiddleware = incomingMiddleware,
71
+ }
72
+ local _left = "argsDecoder"
73
+ local _result_1 = metadata.incomingSerializers
74
+ if _result_1 ~= nil then
75
+ _result_1 = _result_1[name]
76
+ end
77
+ _object[_left] = _result_1
78
+ local _left_1 = "resultDecoder"
79
+ local _result_2 = metadata.incomingResults
80
+ if _result_2 ~= nil then
81
+ _result_2 = _result_2[name]
82
+ end
83
+ _object[_left_1] = _result_2
84
+ _object.onMalformed = onMalformed
85
+ _result = createFunctionReceiver(_object)
86
+ else
87
+ _result = nil
88
+ end
89
+ local receiver = _result
90
+ local _result_1
91
+ if isSender then
92
+ local _object = {
93
+ namespace = globalName,
94
+ debugName = name,
95
+ id = if isReceiver then `{senderPrefix}{effectiveName}` else effectiveName,
96
+ networkInfo = networkInfo,
97
+ }
98
+ local _left = "resultDecoder"
99
+ local _result_2 = metadata.outgoingResults
100
+ if _result_2 ~= nil then
101
+ _result_2 = _result_2[name]
102
+ end
103
+ _object[_left] = _result_2
104
+ _object.onMalformed = function(player, message)
105
+ if config.warnOnInvalidGuards then
106
+ warn(`Received a malformed response for function '{name}': {message}`)
107
+ end
108
+ signals:fire("onBadResponse", player or Players.LocalPlayer, {
109
+ networkInfo = networkInfo,
110
+ value = message,
111
+ })
112
+ end
113
+ _object.responseMiddleware = if config.disableIncomingGuards then nil else function(player, value, resolve, reject)
114
+ local returnGuard = metadata.outgoing[name]
115
+ if returnGuard and not returnGuard(value) then
116
+ reject(NetworkingFunctionError.InvalidResult)
117
+ signals:fire("onBadResponse", player or Players.LocalPlayer, {
118
+ networkInfo = networkInfo,
119
+ value = value,
120
+ })
121
+ else
122
+ resolve(value)
123
+ end
124
+ end
125
+ _result_1 = createFunctionSender(_object)
126
+ else
127
+ _result_1 = nil
128
+ end
129
+ local sender = _result_1
130
+ handler[name] = createMethod(config, receiver, sender)
131
+ end
132
+ for _, namespaceId in metadata.namespaceIds do
133
+ local namespace = metadata.namespaces[namespaceId]
134
+ handler[namespaceId] = createGenericHandler(globalName, if namespaceName ~= nil then `{namespaceName}/{namespaceId}` else namespaceId, receiverPrefix, senderPrefix, namespace, getNamespaceConfig(config, namespaceId), signals, createMethod)
135
+ end
136
+ return handler
137
+ end
138
+ return {
139
+ createGenericHandler = createGenericHandler,
140
+ }
@@ -0,0 +1,2 @@
1
+ import { GlobalFunction } from "./types";
2
+ export declare function createNetworkingFunction<S, C>(globalName: string): GlobalFunction<S, C>;
@@ -0,0 +1,68 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
4
+ local createSignalContainer = TS.import(script, script.Parent.Parent, "util", "createSignalContainer").createSignalContainer
5
+ local createGenericHandler = TS.import(script, script.Parent, "createGenericHandler").createGenericHandler
6
+ local createServerMethod = TS.import(script, script.Parent, "createServerMethod").createServerMethod
7
+ local createClientMethod = TS.import(script, script.Parent, "createClientMethod").createClientMethod
8
+ local SERVER_PREFIX = "$"
9
+ local CLIENT_PREFIX = "@"
10
+ local function getDefaultConfiguration(config)
11
+ local _object = {}
12
+ local _left = "middleware"
13
+ local _condition = config.middleware
14
+ if _condition == nil then
15
+ _condition = {}
16
+ end
17
+ _object[_left] = _condition
18
+ local _left_1 = "defaultTimeout"
19
+ local _condition_1 = config.defaultTimeout
20
+ if _condition_1 == nil then
21
+ _condition_1 = (if RunService:IsClient() then 30 else 10)
22
+ end
23
+ _object[_left_1] = _condition_1
24
+ local _left_2 = "warnOnInvalidGuards"
25
+ local _condition_2 = config.warnOnInvalidGuards
26
+ if _condition_2 == nil then
27
+ _condition_2 = RunService:IsStudio()
28
+ end
29
+ _object[_left_2] = _condition_2
30
+ local _left_3 = "disableIncomingGuards"
31
+ local _condition_3 = config.disableIncomingGuards
32
+ if _condition_3 == nil then
33
+ _condition_3 = false
34
+ end
35
+ _object[_left_3] = _condition_3
36
+ return _object
37
+ end
38
+ local function createNetworkingFunction(globalName)
39
+ local signals = createSignalContainer()
40
+ local server
41
+ local client
42
+ return {
43
+ createServer = function(self, config, meta)
44
+ if RunService:IsRunning() and not RunService:IsServer() then
45
+ return nil
46
+ end
47
+ if server == nil then
48
+ server = createGenericHandler(globalName, nil, SERVER_PREFIX, CLIENT_PREFIX, meta, getDefaultConfiguration(config), signals, createServerMethod)
49
+ end
50
+ return server
51
+ end,
52
+ createClient = function(self, config, meta)
53
+ if RunService:IsRunning() and not RunService:IsClient() then
54
+ return nil
55
+ end
56
+ if client == nil then
57
+ client = createGenericHandler(globalName, nil, CLIENT_PREFIX, SERVER_PREFIX, meta, getDefaultConfiguration(config), signals, createClientMethod)
58
+ end
59
+ return client
60
+ end,
61
+ registerHandler = function(self, key, callback)
62
+ return signals:connect(key, callback)
63
+ end,
64
+ }
65
+ end
66
+ return {
67
+ createNetworkingFunction = createNetworkingFunction,
68
+ }
@@ -0,0 +1,15 @@
1
+ import { FunctionReceiverInterface } from "../function/createFunctionReceiver";
2
+ import { FunctionSenderInterface } from "../function/createFunctionSender";
3
+ import { FunctionCreateConfiguration } from "./types";
4
+ export declare function createServerMethod(config: FunctionCreateConfiguration<unknown>, receiver?: FunctionReceiverInterface, sender?: FunctionSenderInterface): {
5
+ readonly _flamework_send?: unknown[] | undefined;
6
+ _invoke: (player: Player, payload?: buffer, blobs?: Array<defined>) => Promise<unknown>;
7
+ _invokeWithTimeout: (player: Player, timeout: number, payload?: buffer, blobs?: Array<defined>) => Promise<unknown>;
8
+ invoke: (player: Player, ...args: unknown[]) => Promise<unknown>;
9
+ invokeWithTimeout: (player: Player, timeout: number, ...args: unknown[]) => Promise<unknown>;
10
+ readonly _flamework_receive?: unknown[] | undefined;
11
+ readonly _flamework_fn?: unknown;
12
+ _setCallback: (callback: (player: Player, ...args: never[]) => unknown) => void;
13
+ setCallback: (callback: (player: Player, ...args: unknown[]) => unknown | Promise<unknown>) => void;
14
+ predict: (player: Player, ...args: unknown[]) => Promise<unknown>;
15
+ };
@@ -0,0 +1,52 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local NetworkingFunctionError = TS.import(script, script.Parent.Parent, "function", "errors").NetworkingFunctionError
4
+ local timeoutPromise = TS.import(script, script.Parent.Parent, "util", "timeoutPromise").timeoutPromise
5
+ local function createServerMethod(config, receiver, sender)
6
+ local method = {
7
+ invoke = function(self, player, ...)
8
+ local args = { ... }
9
+ return self:invokeWithTimeout(player, config.defaultTimeout, unpack(args))
10
+ end,
11
+ invokeWithTimeout = function(self, player, timeout, ...)
12
+ local args = { ... }
13
+ local _sender = sender
14
+ assert(_sender, "This is not a sender remote.")
15
+ return TS.Promise.race({ timeoutPromise(timeout, NetworkingFunctionError.Timeout), sender:invokeClient(player, unpack(args)) })
16
+ end,
17
+ _invoke = function(self, player, ...)
18
+ local packed = { ... }
19
+ return self:invokeWithTimeout(player, config.defaultTimeout, unpack(packed))
20
+ end,
21
+ _invokeWithTimeout = function(self, player, timeout, ...)
22
+ local packed = { ... }
23
+ return self:invokeWithTimeout(player, timeout, unpack(packed))
24
+ end,
25
+ setCallback = function(self, callback)
26
+ local _receiver = receiver
27
+ assert(_receiver, "This is not a receiver remote.")
28
+ receiver:setServerCallback(callback)
29
+ end,
30
+ _setCallback = function(self, callback)
31
+ local _receiver = receiver
32
+ assert(_receiver, "This is not a receiver remote.")
33
+ receiver:setServerCallback(callback, true)
34
+ end,
35
+ predict = function(self, player, ...)
36
+ local args = { ... }
37
+ local _receiver = receiver
38
+ assert(_receiver, "This is not a receiver remote.")
39
+ return receiver:invoke(player, unpack(args))
40
+ end,
41
+ }
42
+ setmetatable(method, {
43
+ __call = function(method, player, ...)
44
+ local args = { ... }
45
+ return method:invoke(player, unpack(args))
46
+ end,
47
+ })
48
+ return method
49
+ end
50
+ return {
51
+ createServerMethod = createServerMethod,
52
+ }
@@ -0,0 +1,289 @@
1
+ import { NetworkingFunctionError } from "../function/errors";
2
+ import {
3
+ FunctionParameters,
4
+ FunctionReturn,
5
+ IntrinsicTupleGuards,
6
+ IntrinsicNetworkDecoder,
7
+ IntrinsicNetworkResultDecoder,
8
+ IntrinsicObfuscate,
9
+ NetworkingObfuscationMarker,
10
+ NetworkRaw,
11
+ ObfuscateNames,
12
+ } from "../types";
13
+ import { FunctionNetworkingEvents } from "../handlers";
14
+ import { FunctionMiddleware } from "../middleware/types";
15
+ import { Modding } from "@flamework-experimental/core";
16
+
17
+ /**
18
+ * A sender declared `Networking.Raw`: its arguments and the result travel as they are. Without the
19
+ * hidden marker below, no call site packs them and the peer runs no decoder.
20
+ */
21
+ export interface RawServerSender<I extends unknown[], O> {
22
+ (player: Player, ...args: I): Promise<O>;
23
+
24
+ /**
25
+ * Sends this request to the specified player.
26
+ * @param player The player that will receive this event
27
+ */
28
+ invoke(player: Player, ...args: I): Promise<O>;
29
+
30
+ /**
31
+ * Sends this request to the specified player, specifying a timeout.
32
+ * @param player The player that will receive this event
33
+ * @param timeout The maximum time to wait before timing out
34
+ */
35
+ invokeWithTimeout(player: Player, timeout: number, ...args: I): Promise<O>;
36
+ }
37
+
38
+ export interface ServerSender<I extends unknown[], O> extends RawServerSender<I, O> {
39
+ /** @hidden Marks a sender for the transformer, which packs its arguments at each call site. */
40
+ readonly _flamework_send?: I;
41
+
42
+ /** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
43
+ _invoke(player: Player, payload?: buffer, blobs?: Array<defined>): Promise<O>;
44
+
45
+ /** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
46
+ _invokeWithTimeout(player: Player, timeout: number, payload?: buffer, blobs?: Array<defined>): Promise<O>;
47
+ }
48
+
49
+ export interface RawServerReceiver<I extends unknown[], O> {
50
+ /**
51
+ * Connect to a networking event.
52
+ * @param event The event to connect to
53
+ * @param callback The callback that will be invoked
54
+ * @param guards A list of guards that will only be used on this connection
55
+ */
56
+ setCallback(callback: (player: Player, ...args: I) => O | Promise<O>): void;
57
+
58
+ /**
59
+ * Invokes a server function using player as the sender.
60
+ */
61
+ predict(player: Player, ...args: I): Promise<O>;
62
+ }
63
+
64
+ export interface ServerReceiver<I extends unknown[], O, F = unknown> extends RawServerReceiver<I, O> {
65
+ /** @hidden Marks a receiver for the transformer, which packs the callback's result at the call site. */
66
+ readonly _flamework_receive?: I;
67
+
68
+ /** @hidden The declared function type; its return type is what the transformer packs. */
69
+ readonly _flamework_fn?: F;
70
+
71
+ /** @hidden Registers a callback whose successful results are already packed as `[payload, blobs?]`. */
72
+ _setCallback(callback: (player: Player, ...args: never[]) => unknown): void;
73
+ }
74
+
75
+ export interface RawClientSender<I extends unknown[], O> {
76
+ (...args: I): Promise<O>;
77
+
78
+ /**
79
+ * Sends this request to the server.
80
+ */
81
+ invoke(...args: I): Promise<O>;
82
+
83
+ /**
84
+ * Sends this request to the server, specifying a timeout.
85
+ * @param timeout The maximum time to wait before timing out
86
+ */
87
+ invokeWithTimeout(timeout: number, ...args: I): Promise<O>;
88
+ }
89
+
90
+ export interface ClientSender<I extends unknown[], O> extends RawClientSender<I, O> {
91
+ /** @hidden Marks a sender for the transformer, which packs its arguments at each call site. */
92
+ readonly _flamework_send?: I;
93
+
94
+ /** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
95
+ _invoke(payload?: buffer, blobs?: Array<defined>): Promise<O>;
96
+
97
+ /** @hidden Sends an argument list the transformer already packed; nothing when the list carries nothing. */
98
+ _invokeWithTimeout(timeout: number, payload?: buffer, blobs?: Array<defined>): Promise<O>;
99
+ }
100
+
101
+ export interface RawClientReceiver<I extends unknown[], O> {
102
+ /**
103
+ * Connect to a networking function.
104
+ * @param event The function to connect to
105
+ * @param callback The callback that will be invoked
106
+ */
107
+ setCallback(callback: (...args: I) => O | Promise<O>): void;
108
+
109
+ /**
110
+ * Invokes a client function.
111
+ */
112
+ predict(...args: I): Promise<O>;
113
+ }
114
+
115
+ export interface ClientReceiver<I extends unknown[], O, F = unknown> extends RawClientReceiver<I, O> {
116
+ /** @hidden Marks a receiver for the transformer, which packs the callback's result at the call site. */
117
+ readonly _flamework_receive?: I;
118
+
119
+ /** @hidden The declared function type; its return type is what the transformer packs. */
120
+ readonly _flamework_fn?: F;
121
+
122
+ /** @hidden Registers a callback whose successful results are already packed as `[payload, blobs?]`. */
123
+ _setCallback(callback: (...args: never[]) => unknown): void;
124
+ }
125
+
126
+ export type ServerHandler<E, R> = NetworkingObfuscationMarker & {
127
+ [k in keyof Functions<E>]: E[k] extends NetworkRaw<unknown>
128
+ ? RawServerSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>
129
+ : ServerSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>;
130
+ } & {
131
+ [k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
132
+ ? RawServerReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>>
133
+ : ServerReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>, R[k]>;
134
+ } & {
135
+ [k in keyof FunctionNamespaces<E>]: ServerHandler<E[k], k extends keyof R ? R[k] : {}>;
136
+ } & {
137
+ [k in keyof FunctionNamespaces<R>]: ServerHandler<k extends keyof E ? E[k] : {}, R[k]>;
138
+ };
139
+
140
+ export type ClientHandler<E, R> = NetworkingObfuscationMarker & {
141
+ [k in keyof Functions<E>]: E[k] extends NetworkRaw<unknown>
142
+ ? RawClientSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>
143
+ : ClientSender<FunctionParameters<E[k]>, FunctionReturn<E[k]>>;
144
+ } & {
145
+ [k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
146
+ ? RawClientReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>>
147
+ : ClientReceiver<FunctionParameters<R[k]>, FunctionReturn<R[k]>, R[k]>;
148
+ } & {
149
+ [k in keyof FunctionNamespaces<E>]: ClientHandler<E[k], k extends keyof R ? R[k] : {}>;
150
+ } & {
151
+ [k in keyof FunctionNamespaces<R>]: ClientHandler<k extends keyof E ? E[k] : {}, R[k]>;
152
+ };
153
+
154
+ export interface FunctionCreateConfiguration<T> {
155
+ /**
156
+ * Disables input validation, allowing any value to pass.
157
+ * Defaults to `false`
158
+ */
159
+ disableIncomingGuards: boolean;
160
+
161
+ /**
162
+ * Emit a warning whenever a guard fails.
163
+ * Defaults to `RunService.IsStudio()`
164
+ */
165
+ warnOnInvalidGuards: boolean;
166
+
167
+ /**
168
+ * The default timeout for outgoing requests.
169
+ * Defaults to `10`
170
+ */
171
+ defaultTimeout: number;
172
+
173
+ /**
174
+ * The middleware for each event.
175
+ */
176
+ middleware: FunctionMiddlewareList<T>;
177
+ }
178
+
179
+ export interface GlobalFunction<S, C> {
180
+ /**
181
+ * This is the server implementation of the network and does not exist on the client.
182
+ *
183
+ * @metadata macro {@link config intrinsic-const} {@link config intrinsic-middleware}
184
+ */
185
+ createServer(config: Partial<FunctionCreateConfiguration<S>>, meta?: NamespaceMetadata<S, C>): ServerHandler<C, S>;
186
+
187
+ /**
188
+ * This is the client implementation of the network and does not exist on the server.
189
+ *
190
+ * @metadata macro {@link config intrinsic-const} {@link config intrinsic-middleware}
191
+ */
192
+ createClient(config: Partial<FunctionCreateConfiguration<C>>, meta?: NamespaceMetadata<C, S>): ClientHandler<S, C>;
193
+
194
+ /**
195
+ * Registers a networking event handler.
196
+ * @param key The name of the event
197
+ * @param callback The handler you wish to attach
198
+ */
199
+ registerHandler<K extends keyof FunctionNetworkingEvents>(
200
+ key: K,
201
+ callback: FunctionNetworkingEvents[K],
202
+ ): RBXScriptConnection;
203
+ }
204
+
205
+ export interface FunctionConfiguration {
206
+ /**
207
+ * Disables input validation and return validation on the server, allowing any value to pass.
208
+ * Defaults to `false`
209
+ */
210
+ disableServerGuards: boolean;
211
+
212
+ /**
213
+ * Disables input validation and return validation on the client, allowing any value to pass.
214
+ * Defaults to `false`
215
+ */
216
+ disableClientGuards: boolean;
217
+
218
+ /**
219
+ * The default timeout for requests from the server to the client.
220
+ * Defaults to `10`
221
+ */
222
+ defaultServerTimeout: number;
223
+
224
+ /**
225
+ * The default timeout for requests from the client to the server.
226
+ * Defaults to `30`
227
+ */
228
+ defaultClientTimeout: number;
229
+
230
+ /**
231
+ * Emit a warning whenever a guard fails.
232
+ * Defaults to `RunService.IsStudio()`
233
+ */
234
+ warnOnInvalidGuards: boolean;
235
+ }
236
+
237
+ export interface RequestInfo {
238
+ nextId: number;
239
+ requests: Map<number, (value: unknown, rejection?: NetworkingFunctionError) => void>;
240
+ }
241
+
242
+ export type FunctionNamespaces<T> = ExcludeMembers<T, Callback>;
243
+ export type Functions<T> = ExtractMembers<T, Callback>;
244
+
245
+ /**
246
+ * We must generate the return type of events separately as Flamework no longer includes all type guards on both server and client.
247
+ */
248
+ export type NamespaceMetadata<R, S> = Modding.Emit<{
249
+ incomingIds: ObfuscateNames<keyof Functions<R>>;
250
+ incoming: IntrinsicObfuscate<{ [k in keyof Functions<R>]: IntrinsicTupleGuards<Parameters<R[k]>> }>;
251
+
252
+ outgoingIds: ObfuscateNames<keyof Functions<S>>;
253
+ outgoing: IntrinsicObfuscate<{ [k in keyof Functions<S>]: Modding.Target.Guard<ReturnType<S[k]>> }>;
254
+
255
+ /**
256
+ * Decoders, present only with `networking.serialization` on and absent for raw functions: the
257
+ * argument lists of requests this realm receives, the results its callbacks return (so `predict`
258
+ * can unpack them) and the responses to requests it sends. Requests and results are packed inline
259
+ * where they are produced.
260
+ */
261
+ incomingSerializers: IntrinsicObfuscate<{
262
+ [k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown>
263
+ ? undefined
264
+ : IntrinsicNetworkDecoder<Parameters<R[k]>>;
265
+ }>;
266
+ incomingResults: IntrinsicObfuscate<{
267
+ [k in keyof Functions<R>]: R[k] extends NetworkRaw<unknown> ? undefined : IntrinsicNetworkResultDecoder<R[k]>;
268
+ }>;
269
+ outgoingResults: IntrinsicObfuscate<{
270
+ [k in keyof Functions<S>]: S[k] extends NetworkRaw<unknown> ? undefined : IntrinsicNetworkResultDecoder<S[k]>;
271
+ }>;
272
+
273
+ namespaceIds: ObfuscateNames<keyof FunctionNamespaces<R> | keyof FunctionNamespaces<S>>;
274
+ namespaces: IntrinsicObfuscate<
275
+ {
276
+ [k in keyof FunctionNamespaces<R>]: NamespaceMetadata<R[k], k extends keyof S ? S[k] : {}>;
277
+ } & {
278
+ [k in keyof FunctionNamespaces<S>]: NamespaceMetadata<k extends keyof R ? R[k] : {}, S[k]>;
279
+ }
280
+ >;
281
+ }>;
282
+
283
+ export type FunctionMiddlewareList<T> = {
284
+ readonly [k in keyof Functions<T>]?: T[k] extends (...args: infer I) => infer O
285
+ ? [...FunctionMiddleware<I, O>[]]
286
+ : never;
287
+ } & {
288
+ readonly [k in keyof FunctionNamespaces<T>]?: FunctionMiddlewareList<T[k]>;
289
+ };
@@ -0,0 +1,36 @@
1
+ import Signal from "@rbxts/signal";
2
+ import { NetworkInfo } from "./types";
3
+
4
+ interface BaseEvent {
5
+ /**
6
+ * The event or function that was fired.
7
+ */
8
+ networkInfo: NetworkInfo;
9
+ }
10
+
11
+ interface BadRequestData extends BaseEvent {
12
+ /**
13
+ * The index of the argument that was incorrect, or -1 when a serialized payload could not be decoded.
14
+ */
15
+ argIndex: number;
16
+
17
+ /**
18
+ * The value of the argument that was incorrect, or the decoding error for a malformed payload.
19
+ */
20
+ argValue: unknown;
21
+ }
22
+
23
+ interface BadResponseData extends BaseEvent {
24
+ /**
25
+ * The index of the argument that was incorrect.
26
+ */
27
+ value: unknown;
28
+ }
29
+
30
+ export interface EventNetworkingEvents {
31
+ onBadRequest: (player: Player, data: BadRequestData) => void;
32
+ }
33
+
34
+ export interface FunctionNetworkingEvents extends EventNetworkingEvents {
35
+ onBadResponse: (player: Player, data: BadResponseData) => void;
36
+ }
package/out/index.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { GlobalEvent } from "./events/types";
2
+ import { GlobalFunction } from "./functions/types";
3
+ import { Skip as NetworkingSkip } from "./middleware/skip";
4
+ import { NetworkingFunctionError } from "./function/errors";
5
+ import { EventMiddleware as _EventMiddleware, FunctionMiddleware as _FunctionMiddleware } from "./middleware/types";
6
+ import { NetworkRaw, NetworkUnreliable } from "./types";
7
+ import type { Modding } from "@flamework-experimental/core";
8
+ export declare namespace Networking {
9
+ /**
10
+ * Creates a new event based off the supplied types.
11
+ * @param serverMiddleware Middleware for server events
12
+ * @param clientMiddleware Middleware for client events
13
+ * @metadata macro
14
+ */
15
+ function createEvent<S, C>(name?: Modding.Caller.Uuid): GlobalEvent<S, C>;
16
+ /**
17
+ * Creates a new function event based off the supplied types.
18
+ * @param serverMiddleware Middleware for server events
19
+ * @param clientMiddleware Middleware for client events
20
+ * @metadata macro
21
+ */
22
+ function createFunction<S, C>(name?: Modding.Caller.Uuid): GlobalFunction<S, C>;
23
+ /**
24
+ * Stops networking function middleware.
25
+ */
26
+ const Skip: NetworkingSkip;
27
+ /**
28
+ * Specifies that this event is unreliable.
29
+ *
30
+ * This will only work on remote events.
31
+ */
32
+ type Unreliable<T> = NetworkUnreliable<T>;
33
+ /**
34
+ * Sends this event's arguments as they are, bypassing `networking.serialization` for this event
35
+ * alone. The generated guards still run on what arrives.
36
+ */
37
+ type RawReliable<T> = NetworkRaw<T>;
38
+ /**
39
+ * An unreliable event whose arguments bypass serialization; see {@link RawReliable}.
40
+ */
41
+ type RawUnreliable<T> = NetworkUnreliable<NetworkRaw<T>>;
42
+ /**
43
+ * A function whose requests and results bypass serialization; see {@link RawReliable}.
44
+ */
45
+ type Raw<T> = NetworkRaw<T>;
46
+ /**
47
+ * A function that generates an event middleware.
48
+ */
49
+ type EventMiddleware<I extends readonly unknown[] = unknown[]> = _EventMiddleware<I>;
50
+ /**
51
+ * A function that generates an event middleware.
52
+ */
53
+ type FunctionMiddleware<I extends readonly unknown[] = unknown[], O = void> = _FunctionMiddleware<I, O>;
54
+ }
55
+ export { NetworkingFunctionError };