@axpecter/lync 2.3.3 → 3.0.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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +302 -299
  3. package/Types.luau +215 -0
  4. package/api/Define.luau +154 -0
  5. package/api/Lifecycle.luau +119 -0
  6. package/api/Packet.luau +108 -0
  7. package/api/Query.luau +149 -0
  8. package/api/Set.luau +189 -0
  9. package/channel/Blocks.luau +124 -0
  10. package/channel/Group.luau +118 -0
  11. package/channel/Link.luau +135 -0
  12. package/channel/Outbox.luau +261 -0
  13. package/channel/Recipients.luau +129 -0
  14. package/channel/Transport.luau +138 -0
  15. package/codec/Base.luau +236 -0
  16. package/codec/Composites.luau +128 -0
  17. package/codec/Datatypes.luau +162 -0
  18. package/codec/Legality.luau +61 -0
  19. package/codec/Scalars.luau +72 -0
  20. package/codec/Text.luau +89 -0
  21. package/codec/init.luau +39 -0
  22. package/index.d.ts +285 -0
  23. package/init.luau +91 -0
  24. package/kernel/Bits.luau +16 -0
  25. package/kernel/Catalog.luau +121 -0
  26. package/kernel/Heap.luau +80 -0
  27. package/kernel/Listeners.luau +95 -0
  28. package/kernel/Log.luau +197 -0
  29. package/kernel/Tally.luau +128 -0
  30. package/kernel/Threads.luau +44 -0
  31. package/kernel/Wide.luau +267 -0
  32. package/package.json +15 -32
  33. package/runtime/Boundary.luau +180 -0
  34. package/runtime/Dispatch.luau +91 -0
  35. package/runtime/Handles.luau +114 -0
  36. package/runtime/Handshake.luau +90 -0
  37. package/runtime/Pending.luau +196 -0
  38. package/runtime/Router.luau +379 -0
  39. package/runtime/Session.luau +731 -0
  40. package/shape/Compile.luau +340 -0
  41. package/shape/Folds.luau +332 -0
  42. package/shape/Frames.luau +170 -0
  43. package/shape/Grid.luau +169 -0
  44. package/shape/Ir.luau +540 -0
  45. package/shape/Joins.luau +125 -0
  46. package/shape/Legality.luau +273 -0
  47. package/shape/Lower.luau +419 -0
  48. package/shape/Order.luau +64 -0
  49. package/shape/Regions.luau +113 -0
  50. package/shape/Rotation.luau +472 -0
  51. package/shape/Serial.luau +258 -0
  52. package/shape/Words.luau +89 -0
  53. package/shape/emit/Block.luau +453 -0
  54. package/shape/emit/Column.luau +338 -0
  55. package/shape/emit/Leaf.luau +462 -0
  56. package/shape/emit/Word.luau +234 -0
  57. package/shape/emit/init.luau +222 -0
  58. package/shape/init.luau +78 -0
  59. package/state/Apply.luau +330 -0
  60. package/state/Audience.luau +126 -0
  61. package/state/Catchup.luau +218 -0
  62. package/state/Coalesce.luau +43 -0
  63. package/state/Fieldset.luau +177 -0
  64. package/state/Newest.luau +339 -0
  65. package/state/Plan.luau +441 -0
  66. package/state/Sections.luau +468 -0
  67. package/state/Store.luau +188 -0
  68. package/state/Sync.luau +762 -0
  69. package/wire/Bytes.luau +118 -0
  70. package/wire/Clock.luau +37 -0
  71. package/wire/Protocol.luau +110 -0
  72. package/wire/Sequence.luau +40 -0
  73. package/wire/Varint.luau +124 -0
  74. package/src/Types.luau +0 -180
  75. package/src/api/Group.luau +0 -156
  76. package/src/api/Packet.luau +0 -317
  77. package/src/api/Query.luau +0 -338
  78. package/src/api/Scope.luau +0 -90
  79. package/src/api/Signal.luau +0 -193
  80. package/src/codec/Base.luau +0 -136
  81. package/src/codec/composite/Array.luau +0 -473
  82. package/src/codec/composite/Map.luau +0 -485
  83. package/src/codec/composite/Optional.luau +0 -54
  84. package/src/codec/composite/Shared.luau +0 -311
  85. package/src/codec/composite/Struct.luau +0 -494
  86. package/src/codec/composite/Tagged.luau +0 -103
  87. package/src/codec/composite/Tuple.luau +0 -143
  88. package/src/codec/datatype/Buffer.luau +0 -66
  89. package/src/codec/datatype/CFrame.luau +0 -109
  90. package/src/codec/datatype/Color.luau +0 -32
  91. package/src/codec/datatype/Instance.luau +0 -52
  92. package/src/codec/datatype/IntVector.luau +0 -39
  93. package/src/codec/datatype/NumberRange.luau +0 -39
  94. package/src/codec/datatype/Ray.luau +0 -36
  95. package/src/codec/datatype/Rect.luau +0 -31
  96. package/src/codec/datatype/Region.luau +0 -62
  97. package/src/codec/datatype/Sequence.luau +0 -184
  98. package/src/codec/datatype/String.luau +0 -94
  99. package/src/codec/datatype/UDim.luau +0 -46
  100. package/src/codec/datatype/Vector.luau +0 -130
  101. package/src/codec/meta/Auto.luau +0 -318
  102. package/src/codec/meta/Bitfield.luau +0 -160
  103. package/src/codec/meta/Custom.luau +0 -33
  104. package/src/codec/meta/DeltaScalar.luau +0 -390
  105. package/src/codec/meta/Enum.luau +0 -50
  106. package/src/codec/meta/Float.luau +0 -38
  107. package/src/codec/meta/Nothing.luau +0 -13
  108. package/src/codec/meta/Unknown.luau +0 -41
  109. package/src/codec/primitive/Bool.luau +0 -26
  110. package/src/codec/primitive/Float16.luau +0 -99
  111. package/src/codec/primitive/Int.luau +0 -59
  112. package/src/codec/primitive/Number.luau +0 -24
  113. package/src/codec/primitive/Signed.luau +0 -32
  114. package/src/codec/primitive/Varint.luau +0 -165
  115. package/src/codec/primitive/Zint.luau +0 -99
  116. package/src/index.d.ts +0 -423
  117. package/src/init.luau +0 -362
  118. package/src/internal/Baseline.luau +0 -57
  119. package/src/internal/Channel.luau +0 -484
  120. package/src/internal/Middleware.luau +0 -100
  121. package/src/internal/Pool.luau +0 -66
  122. package/src/internal/Registry.luau +0 -119
  123. package/src/internal/Transport.luau +0 -28
  124. package/src/transport/Bridge.luau +0 -110
  125. package/src/transport/Client.luau +0 -97
  126. package/src/transport/Gate.luau +0 -488
  127. package/src/transport/Reader.luau +0 -331
  128. package/src/transport/Server.luau +0 -233
  129. package/src/util/Array.luau +0 -18
  130. package/src/util/Buffer.luau +0 -90
  131. package/src/util/Constants.luau +0 -30
  132. package/src/util/Log.luau +0 -68
  133. package/src/util/Player.luau +0 -14
  134. package/src/util/Quantize.luau +0 -84
  135. package/src/util/Quat.luau +0 -124
