@axpecter/lync 2.0.0 → 2.1.1

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 (55) hide show
  1. package/README.md +342 -428
  2. package/package.json +1 -1
  3. package/src/Types.luau +63 -31
  4. package/src/api/Group.luau +101 -106
  5. package/src/api/Packet.luau +187 -186
  6. package/src/api/Query.luau +223 -284
  7. package/src/api/Scope.luau +46 -57
  8. package/src/api/Signal.luau +104 -137
  9. package/src/codec/Base.luau +69 -20
  10. package/src/codec/composite/Array.luau +179 -270
  11. package/src/codec/composite/Map.luau +97 -347
  12. package/src/codec/composite/Optional.luau +27 -24
  13. package/src/codec/composite/Shared.luau +96 -65
  14. package/src/codec/composite/Struct.luau +200 -360
  15. package/src/codec/composite/Tagged.luau +62 -187
  16. package/src/codec/composite/Tuple.luau +79 -103
  17. package/src/codec/datatype/Buffer.luau +49 -21
  18. package/src/codec/datatype/CFrame.luau +207 -30
  19. package/src/codec/datatype/Color.luau +21 -11
  20. package/src/codec/datatype/Instance.luau +28 -21
  21. package/src/codec/datatype/IntVector.luau +33 -21
  22. package/src/codec/datatype/NumberRange.luau +19 -10
  23. package/src/codec/datatype/Ray.luau +26 -22
  24. package/src/codec/datatype/Rect.luau +20 -16
  25. package/src/codec/datatype/Region.luau +51 -45
  26. package/src/codec/datatype/Sequence.luau +64 -56
  27. package/src/codec/datatype/String.luau +89 -56
  28. package/src/codec/datatype/UDim.luau +40 -22
  29. package/src/codec/datatype/Vector.luau +181 -17
  30. package/src/codec/meta/Auto.luau +295 -253
  31. package/src/codec/meta/Bitfield.luau +104 -148
  32. package/src/codec/meta/Custom.luau +8 -4
  33. package/src/codec/meta/Enum.luau +29 -57
  34. package/src/codec/meta/Float.luau +64 -0
  35. package/src/codec/meta/Nothing.luau +9 -5
  36. package/src/codec/meta/Unknown.luau +44 -36
  37. package/src/codec/primitive/Bool.luau +16 -26
  38. package/src/codec/primitive/Float16.luau +58 -64
  39. package/src/codec/primitive/Int.luau +68 -0
  40. package/src/codec/primitive/Number.luau +21 -43
  41. package/src/codec/primitive/Varint.luau +67 -46
  42. package/src/index.d.ts +251 -335
  43. package/src/init.luau +319 -207
  44. package/src/internal/Baseline.luau +29 -24
  45. package/src/internal/Channel.luau +333 -278
  46. package/src/internal/Middleware.luau +60 -85
  47. package/src/internal/Pool.luau +19 -30
  48. package/src/internal/Registry.luau +56 -113
  49. package/src/transport/Bridge.luau +64 -43
  50. package/src/transport/Client.luau +59 -170
  51. package/src/transport/Gate.luau +282 -142
  52. package/src/transport/Reader.luau +148 -140
  53. package/src/transport/Server.luau +138 -488
  54. package/src/api/Namespace.luau +0 -256
  55. package/src/codec/meta/Quantized.luau +0 -174
package/src/index.d.ts CHANGED
@@ -1,347 +1,263 @@
1
- // Type declarations for Lync networking library.
1
+ /// <reference types="@rbxts/types" />
2
2
 