package/src/init.luau DELETED
@@ -1,362 +0,0 @@
1
- --!strict
2
- --!optimize 2
3
- -- Lync: buffer networking for Roblox.
4
-
5
- local RunService = game:GetService("RunService")
6
-
7
- local Baseline = require(script.internal.Baseline)
8
- local Bridge = require(script.transport.Bridge)
9
- local Channel = require(script.internal.Channel)
10
- local Gate = require(script.transport.Gate)
11
- local Group = require(script.api.Group)
12
- local Log = require(script.util.Log)
13
- local Middleware = require(script.internal.Middleware)
14
- local Packet = require(script.api.Packet)
15
- local Player = require(script.util.Player)
16
- local Pool = require(script.internal.Pool)
17
- local Query = require(script.api.Query)
18
- local Registry = require(script.internal.Registry)
19
- local Scope = require(script.api.Scope)
20
- local Types = require(script.Types)
21
-
22
- local ArrayC = require(script.codec.composite.Array)
23
- local AutoC = require(script.codec.meta.Auto)
24
- local BitfieldC = require(script.codec.meta.Bitfield)
25
- local BoolC = require(script.codec.primitive.Bool)
26
- local BufferC = require(script.codec.datatype.Buffer)
27
- local CFrameC = require(script.codec.datatype.CFrame)
28
- local ColorC = require(script.codec.datatype.Color)
29
- local CustomC = require(script.codec.meta.Custom)
30
- local DeltaScalarC = require(script.codec.meta.DeltaScalar)
31
- local EnumC = require(script.codec.meta.Enum)
32
- local Float16C = require(script.codec.primitive.Float16)
33
- local FloatC = require(script.codec.meta.Float)
34
- local IVC = require(script.codec.datatype.IntVector)
35
- local InstanceC = require(script.codec.datatype.Instance)
36
- local IntC = require(script.codec.primitive.Int)
37
- local MapC = require(script.codec.composite.Map)
38
- local NRC = require(script.codec.datatype.NumberRange)
39
- local NothingC = require(script.codec.meta.Nothing)
40
- local NumberC = require(script.codec.primitive.Number)
41
- local OptionalC = require(script.codec.composite.Optional)
42
- local RayC = require(script.codec.datatype.Ray)
43
- local RectC = require(script.codec.datatype.Rect)
44
- local RegionC = require(script.codec.datatype.Region)
45
- local SeqC = require(script.codec.datatype.Sequence)
46
- local StringC = require(script.codec.datatype.String)
47
- local StructC = require(script.codec.composite.Struct)
48
- local TaggedC = require(script.codec.composite.Tagged)
49
- local TupleC = require(script.codec.composite.Tuple)
50
- local UDimC = require(script.codec.datatype.UDim)
51
- local UnknownC = require(script.codec.meta.Unknown)
52
- local VectorC = require(script.codec.datatype.Vector)
53
- local ZintC = require(script.codec.primitive.Zint)
54
-
55
- -- Public types -----------------------------------------------------------
56
-
57
- export type Codec<T> = Types.Codec<T>
58
- export type Connection = Types.Connection
59
- export type Packet<T> = Packet.PacketHandle<T>
60
- export type Query<Req, Resp> = Query.QueryHandle<Req, Resp>
61
- export type Group = Group.GroupHandle
62
- export type Scope = Scope.ScopeHandle
63
- export type PacketOptions = Types.PacketOptions
64
- export type QueryOptions = Types.QueryOptions
65
- export type ConfigureOptions = Types.ConfigureOptions
66
- export type RateLimitConfig = Types.RateLimitConfig
67
- export type PacketStats = Types.PacketStats
68
- export type PlayerStats = Types.PlayerStats
69
-
70
- -- Constants --------------------------------------------------------------
71
-
72
- local IS_SERVER = RunService:IsServer()
73
-
74
- --[[
75
- Singleton-string brand on a single `_lyncKind` field: dispatch is one
76
- hash lookup at the same predicted slot, and the literals narrow on `==`.
77
- ]]
78
- local ALL = table.freeze({ _lyncKind = "all" :: "all" })
79
- local DROP = table.freeze({ _lyncKind = "drop" :: "drop" })
80
-
81
- local CHANNEL_MAX_MIN, CHANNEL_MAX_MAX = 4096, 1048576
82
- local DEPTH_MIN, DEPTH_MAX = 4, 32
83
- local POOL_MIN, POOL_MAX = 2, 128
84
- local FLUSH_HZ_MIN, FLUSH_HZ_MAX = 1, 60
85
-
86
- -- State ------------------------------------------------------------------
87
-
88
- -- Single table so the Heartbeat closure captures one LCT_VAL, not N LCT_REFs.
89
- local flushState = {
90
- started = false,
91
- rate = FLUSH_HZ_MAX,
92
- accum = 0,
93
- conn = nil :: RBXScriptConnection?,
94
- transport = nil :: { flush: () -> () }?,
95
- }
96
-
97
- -- Private ----------------------------------------------------------------
98
-
99
- local isPlayer = Player.is
100
-
101
- type ExceptValue = { _lyncKind: "except", _excluded: { [Player]: boolean } }
102
-
103
- local function except(...: any): ExceptValue
104
- local excluded: { [Player]: boolean } = {}
105
-
106
- for i = 1, select("#", ...) do
107
- local arg = select(i, ...)
108
- if isPlayer(arg) then
109
- excluded[arg :: Player] = true
110
- elseif typeof(arg) == "table" and arg._lyncKind == "group" then
111
- for player in arg._members do
112
- excluded[player] = true
113
- end
114
- else
115
- Log.error(`argument must be a Player or Group, got {typeof(arg)}`)
116
- end
117
- end
118
-
119
- return table.freeze({
120
- _lyncKind = "except" :: "except",
121
- _excluded = table.freeze(excluded),
122
- })
123
- end
124
-
125
- local function setupFlush(transport: { flush: () -> () }): ()
126
- flushState.transport = transport
127
-
128
- flushState.conn = RunService.Heartbeat:Connect(function(dt: number)
129
- local rate = flushState.rate
130
- if rate >= FLUSH_HZ_MAX then
131
- transport.flush()
132
- return
133
- end
134
-
135
- local accum = flushState.accum + dt
136
- local interval = 1 / rate
137
- if accum >= interval then
138
- -- Frame-stall guard: zero the accumulator instead of catching up.
139
- accum = if accum >= 2 * interval then 0 else accum - interval
140
- transport.flush()
141
- end
142
- flushState.accum = accum
143
- end)
144
- end
145
-
146
- -- Validates `value` in [min, max] and applies it; errors with a configure-formatted message.
147
- local function applyOption(
148
- name: string,
149
- value: number?,
150
- min: number,
151
- max: number,
152
- apply: (number) -> ()
153
- ): ()
154
- if value == nil then
155
- return
156
- end
157
- if value < min or value > max then
158
- Log.error(`{name} must be {min}-{max}`)
159
- end
160
- apply(value)
161
- end
162
-
163
- -- Public -----------------------------------------------------------------
164
-
165
- local Lync = {}
166
-
167
- function Lync.configure(options: Types.ConfigureOptions): ()
168
- Log.assert(not flushState.started, "must be called before Lync.start()")
169
-
170
- applyOption(
171
- "channelMaxSize",
172
- options.channelMaxSize,
173
- CHANNEL_MAX_MIN,
174
- CHANNEL_MAX_MAX,
175
- Channel.setMaxSize
176
- )
177
- applyOption("validationDepth", options.validationDepth, DEPTH_MIN, DEPTH_MAX, Gate.setDepth)
178
- applyOption("poolSize", options.poolSize, POOL_MIN, POOL_MAX, Pool.setMaxSize)
179
-
180
- if options.bandwidthLimit then
181
- Gate.configureBandwidth(options.bandwidthLimit.softLimit, options.bandwidthLimit.maxStrikes)
182
- end
183
-
184
- if options.globalRateLimit then
185
- Gate.configureGlobalRateLimit(options.globalRateLimit.maxPerSecond)
186
- end
187
-
188
- if options.stats then
189
- Channel.enableStats()
190
- end
191
- end
192
-
193
- function Lync.start(): ()
194
- Log.assert(not flushState.started, "already started")
195
- flushState.started = true
196
-
197
- if IS_SERVER then
198
- local Server = require(script.transport.Server)
199
- Server.start()
200
- setupFlush(Server)
201
- else
202
- local Client = require(script.transport.Client)
203
- Client.start()
204
- setupFlush(Client)
205
- end
206
- end
207
-
208
- function Lync.flush(): ()
209
- Log.assert(flushState.started, "must call Lync.start() first")
210
- -- Bind to a local: bare `(expr).flush()` after a statement parses as a continuation.
211
- local transport = flushState.transport :: { flush: () -> () }
212
- transport.flush()
213
- flushState.accum = 0
214
- end
215
-
216
- function Lync.flushRate(hz: number): ()
217
- if hz < FLUSH_HZ_MIN or hz > FLUSH_HZ_MAX then
218
- Log.error(`hz must be {FLUSH_HZ_MIN}-{FLUSH_HZ_MAX}`)
219
- end
220
- flushState.rate = hz
221
- flushState.accum = 0
222
- end
223
-
224
- function Lync.isStarted(): boolean
225
- return flushState.started
226
- end
227
-
228
- -- Restore module state to post-require defaults. For tests / hot reload.
229
- function Lync.reset(): ()
230
- if flushState.conn then
231
- flushState.conn:Disconnect()
232
- flushState.conn = nil
233
- end
234
- flushState.started = false
235
- flushState.rate = FLUSH_HZ_MAX
236
- flushState.accum = 0
237
- flushState.transport = nil
238
-
239
- Baseline.reset()
240
- Bridge.reset()
241
- Channel.resetGlobals()
242
- Gate.reset()
243
- Group.reset()
244
- Log.reset()
245
- Middleware.reset()
246
- Pool.reset()
247
- Registry.reset()
248
- end
249
-
250
- Lync.packet = Packet.define
251
- Lync.query = Query.define
252
- Lync.group = Group.create
253
- Lync.scope = Scope.create
254
-
255
- Lync.all = ALL
256
- Lync.except = except
257
- Lync.DROP = DROP
258
-
259
- Lync.onSend = Middleware.onSend
260
- Lync.onReceive = Middleware.onReceive
261
- Lync.onDrop = Middleware.onDrop
262
-
263
- Lync.stats = table.freeze({
264
- player = function(player: Player): Types.PlayerStats?
265
- if not IS_SERVER then
266
- return nil
267
- end
268
- local Server = require(script.transport.Server)
269
- return Server.getPlayerStats(player)
270
- end,
271
-
272
- reset = function(): ()
273
- if IS_SERVER then
274
- local Server = require(script.transport.Server)
275
- Server.resetStats()
276
- end
277
- for _, reg in Registry.all() do
278
- reg.bytesSent = 0
279
- reg.bytesReceived = 0
280
- reg.fires = 0
281
- reg.recvFires = 0
282
- reg.drops = 0
283
- end
284
- end,
285
- })
286
-
287
- Lync.debug = table.freeze({
288
- --[[
289
- Stubs reserved for capture/replay tooling. No-ops keep the API
290
- surface stable across versions with or without the recorder.
291
- ]]
292
- capture = function(_label: string?): () end,
293
- stop = function(): () end,
294
- dump = function(): () end,
295
-
296
- pending = function(): number
297
- return Query.pendingCount()
298
- end,
299
-
300
- registrations = function(): { any }
301
- -- Registry IDs are sequential 1..count and never freed, so get(i) is non-nil in range.
302
- local count = Registry.count()
303
- local result = table.create(count)
304
- for i = 1, count do
305
- local reg = Registry.get(i) :: Types.Registration
306
- result[i] = table.freeze({
307
- name = reg.name,
308
- id = reg.id,
309
- kind = reg.kind,
310
- isUnreliable = reg.isUnreliable,
311
- })
312
- end
313
- return table.freeze(result)
314
- end,
315
- })
316
-
317
- Lync.int = IntC.int
318
- Lync.zint = ZintC.zint
319
- Lync.float = FloatC.float
320
- Lync.deltaInt = DeltaScalarC.deltaInt
321
- Lync.deltaFloat = DeltaScalarC.deltaFloat
322
- Lync.deltaVec3 = DeltaScalarC.deltaVec3
323
- Lync.deltaCFrame = DeltaScalarC.deltaCFrame
324
- Lync.f16 = Float16C.f16
325
- Lync.f32 = NumberC.f32
326
- Lync.f64 = NumberC.f64
327
- Lync.bool = BoolC.bool
328
- Lync.string = StringC
329
- Lync.buff = BufferC.buff
330
- Lync.vec2 = VectorC.vec2
331
- Lync.vec3 = VectorC.vec3
332
- Lync.cframe = CFrameC.cframe
333
- Lync.color3 = ColorC.color3
334
- Lync.inst = InstanceC.inst
335
- Lync.udim = UDimC.udim
336
- Lync.udim2 = UDimC.udim2
337
- Lync.numberRange = NRC.numberRange
338
- Lync.rect = RectC.rect
339
- Lync.ray = RayC.ray
340
- Lync.region3 = RegionC.region3
341
- Lync.region3int16 = RegionC.region3int16
342
- Lync.vec2int16 = IVC.vec2int16
343
- Lync.vec3int16 = IVC.vec3int16
344
- Lync.numberSequence = SeqC.numberSequence
345
- Lync.colorSequence = SeqC.colorSequence
346
- Lync.struct = StructC.struct
347
- Lync.deltaStruct = StructC.deltaStruct
348
- Lync.array = ArrayC.array
349
- Lync.deltaArray = ArrayC.deltaArray
350
- Lync.map = MapC.map
351
- Lync.deltaMap = MapC.deltaMap
352
- Lync.optional = OptionalC.optional
353
- Lync.tuple = TupleC.define
354
- Lync.tagged = TaggedC.define
355
- Lync.enum = EnumC.define
356
- Lync.bitfield = BitfieldC.define
357
- Lync.custom = CustomC.define
358
- Lync.nothing = NothingC.nothing
359
- Lync.unknown = UnknownC.unknown
360
- Lync.auto = AutoC.auto
361
-
362
- return table.freeze(Lync)
@@ -1,57 +0,0 @@
1
- --!strict
2
- --!optimize 2
3
- -- Read-side delta cache, keyed by (deltaId, peer).
4
-
5
- local Types = require(script.Parent.Parent.Types)
6
-
7
- -- State ------------------------------------------------------------------
8
-
9
- -- Per-deltaId map keyed by BaselineKey: server uses Player, client uses `false`.
10
- local _caches: { [number]: { [Types.BaselineKey]: any } } = {}
11
- local _currentKey: Types.BaselineKey = false
12
- local _hasDelta = false
13
-
14
- -- Public -----------------------------------------------------------------
15
-
16
- local Baseline = {}
17
-
18
- function Baseline.setReadKey(key: Types.BaselineKey): ()
19
- _currentKey = key
20
- end
21
-
22
- function Baseline.getCache(deltaId: number): any?
23
- local perKey = _caches[deltaId]
24
- return if perKey then perKey[_currentKey] else nil
25
- end
26
-
27
- function Baseline.setCache(deltaId: number, value: any): ()
28
- local perKey = _caches[deltaId]
29
- if not perKey then
30
- perKey = {}
31
- _caches[deltaId] = perKey
32
- end
33
- perKey[_currentKey] = value
34
- end
35
-
36
- function Baseline.clearPlayer(key: Types.BaselineKey): ()
37
- for _, perKey in _caches do
38
- perKey[key] = nil
39
- end
40
- end
41
-
42
- -- Reader checks this once to skip baseline-key bookkeeping when no delta codec exists.
43
- function Baseline.markHasDelta(): ()
44
- _hasDelta = true
45
- end
46
-
47
- function Baseline.hasDelta(): boolean
48
- return _hasDelta
49
- end
50
-
51
- function Baseline.reset(): ()
52
- table.clear(_caches)
53
- _currentKey = false
54
- _hasDelta = false
55
- end
56
-
57
- return table.freeze(Baseline)