3
- // -- Utility types -----------------------------------------------------
4
-
5
- // Expands mapped types in hover tooltips.
6
- type Prettify<T> = { [K in keyof T]: T[K] } & {};
7
-
8
- // -- Codec -------------------------------------------------------------
9
-
10
- // Opaque codec handle. Carries the serialized type at the type level.
11
- export interface Codec<T> {
12
- /** @hidden @deprecated Do not use. Only for type metadata. */
13
- readonly _nominal_Codec: T;
14
- }
15
-
16
- // Extracts the value type from a codec.
17
- export type InferCodec<C> = C extends Codec<infer T> ? T : never;
18
-
19
- // Maps a record of codecs to a record of their value types.
20
- type InferSchema<S extends Record<string, Codec<unknown>>> = Prettify<{
21
- [K in keyof S]: InferCodec<S[K]>;
22
- }>;
23
-
24
- // Maps a tuple of codecs to a tuple of their value types.
25
- type InferTuple<T extends readonly Codec<unknown>[]> = {
26
- [K in keyof T]: InferCodec<T[K]>;
27
- };
28
-
29
- // Infers the discriminated union from a tagged variant map.
30
- type InferTagged<
31
- Tag extends string,
32
- V extends Record<string, Codec<unknown>>,
33
- > = {
34
- [K in keyof V & string]: Prettify<InferCodec<V[K]> & { [T in Tag]: K }>;
35
- }[keyof V & string];
36
-
37
- // -- Connection --------------------------------------------------------
38
-
39
- export interface Connection {
40
- readonly connected: boolean;
41
- disconnect(this: Connection): void;
42
- }
43
-
44
- // -- Config ------------------------------------------------------------
45
-
46
- export interface RateLimitConfig {
47
- maxPerSecond: number;
48
- burstAllowance?: number;
49
- }
50
-
51
- export interface BoolFieldSpec {
52
- type: "bool";
53
- }
54
-
55
- export interface UintFieldSpec {
56
- type: "uint";
57
- width: number;
58
- }
59
-
60
- export interface IntFieldSpec {
61
- type: "int";
62
- width: number;
63
- }
64
-
65
- export type FieldSpec = BoolFieldSpec | UintFieldSpec | IntFieldSpec;
66
-
67
- type InferFieldSpec<F extends FieldSpec> = F extends BoolFieldSpec
68
- ? boolean
69
- : number;
70
-
71
- type InferBitfield<S extends Record<string, FieldSpec>> = Prettify<{
72
- [K in keyof S]: InferFieldSpec<S[K]>;
73
- }>;
74
-
75
- // -- Target descriptors ------------------------------------------------
76
-
77
- export interface AllTarget {
78
- readonly _tag: "all";
79
- }
80
-
81
- export interface ExceptTarget {
82
- readonly _tag: "except";
83
- readonly _set: ReadonlyMap<Player, true>;
84
- }
85
-
86
- export interface GroupObject {
87
- readonly _tag: "group";
88
- add(this: GroupObject, player: Player): boolean;
89
- remove(this: GroupObject, player: Player): boolean;
90
- has(this: GroupObject, player: Player): boolean;
91
- count(this: GroupObject): number;
92
- forEach(this: GroupObject, fn: (player: Player) => void): void;
93
- getSet(this: GroupObject): ReadonlyMap<Player, true>;
94
- destroy(this: GroupObject): void;
95
- }
96
-
97
- export type Target = Player | AllTarget | ExceptTarget | GroupObject | Player[];
98
-
99
- // -- Scope -------------------------------------------------------------
100
-
101
- export interface Scope {
102
- add(this: Scope, conn: Connection | RBXScriptConnection): void;
103
- listen<T>(this: Scope, source: Packet<T>, callback: (data: T, sender: Player | undefined, timestamp: number | undefined) => void): void;
104
- once<T>(this: Scope, source: Packet<T>, callback: (data: T, sender: Player | undefined, timestamp: number | undefined) => void): void;
105
- listenAll(this: Scope, namespace: Namespace, callback: (name: string, data: unknown, sender: Player | undefined, timestamp: number | undefined) => void): void;
106
- destroy(this: Scope): void;
107
- }
108
-
109
- // -- DROP sentinel -----------------------------------------------------
110
-
111
- export interface DropSentinel {
112
- readonly _tag: "drop";
113
- }
114
-
115
- // -- Packet ------------------------------------------------------------
116
-
117
- export interface PacketConfig<T> {
118
- value: Codec<T>;
119
- unreliable?: boolean;
120
- rateLimit?: RateLimitConfig;
121
- validate?: (data: T, player: Player) => LuaTuple<[boolean, string?]>;
122
- maxPayloadBytes?: number;
123
- timestamp?: "frame" | "offset" | "full";
124
- }
125
-
126
- export interface PlayerStats {
127
- bytesSent: number;
128
- bytesReceived: number;
129
- }
130
-
131
- export interface Packet<T> {
132
- send(this: Packet<T>, data: T, target?: Target): void;
133
- listen(this: Packet<T>, callback: (data: T, sender: Player | undefined, timestamp: number | undefined) => void): Connection;
134
- once(this: Packet<T>, callback: (data: T, sender: Player | undefined, timestamp: number | undefined) => void): Connection;
135
- wait(this: Packet<T>): LuaTuple<[T, Player | undefined]>;
136
- disconnectAll(this: Packet<T>): void;
137
-
138
- getBytesSent(this: Packet<T>): number;
139
- getBytesReceived(this: Packet<T>): number;
140
- getFires(this: Packet<T>): number;
141
- getRecvFires(this: Packet<T>): number;
142
- getDrops(this: Packet<T>): number;
143
- }
144
-
145
- // -- Query -------------------------------------------------------------
146
-
147
- export interface QueryConfig<Req, Resp> {
148
- request: Codec<Req>;
149
- response: Codec<Resp>;
150
- timeout?: number;
151
- rateLimit?: RateLimitConfig;
152
- validate?: (data: Req, player: Player) => LuaTuple<[boolean, string?]>;
153
- }
154
-
155
- export interface Query<Req, Resp> {
156
- listen(
157
- this: Query<Req, Resp>,
158
- callback: (request: Req, player: Player) => Resp | undefined,
159
- ): Connection;
160
- request(this: Query<Req, Resp>, data: Req): Resp | undefined;
161
- requestFrom(this: Query<Req, Resp>, player: Player, data: Req): Resp | undefined;
162
- requestAll(this: Query<Req, Resp>, data: Req): Map<Player, Resp | undefined>;
163
- requestList(
164
- this: Query<Req, Resp>,
165
- players: Player[],
166
- data: Req,
167
- ): Map<Player, Resp | undefined>;
168
- requestGroup(
169
- this: Query<Req, Resp>,
170
- group: GroupObject,
171
- data: Req,
172
- ): Map<Player, Resp | undefined>;
3
+ declare namespace Lync {
4
+ // ── Core Types ──────────────────────────────────────────────────
5
+
6
+ interface Codec<T> {
7
+ /** @hidden */ readonly _nominal_codec: T;
8
+ }
9
+
10
+ interface Connection {
11
+ connected: boolean;
12
+ disconnect(): void;
13
+ }
14
+
15
+ interface PacketStats {
16
+ bytesSent: number;
17
+ bytesReceived: number;
18
+ fires: number;
19
+ recvFires: number;
20
+ drops: number;
21
+ }
22
+
23
+ interface PlayerStats {
24
+ bytesSent: number;
25
+ bytesReceived: number;
26
+ }
27
+
28
+ // ── Packet ──────────────────────────────────────────────────────
29
+
30
+ interface PacketOptions<T> {
31
+ unreliable?: boolean;
32
+ rateLimit?: { maxPerSecond?: number; burst?: number } | { cooldown: number };
33
+ validate?: (data: T, player: Player) => LuaTuple<[boolean, string?]>;
34
+ maxPayloadBytes?: number;
35
+ timestamp?: "frame" | "offset" | "full";
36
+ }
37
+
38
+ interface Packet<T> {
39
+ send(this: Packet<T>, data: T, target?: Target): void;
40
+ on(this: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
41
+ once(this: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
42
+ wait(this: Packet<T>): LuaTuple<[T, Player?, number?]>;
43
+ name(this: Packet<T>): string;
44
+ stats(this: Packet<T>): PacketStats;
45
+ }
46
+
47
+ // ── Query ───────────────────────────────────────────────────────
48
+
49
+ interface QueryOptions<Req> {
50
+ timeout?: number;
51
+ rateLimit?: { maxPerSecond?: number; burst?: number };
52
+ validate?: (data: Req, player: Player) => LuaTuple<[boolean, string?]>;
53
+ }
54
+
55
+ interface Query<Req, Resp> {
56
+ handle(this: Query<Req, Resp>, fn: (request: Req, player?: Player) => Resp | undefined): Connection;
57
+ request(this: Query<Req, Resp>, data: Req): Resp | undefined;
58
+ request(this: Query<Req, Resp>, data: Req, target: Player): Resp | undefined;
59
+ request(this: Query<Req, Resp>, data: Req, target: Target): Map<Player, Resp | undefined>;
60
+ name(this: Query<Req, Resp>): string;
61
+ stats(this: Query<Req, Resp>): PacketStats;
62
+ }
63
+
64
+ // ── Group ───────────────────────────────────────────────────────
65
+
66
+ interface Group extends Iterable<Player> {
67
+ add(this: Group, player: Player): boolean;
68
+ remove(this: Group, player: Player): boolean;
69
+ has(this: Group, player: Player): boolean;
70
+ count(this: Group): number;
71
+ destroy(this: Group): void;
72
+ }
73
+
74
+ // ── Scope ───────────────────────────────────────────────────────
75
+
76
+ interface Scope {
77
+ on<T>(this: Scope, source: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
78
+ once<T>(this: Scope, source: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
79
+ add(this: Scope, connection: Connection | RBXScriptConnection): void;
80
+ destroy(this: Scope): void;
81
+ }
82
+
83
+ // ── Targets ─────────────────────────────────────────────────────
84
+
85
+ type Target = Player | Player[] | Group | AllTarget | ExceptTarget;
86
+
87
+ interface AllTarget {
88
+ /** @hidden */ readonly _lyncAll: true;
89
+ }
90
+
91
+ interface ExceptTarget {
92
+ /** @hidden */ readonly _lyncExcept: true;
93
+ }
94
+
95
+ // ── Codec Inference ─────────────────────────────────────────────
96
+
97
+ type InferCodec<C> = C extends Codec<infer T> ? T : never;
98
+
99
+ type InferSchema<S extends Record<string, Codec<unknown>>> = {
100
+ [K in keyof S]: InferCodec<S[K]>;
101
+ };
102
+
103
+ // ── Callable Codecs ─────────────────────────────────────────────
104
+
105
+ interface StringCodec extends Codec<string> {
106
+ (maxLength: number): Codec<string>;
107
+ }
108
+
109
+ interface Vec2Codec extends Codec<Vector2> {
110
+ (min: number, max: number, precision: number): Codec<Vector2>;
111
+ }
112
+
113
+ interface Vec3Codec extends Codec<Vector3> {
114
+ (min: number, max: number, precision: number): Codec<Vector3>;
115
+ }
116
+
117
+ interface CFrameCodec extends Codec<CFrame> {
118
+ (): Codec<CFrame>;
119
+ }
120
+
121
+ // ── Configure ───────────────────────────────────────────────────
122
+
123
+ interface ConfigureOptions {
124
+ channelMaxSize?: number;
125
+ validationDepth?: number;
126
+ poolSize?: number;
127
+ bandwidthLimit?: { softLimit: number; maxStrikes: number };
128
+ globalRateLimit?: { maxPerSecond: number };
129
+ stats?: boolean;
130
+ }
131
+
132
+ // ── Drop Sentinel ───────────────────────────────────────────────
133
+
134
+ interface DropSentinel {
135
+ /** @hidden */ readonly _lyncDrop: true;
136
+ }
173
137
  }
174
138
 
175
- // -- Namespace ---------------------------------------------------------
139
+ interface LyncModule {
140
+ // ── Lifecycle ────────────────────────────────────────────────────
176
141
 
177
- export interface NamespaceConfig {
178
- packets?: Record<string, PacketConfig<unknown>>;
179
- queries?: Record<string, QueryConfig<unknown, unknown>>;
180
- }
181
-
182
- type InferPackets<P extends Record<string, PacketConfig<unknown>>> = {
183
- [K in keyof P]: P[K] extends PacketConfig<infer T> ? Packet<T> : never;
184
- };
185
-
186
- type InferQueries<Q extends Record<string, QueryConfig<unknown, unknown>>> = {
187
- [K in keyof Q]: Q[K] extends QueryConfig<infer Req, infer Resp>
188
- ? Query<Req, Resp>
189
- : never;
190
- };
191
-
192
- export interface Namespace {
193
- readonly packets: Record<string, Packet<unknown>>;
194
- readonly queries: Record<string, Query<unknown, unknown>>;
195
- listenAll(
196
- this: Namespace,
197
- callback: (name: string, data: unknown, sender: Player | undefined, timestamp: number | undefined) => void,
198
- ): Connection;
199
- onSend(
200
- this: Namespace,
201
- handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
202
- ): () => void;
203
- onReceive(
204
- this: Namespace,
205
- handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
206
- ): () => void;
207
- disconnectAll(this: Namespace): void;
208
- destroy(this: Namespace): void;
209
- packetNames(this: Namespace): string[];
210
- queryNames(this: Namespace): string[];
211
- }
142
+ configure(this: void, options: Lync.ConfigureOptions): void;
143
+ start(this: void): void;
144
+ readonly started: boolean;
212
145
 
213
- // -- Lync --------------------------------------------------------------
146
+ // ── Definitions ─────────────────────────────────────────────────
214
147
 
215
- declare namespace Lync {
216
- // Lifecycle
217
- export const VERSION: string;
218
- export function start(): void;
148
+ packet<T>(this: void, name: string, codec: Lync.Codec<T>, options?: Lync.PacketOptions<T>): Lync.Packet<T>;
219
149
 
220
- // Definition
221
- export function definePacket<T>(name: string, config: PacketConfig<T>): Packet<T>;
222
- export function defineQuery<Req, Resp>(
150
+ query<Req, Resp>(
151
+ this: void,
223
152
  name: string,
224
- config: QueryConfig<Req, Resp>,
225
- ): Query<Req, Resp>;
226
- export function defineNamespace<
227
- P extends Record<string, PacketConfig<unknown>> = {},
228
- Q extends Record<string, QueryConfig<unknown, unknown>> = {},
229
- >(
230
- name: string,
231
- config: { packets?: P; queries?: Q },
232
- ): Namespace & InferPackets<P> & InferQueries<Q>;
233
-
234
- // Primitives
235
- export const u8: Codec<number>;
236
- export const u16: Codec<number>;
237
- export const u32: Codec<number>;
238
- export const i8: Codec<number>;
239
- export const i16: Codec<number>;
240
- export const i32: Codec<number>;
241
- export const f32: Codec<number>;
242
- export const f64: Codec<number>;
243
- export const bool: Codec<boolean>;
244
- export const f16: Codec<number>;
245
-
246
- // Datatypes
247
- const string: Codec<string>;
248
- export { string };
249
- export const vec2: Codec<Vector2>;
250
- export const vec3: Codec<Vector3>;
251
- export const cframe: Codec<CFrame>;
252
- export const color3: Codec<Color3>;
253
- export const inst: Codec<Instance>;
254
- export const buff: Codec<buffer>;
255
- export const udim: Codec<UDim>;
256
- export const udim2: Codec<UDim2>;
257
- export const numberRange: Codec<NumberRange>;
258
- export const rect: Codec<Rect>;
259
- export const vec2int16: Codec<Vector2int16>;
260
- export const vec3int16: Codec<Vector3int16>;
261
- export const region3: Codec<Region3>;
262
- export const region3int16: Codec<Region3int16>;
263
- export const ray: Codec<Ray>;
264
- export const numberSequence: Codec<NumberSequence>;
265
- export const colorSequence: Codec<ColorSequence>;
266
-
267
- // Composites
268
- export function struct<S extends Record<string, Codec<unknown>>>(schema: S): Codec<InferSchema<S>>;
269
- export function deltaStruct<S extends Record<string, Codec<unknown>>>(schema: S): Codec<InferSchema<S>>;
270
- export function array<T>(element: Codec<T>, maxCount?: number): Codec<T[]>;
271
- export function deltaArray<T>(element: Codec<T>, maxCount?: number): Codec<T[]>;
272
- export function map<K extends defined, V>(key: Codec<K>, value: Codec<V>, maxCount?: number): Codec<Map<K, V>>;
273
- export function deltaMap<K extends defined, V>(key: Codec<K>, value: Codec<V>, maxCount?: number): Codec<Map<K, V>>;
274
- export function optional<T>(inner: Codec<T>): Codec<T | undefined>;
275
-
276
- // Meta
277
- function _enum<T extends string>(...values: T[]): Codec<T>;
278
- export { _enum as enum };
279
- export function quantizedFloat(min: number, max: number, precision: number): Codec<number>;
280
- export function quantizedVec3(min: number, max: number, precision: number): Codec<Vector3>;
281
- export function bitfield<S extends Record<string, FieldSpec>>(schema: S): Codec<InferBitfield<S>>;
282
- export function tagged<Tag extends string, V extends Record<string, Codec<unknown>>>(
153
+ requestCodec: Lync.Codec<Req>,
154
+ responseCodec: Lync.Codec<Resp>,
155
+ options?: Lync.QueryOptions<Req>,
156
+ ): Lync.Query<Req, Resp>;
157
+
158
+ group(this: void, name: string): Lync.Group;
159
+ scope(this: void): Lync.Scope;
160
+
161
+ // ── Targeting ───────────────────────────────────────────────────
162
+
163
+ readonly all: Lync.AllTarget;
164
+ except(this: void, ...args: Array<Player | Lync.Group>): Lync.ExceptTarget;
165
+ readonly DROP: Lync.DropSentinel;
166
+
167
+ // ── Middleware ───────────────────────────────────────────────────
168
+
169
+ onSend(this: void, fn: (data: unknown, name: string, player?: Player) => unknown): Lync.Connection;
170
+ onReceive(this: void, fn: (data: unknown, name: string, player?: Player) => unknown): Lync.Connection;
171
+ onDrop(this: void, fn: (player: Player, reason: string, name: string, data?: unknown) => void): Lync.Connection;
172
+
173
+ // ── Runtime Control ─────────────────────────────────────────────
174
+
175
+ flush(this: void): void;
176
+ flushRate(this: void, hz: number): void;
177
+
178
+ // ── Stats ───────────────────────────────────────────────────────
179
+
180
+ readonly stats: {
181
+ player(this: void, player: Player): Lync.PlayerStats | undefined;
182
+ reset(this: void): void;
183
+ };
184
+
185
+ // ── Debug ───────────────────────────────────────────────────────
186
+
187
+ readonly debug: {
188
+ capture(this: void, label?: string): void;
189
+ stop(this: void): void;
190
+ dump(this: void): void;
191
+ pending(this: void): number;
192
+ registrations(this: void): ReadonlyArray<{
193
+ name: string;
194
+ id: number;
195
+ kind: number;
196
+ isUnreliable: boolean;
197
+ }>;
198
+ };
199
+
200
+ // ── Number Codecs ───────────────────────────────────────────────
201
+
202
+ int(this: void, min: number, max: number): Lync.Codec<number>;
203
+ float(this: void, min: number, max: number, precision: number): Lync.Codec<number>;
204
+ readonly f16: Lync.Codec<number>;
205
+ readonly f32: Lync.Codec<number>;
206
+ readonly f64: Lync.Codec<number>;
207
+ readonly bool: Lync.Codec<boolean>;
208
+
209
+ // ── String & Buffer ─────────────────────────────────────────────
210
+
211
+ readonly string: Lync.StringCodec;
212
+ readonly buff: Lync.Codec<buffer>;
213
+
214
+ // ── Vectors & Spatial ───────────────────────────────────────────
215
+
216
+ readonly vec2: Lync.Vec2Codec;
217
+ readonly vec3: Lync.Vec3Codec;
218
+ readonly cframe: Lync.CFrameCodec;
219
+ readonly ray: Lync.Codec<Ray>;
220
+ readonly rect: Lync.Codec<Rect>;
221
+ readonly region3: Lync.Codec<Region3>;
222
+ readonly region3int16: Lync.Codec<Region3int16>;
223
+ readonly vec2int16: Lync.Codec<Vector2int16>;
224
+ readonly vec3int16: Lync.Codec<Vector3int16>;
225
+
226
+ // ── Roblox Types ────────────────────────────────────────────────
227
+
228
+ readonly color3: Lync.Codec<Color3>;
229
+ readonly inst: Lync.Codec<Instance>;
230
+ readonly udim: Lync.Codec<UDim>;
231
+ readonly udim2: Lync.Codec<UDim2>;
232
+ readonly numberRange: Lync.Codec<NumberRange>;
233
+ readonly numberSequence: Lync.Codec<NumberSequence>;
234
+ readonly colorSequence: Lync.Codec<ColorSequence>;
235
+
236
+ // ── Composites ──────────────────────────────────────────────────
237
+
238
+ struct<S extends Record<string, Lync.Codec<unknown>>>(this: void, schema: S): Lync.Codec<Lync.InferSchema<S>>;
239
+ deltaStruct<S extends Record<string, Lync.Codec<unknown>>>(this: void, schema: S): Lync.Codec<Lync.InferSchema<S>>;
240
+ array<T>(this: void, element: Lync.Codec<T>, maxCount?: number): Lync.Codec<T[]>;
241
+ deltaArray<T>(this: void, element: Lync.Codec<T>, maxCount?: number): Lync.Codec<T[]>;
242
+ map<K, V>(this: void, keyCodec: Lync.Codec<K>, valueCodec: Lync.Codec<V>, maxCount?: number): Lync.Codec<Map<K, V>>;
243
+ deltaMap<K, V>(this: void, keyCodec: Lync.Codec<K>, valueCodec: Lync.Codec<V>, maxCount?: number): Lync.Codec<Map<K, V>>;
244
+ optional<T>(this: void, codec: Lync.Codec<T>): Lync.Codec<T | undefined>;
245
+ tuple<T extends Lync.Codec<unknown>[]>(this: void, ...codecs: T): Lync.Codec<{ [K in keyof T]: Lync.InferCodec<T[K]> }>;
246
+ tagged<Tag extends string, V extends Record<string, Lync.Codec<unknown>>>(
247
+ this: void,
283
248
  tagField: Tag,
284
249
  variants: V,
285
- ): Codec<InferTagged<Tag, V>>;
286
- export function tuple<T extends Codec<unknown>[]>(...codecs: T): Codec<InferTuple<T>>;
287
- export function custom<T>(
288
- size: number,
289
- write: (b: buffer, offset: number, value: T) => void,
290
- read: (b: buffer, offset: number) => T,
291
- ): Codec<T>;
292
- export function boundedString(maxLength: number): Codec<string>;
293
- export const nothing: Codec<undefined>;
294
- export const unknown: Codec<unknown>;
295
- export const auto: Codec<unknown>;
296
-
297
- // Hooks
298
- export function onDrop(
299
- callback: (player: Player, reason: string, packetName: string, data: unknown) => void,
300
- ): () => void;
301
- export function onSend(
302
- handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
303
- ): () => void;
304
- export function onReceive(
305
- handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
306
- ): () => void;
307
-
308
- // Target descriptors
309
- export const all: AllTarget;
310
- export function except(...players: Player[]): ExceptTarget;
311
-
312
- // Middleware sentinel
313
- export const DROP: DropSentinel;
314
-
315
- // Groups
316
- export function createGroup(name: string): GroupObject;
317
-
318
- // Scope
319
- export function scope(): Scope;
320
-
321
- // Configuration (call before start)
322
- export function setChannelMaxSize(bytes: number): void;
323
- export function setValidationDepth(depth: number): void;
324
- export function setPoolSize(count: number): void;
325
-
326
- // Runtime configuration
327
- export function flush(): void;
328
- export function setFlushRate(hz: number): void;
329
-
330
- // Stats (default off; call enableStats() to activate)
331
- export function enableStats(): void;
332
- export function getPlayerStats(player: Player): PlayerStats | undefined;
333
- export function resetStats(): void;
334
-
335
- // Security (server-only)
336
- export function setBandwidthLimit(softLimit: number, maxStrikes: number): void;
337
-
338
- // Introspection
339
- export function queryPendingCount(): number;
340
-
341
- // Packet capture (server-only, debug)
342
- export function startCapture(label?: string): void;
343
- export function stopCapture(): void;
344
- export function dumpCaptures(): void;
250
+ ): Lync.Codec<{ [K in keyof V]: Lync.InferSchema<{ [F in Tag]: K }> & Lync.InferCodec<V[K]> }[keyof V]>;
251
+
252
+ // ── Meta ────────────────────────────────────────────────────────
253
+
254
+ enum<T extends string[]>(this: void, ...values: T): Lync.Codec<T[number]>;
255
+ bitfield(this: void, schema: Record<string, { type: "bool" } | { type: "uint"; width: number } | { type: "int"; width: number }>): Lync.Codec<Record<string, boolean | number>>;
256
+ custom<T>(this: void, size: number, write: (b: buffer, offset: number, value: T) => void, read: (b: buffer, offset: number) => T): Lync.Codec<T>;
257
+ readonly nothing: Lync.Codec<undefined>;
258
+ readonly unknown: Lync.Codec<unknown>;
259
+ readonly auto: Lync.Codec<unknown>;
345
260
  }
346
261
 
347
- export default Lync;
262
+ declare const Lync: LyncModule;
263
+ export = Lync;