@axpecter/lync 1.4.3 → 1.5.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.
- package/README.md +41 -2
- package/package.json +1 -1
- package/src/Types.luau +13 -1
- package/src/api/Group.luau +35 -28
- package/src/api/Namespace.luau +107 -89
- package/src/api/Packet.luau +69 -51
- package/src/api/Query.luau +101 -95
- package/src/api/Scope.luau +32 -18
- package/src/api/Signal.luau +78 -56
- package/src/codec/Base.luau +17 -17
- package/src/codec/composite/Array.luau +74 -74
- package/src/codec/composite/Map.luau +80 -80
- package/src/codec/composite/Optional.luau +14 -14
- package/src/codec/composite/Shared.luau +35 -35
- package/src/codec/composite/Struct.luau +108 -108
- package/src/codec/composite/Tagged.luau +71 -71
- package/src/codec/composite/Tuple.luau +35 -35
- package/src/codec/datatype/Buffer.luau +18 -18
- package/src/codec/datatype/CFrame.luau +24 -24
- package/src/codec/datatype/Color.luau +8 -12
- package/src/codec/datatype/Instance.luau +13 -13
- package/src/codec/datatype/IntVector.luau +17 -17
- package/src/codec/datatype/NumberRange.luau +7 -7
- package/src/codec/datatype/Ray.luau +16 -16
- package/src/codec/datatype/Rect.luau +13 -13
- package/src/codec/datatype/Region.luau +32 -36
- package/src/codec/datatype/Sequence.luau +41 -41
- package/src/codec/datatype/String.luau +28 -28
- package/src/codec/datatype/UDim.luau +17 -17
- package/src/codec/datatype/Vector.luau +14 -18
- package/src/codec/meta/Auto.luau +75 -73
- package/src/codec/meta/Bitfield.luau +46 -46
- package/src/codec/meta/Custom.luau +7 -7
- package/src/codec/meta/Enum.luau +25 -25
- package/src/codec/meta/Nothing.luau +3 -3
- package/src/codec/meta/Quantized.luau +63 -60
- package/src/codec/meta/Unknown.luau +11 -11
- package/src/codec/primitive/Bool.luau +12 -12
- package/src/codec/primitive/Float16.luau +28 -28
- package/src/codec/primitive/Number.luau +41 -41
- package/src/codec/primitive/Varint.luau +19 -19
- package/src/init.luau +81 -61
- package/src/internal/Baseline.luau +7 -7
- package/src/internal/Channel.luau +56 -56
- package/src/internal/Middleware.luau +29 -29
- package/src/internal/Pool.luau +15 -15
- package/src/internal/Registry.luau +19 -19
- package/src/transport/Bridge.luau +17 -17
- package/src/transport/Client.luau +46 -46
- package/src/transport/Gate.luau +56 -64
- package/src/transport/Reader.luau +34 -34
- package/src/transport/Server.luau +89 -89
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
--!native
|
|
3
3
|
-- LEB128 variable-length integer encoding and decoding.
|
|
4
4
|
|
|
5
|
-
local Channel = require
|
|
6
|
-
local Types = require
|
|
5
|
+
local Channel = require(script.Parent.Parent.Parent.internal.Channel)
|
|
6
|
+
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
7
|
|
|
8
8
|
type ChannelState = Types.ChannelState
|
|
9
9
|
|
|
10
10
|
local alloc = Channel.alloc
|
|
11
11
|
|
|
12
|
-
-- Constants
|
|
12
|
+
-- Constants -----------------------------------------------------------
|
|
13
13
|
|
|
14
14
|
local CONT = 0x80
|
|
15
15
|
local MASK = 0x7F
|
|
@@ -21,56 +21,56 @@ local bor = bit32.bor
|
|
|
21
21
|
local rshift = bit32.rshift
|
|
22
22
|
local lshift = bit32.lshift
|
|
23
23
|
|
|
24
|
-
-- Public
|
|
24
|
+
-- Public --------------------------------------------------------------
|
|
25
25
|
|
|
26
26
|
local Varint = {}
|
|
27
27
|
|
|
28
|
-
function Varint.write
|
|
28
|
+
function Varint.write(ch: ChannelState, value: number): ()
|
|
29
29
|
if value < 0 or value > MAX_VALUE then
|
|
30
|
-
error
|
|
30
|
+
error(`[Lync] Varint value out of range: {value}`)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
-- Fast path: ~80%+ of real-world varints are single-byte
|
|
33
|
+
-- Fast path: ~80%+ of real-world varints are single-byte(lengths, counts)
|
|
34
34
|
if value < CONT then
|
|
35
35
|
local c = ch.cursor
|
|
36
36
|
if c + 1 > ch.size then
|
|
37
|
-
alloc
|
|
37
|
+
alloc(ch, 1)
|
|
38
38
|
end
|
|
39
|
-
buffer.writeu8
|
|
39
|
+
buffer.writeu8(ch.buff, c, value)
|
|
40
40
|
ch.cursor = c + 1
|
|
41
41
|
return
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
local c = ch.cursor
|
|
45
45
|
if c + MAX_BYTES > ch.size then
|
|
46
|
-
alloc
|
|
46
|
+
alloc(ch, MAX_BYTES)
|
|
47
47
|
end
|
|
48
48
|
local b = ch.buff
|
|
49
49
|
|
|
50
50
|
while value >= CONT do
|
|
51
|
-
buffer.writeu8
|
|
52
|
-
value = rshift
|
|
51
|
+
buffer.writeu8(b, c, bor(band(value, MASK), CONT))
|
|
52
|
+
value = rshift(value, 7)
|
|
53
53
|
c += 1
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
buffer.writeu8
|
|
56
|
+
buffer.writeu8(b, c, value)
|
|
57
57
|
ch.cursor = c + 1
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
-- Reads rely on buffer.readu8 throwing on OOB. MAX_BYTES rejects malformed loops.
|
|
61
|
-
function Varint.read
|
|
61
|
+
function Varint.read(src: buffer, pos: number): (number, number)
|
|
62
62
|
local result = 0
|
|
63
63
|
|
|
64
64
|
for offset = 0, MAX_BYTES - 1 do
|
|
65
|
-
local byte = buffer.readu8
|
|
66
|
-
result = bor
|
|
65
|
+
local byte = buffer.readu8(src, pos + offset)
|
|
66
|
+
result = bor(result, lshift(band(byte, MASK), offset * 7))
|
|
67
67
|
|
|
68
|
-
if band
|
|
68
|
+
if band(byte, CONT) == 0 then
|
|
69
69
|
return result, offset + 1
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
error
|
|
73
|
+
error(`[Lync] Varint exceeds {MAX_BYTES} bytes at position {pos}`)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
return table.freeze
|
|
76
|
+
return table.freeze(Varint)
|
package/src/init.luau
CHANGED
|
@@ -2,97 +2,117 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Public API.
|
|
4
4
|
|
|
5
|
-
local RunService = game:GetService
|
|
5
|
+
local RunService = game:GetService("RunService")
|
|
6
6
|
|
|
7
7
|
-- Codec: primitive
|
|
8
|
-
local BoolCodec = require
|
|
9
|
-
local Float16 = require
|
|
10
|
-
local NumberCodec = require
|
|
8
|
+
local BoolCodec = require(script.codec.primitive.Bool)
|
|
9
|
+
local Float16 = require(script.codec.primitive.Float16)
|
|
10
|
+
local NumberCodec = require(script.codec.primitive.Number)
|
|
11
11
|
|
|
12
12
|
-- Codec: datatype
|
|
13
|
-
local BufferCodec = require
|
|
14
|
-
local CFrameCodec = require
|
|
15
|
-
local ColorCodec = require
|
|
16
|
-
local InstanceCodec = require
|
|
17
|
-
local IntVectorCodec = require
|
|
18
|
-
local NumberRangeCodec = require
|
|
19
|
-
local RayCodec = require
|
|
20
|
-
local RectCodec = require
|
|
21
|
-
local RegionCodec = require
|
|
22
|
-
local SequenceCodec = require
|
|
23
|
-
local StringCodec = require
|
|
24
|
-
local UDimCodec = require
|
|
25
|
-
local VectorCodec = require
|
|
13
|
+
local BufferCodec = require(script.codec.datatype.Buffer)
|
|
14
|
+
local CFrameCodec = require(script.codec.datatype.CFrame)
|
|
15
|
+
local ColorCodec = require(script.codec.datatype.Color)
|
|
16
|
+
local InstanceCodec = require(script.codec.datatype.Instance)
|
|
17
|
+
local IntVectorCodec = require(script.codec.datatype.IntVector)
|
|
18
|
+
local NumberRangeCodec = require(script.codec.datatype.NumberRange)
|
|
19
|
+
local RayCodec = require(script.codec.datatype.Ray)
|
|
20
|
+
local RectCodec = require(script.codec.datatype.Rect)
|
|
21
|
+
local RegionCodec = require(script.codec.datatype.Region)
|
|
22
|
+
local SequenceCodec = require(script.codec.datatype.Sequence)
|
|
23
|
+
local StringCodec = require(script.codec.datatype.String)
|
|
24
|
+
local UDimCodec = require(script.codec.datatype.UDim)
|
|
25
|
+
local VectorCodec = require(script.codec.datatype.Vector)
|
|
26
26
|
|
|
27
27
|
-- Codec: composite
|
|
28
|
-
local Array = require
|
|
29
|
-
local Map = require
|
|
30
|
-
local Optional = require
|
|
31
|
-
local Struct = require
|
|
32
|
-
local Tagged = require
|
|
33
|
-
local Tuple = require
|
|
28
|
+
local Array = require(script.codec.composite.Array)
|
|
29
|
+
local Map = require(script.codec.composite.Map)
|
|
30
|
+
local Optional = require(script.codec.composite.Optional)
|
|
31
|
+
local Struct = require(script.codec.composite.Struct)
|
|
32
|
+
local Tagged = require(script.codec.composite.Tagged)
|
|
33
|
+
local Tuple = require(script.codec.composite.Tuple)
|
|
34
34
|
|
|
35
35
|
-- Codec: meta
|
|
36
|
-
local Auto = require
|
|
37
|
-
local Bitfield = require
|
|
38
|
-
local Custom = require
|
|
39
|
-
local EnumCodec = require
|
|
40
|
-
local Nothing = require
|
|
41
|
-
local Quantized = require
|
|
42
|
-
local Unknown = require
|
|
36
|
+
local Auto = require(script.codec.meta.Auto)
|
|
37
|
+
local Bitfield = require(script.codec.meta.Bitfield)
|
|
38
|
+
local Custom = require(script.codec.meta.Custom)
|
|
39
|
+
local EnumCodec = require(script.codec.meta.Enum)
|
|
40
|
+
local Nothing = require(script.codec.meta.Nothing)
|
|
41
|
+
local Quantized = require(script.codec.meta.Quantized)
|
|
42
|
+
local Unknown = require(script.codec.meta.Unknown)
|
|
43
43
|
|
|
44
44
|
-- Internal
|
|
45
|
-
local Channel = require
|
|
46
|
-
local Middleware = require
|
|
47
|
-
local Pool = require
|
|
45
|
+
local Channel = require(script.internal.Channel)
|
|
46
|
+
local Middleware = require(script.internal.Middleware)
|
|
47
|
+
local Pool = require(script.internal.Pool)
|
|
48
48
|
|
|
49
49
|
-- Transport
|
|
50
|
-
local Client = require
|
|
51
|
-
local Gate = require
|
|
52
|
-
local Server = require
|
|
50
|
+
local Client = require(script.transport.Client)
|
|
51
|
+
local Gate = require(script.transport.Gate)
|
|
52
|
+
local Server = require(script.transport.Server)
|
|
53
53
|
|
|
54
54
|
-- API
|
|
55
|
-
local
|
|
56
|
-
local
|
|
57
|
-
local
|
|
58
|
-
local
|
|
59
|
-
local
|
|
55
|
+
local GroupModule = require(script.api.Group)
|
|
56
|
+
local NamespaceModule = require(script.api.Namespace)
|
|
57
|
+
local PacketModule = require(script.api.Packet)
|
|
58
|
+
local QueryModule = require(script.api.Query)
|
|
59
|
+
local ScopeModule = require(script.api.Scope)
|
|
60
|
+
local SignalModule = require(script.api.Signal)
|
|
60
61
|
|
|
61
|
-
--
|
|
62
|
+
-- Type re-exports -----------------------------------------------------
|
|
62
63
|
|
|
63
|
-
local
|
|
64
|
+
local Types = require(script.Types)
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
export type Codec<T> = Types.Codec<T>
|
|
67
|
+
export type InternalCodec<T> = Types.InternalCodec<T>
|
|
68
|
+
export type Connection = Types.Connection
|
|
69
|
+
export type RateLimitConfig = Types.RateLimitConfig
|
|
70
|
+
export type PacketConfig<T> = Types.PacketConfig<T>
|
|
71
|
+
export type QueryConfig<R, S> = Types.QueryConfig<R, S>
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
export type Packet = PacketModule.Packet
|
|
74
|
+
export type Query = QueryModule.Query
|
|
75
|
+
export type Group = GroupModule.Group
|
|
76
|
+
export type Scope = ScopeModule.Scope
|
|
77
|
+
export type Namespace = NamespaceModule.Namespace
|
|
78
|
+
export type Signal = SignalModule.Signal
|
|
79
|
+
export type NamespaceConfig = Types.NamespaceConfig
|
|
80
|
+
|
|
81
|
+
-- Constants -----------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
local ALL = table.freeze({ _tag = "all" })
|
|
84
|
+
|
|
85
|
+
-- Private -------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
local function except(...: any): any
|
|
88
|
+
local count = select("#", ...)
|
|
69
89
|
local set = {} :: { [Player]: true }
|
|
70
90
|
for i = 1, count do
|
|
71
|
-
set[select
|
|
91
|
+
set[select(i, ...)] = true
|
|
72
92
|
end
|
|
73
93
|
return { _tag = "except", _set = set }
|
|
74
94
|
end
|
|
75
95
|
|
|
76
|
-
local function start
|
|
77
|
-
if RunService:IsServer
|
|
78
|
-
Server.start
|
|
96
|
+
local function start(): ()
|
|
97
|
+
if RunService:IsServer() then
|
|
98
|
+
Server.start()
|
|
79
99
|
else
|
|
80
|
-
Client.start
|
|
100
|
+
Client.start()
|
|
81
101
|
end
|
|
82
102
|
end
|
|
83
103
|
|
|
84
|
-
-- Public
|
|
104
|
+
-- Public --------------------------------------------------------------
|
|
85
105
|
|
|
86
106
|
local Lync = {
|
|
87
|
-
VERSION = "1.
|
|
107
|
+
VERSION = "1.5.0",
|
|
88
108
|
|
|
89
109
|
-- Lifecycle
|
|
90
110
|
start = start,
|
|
91
111
|
|
|
92
112
|
-- Definition
|
|
93
|
-
definePacket =
|
|
94
|
-
defineQuery =
|
|
95
|
-
defineNamespace =
|
|
113
|
+
definePacket = PacketModule.define,
|
|
114
|
+
defineQuery = QueryModule.define,
|
|
115
|
+
defineNamespace = NamespaceModule.define,
|
|
96
116
|
|
|
97
117
|
-- Primitives
|
|
98
118
|
u8 = NumberCodec.u8,
|
|
@@ -162,19 +182,19 @@ local Lync = {
|
|
|
162
182
|
DROP = Middleware.DROP,
|
|
163
183
|
|
|
164
184
|
-- Groups
|
|
165
|
-
createGroup =
|
|
185
|
+
createGroup = GroupModule.create,
|
|
166
186
|
|
|
167
187
|
-- Scope
|
|
168
|
-
scope =
|
|
188
|
+
scope = ScopeModule.create,
|
|
169
189
|
|
|
170
|
-
-- Configuration
|
|
190
|
+
-- Configuration(call before start)
|
|
171
191
|
setChannelMaxSize = Channel.setMaxSize,
|
|
172
192
|
setValidationDepth = Gate.setMaxDepth,
|
|
173
193
|
setPoolSize = Pool.setMaxSize,
|
|
174
194
|
|
|
175
195
|
-- Introspection
|
|
176
|
-
queryPendingCount =
|
|
196
|
+
queryPendingCount = QueryModule.pendingCount,
|
|
177
197
|
}
|
|
178
198
|
|
|
179
199
|
Lync.default = Lync
|
|
180
|
-
return table.freeze
|
|
200
|
+
return table.freeze(Lync)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!optimize 2
|
|
3
|
-
-- Read-side baseline cache keyed by source
|
|
3
|
+
-- Read-side baseline cache keyed by source(player or client sentinel).
|
|
4
4
|
|
|
5
|
-
-- State
|
|
5
|
+
-- State ---------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
local _readKey = false :: any
|
|
8
8
|
local _readCaches = {} :: { [any]: { [number]: any } }
|
|
9
9
|
|
|
10
|
-
-- Public
|
|
10
|
+
-- Public --------------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
local Baseline = {}
|
|
13
13
|
|
|
@@ -16,16 +16,16 @@ local Baseline = {}
|
|
|
16
16
|
-- cheap branch once deltas are first used in the session.
|
|
17
17
|
Baseline.hasDelta = false
|
|
18
18
|
|
|
19
|
-
function Baseline.setReadKey
|
|
19
|
+
function Baseline.setReadKey(key: any): ()
|
|
20
20
|
_readKey = key
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
function Baseline.getCache
|
|
23
|
+
function Baseline.getCache(deltaId: number): any
|
|
24
24
|
local map = _readCaches[_readKey]
|
|
25
25
|
return map and map[deltaId]
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
function Baseline.setCache
|
|
28
|
+
function Baseline.setCache(deltaId: number, data: any): ()
|
|
29
29
|
if not Baseline.hasDelta then
|
|
30
30
|
Baseline.hasDelta = true
|
|
31
31
|
end
|
|
@@ -37,7 +37,7 @@ function Baseline.setCache (deltaId: number, data: any): ()
|
|
|
37
37
|
map[deltaId] = data
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
function Baseline.clearSource
|
|
40
|
+
function Baseline.clearSource(key: any): ()
|
|
41
41
|
_readCaches[key] = nil
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
--!native
|
|
3
3
|
-- Per-channel buffer state with batching, delta cache, frame XOR.
|
|
4
4
|
|
|
5
|
-
local Types = require
|
|
5
|
+
local Types = require(script.Parent.Parent.Types)
|
|
6
6
|
|
|
7
7
|
type ChannelState = Types.ChannelState
|
|
8
8
|
|
|
9
|
-
-- Constants
|
|
9
|
+
-- Constants -----------------------------------------------------------
|
|
10
10
|
|
|
11
11
|
local INITIAL_SIZE = 1024
|
|
12
12
|
local MAX_SIZE = 262144
|
|
@@ -18,7 +18,7 @@ local band32 = bit32.band
|
|
|
18
18
|
local countlz = bit32.countlz
|
|
19
19
|
local lshift = bit32.lshift
|
|
20
20
|
|
|
21
|
-
-- State
|
|
21
|
+
-- State ---------------------------------------------------------------
|
|
22
22
|
|
|
23
23
|
local _maxSize = MAX_SIZE
|
|
24
24
|
|
|
@@ -26,25 +26,25 @@ local _maxSize = MAX_SIZE
|
|
|
26
26
|
-- serializers may overwrite before the error fires.
|
|
27
27
|
local _currentPacket = ""
|
|
28
28
|
|
|
29
|
-
-- Public
|
|
29
|
+
-- Public --------------------------------------------------------------
|
|
30
30
|
|
|
31
31
|
local Channel = {}
|
|
32
32
|
|
|
33
33
|
-- Override the maximum buffer size. Call before start(). Range: 4096–1048576.
|
|
34
|
-
function Channel.setMaxSize
|
|
34
|
+
function Channel.setMaxSize(bytes: number): ()
|
|
35
35
|
if bytes < 4096 or bytes > 1048576 then
|
|
36
|
-
error
|
|
36
|
+
error(`[Lync] Channel max size must be 4096–1048576, got {bytes}`)
|
|
37
37
|
end
|
|
38
38
|
_maxSize = bytes
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
function Channel.getMaxSize
|
|
41
|
+
function Channel.getMaxSize(): number
|
|
42
42
|
return _maxSize
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
function Channel.create
|
|
45
|
+
function Channel.create(): ChannelState
|
|
46
46
|
return {
|
|
47
|
-
buff = buffer.create
|
|
47
|
+
buff = buffer.create(INITIAL_SIZE),
|
|
48
48
|
cursor = 0,
|
|
49
49
|
size = INITIAL_SIZE,
|
|
50
50
|
refs = {},
|
|
@@ -57,21 +57,21 @@ function Channel.create (): ChannelState
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
-- Grows the channel buffer to fit the requested bytes. Power-of-two sizing.
|
|
60
|
-
function Channel.alloc
|
|
60
|
+
function Channel.alloc(ch: ChannelState, bytes: number): ()
|
|
61
61
|
local needed = ch.cursor + bytes
|
|
62
62
|
if needed <= ch.size then
|
|
63
63
|
return
|
|
64
64
|
end
|
|
65
65
|
if needed > _maxSize then
|
|
66
|
-
error
|
|
67
|
-
`[Lync] Channel overflow writing "{_currentPacket}": {needed} bytes > {_maxSize} max
|
|
66
|
+
error(
|
|
67
|
+
`[Lync] Channel overflow writing "{_currentPacket}": {needed} bytes > {_maxSize} max(call Channel.setMaxSize to raise)`
|
|
68
68
|
)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
local newSize = lshift
|
|
71
|
+
local newSize = lshift(1, 32 - countlz(needed - 1))
|
|
72
72
|
|
|
73
|
-
local newBuff = buffer.create
|
|
74
|
-
buffer.copy
|
|
73
|
+
local newBuff = buffer.create(newSize)
|
|
74
|
+
buffer.copy(newBuff, 0, ch.buff, 0, ch.cursor)
|
|
75
75
|
ch.buff = newBuff
|
|
76
76
|
ch.size = newSize
|
|
77
77
|
end
|
|
@@ -79,38 +79,38 @@ end
|
|
|
79
79
|
local alloc = Channel.alloc
|
|
80
80
|
|
|
81
81
|
-- Seals the open batch header and returns a snapshot of the buffer + refs.
|
|
82
|
-
function Channel.sealAndDump
|
|
82
|
+
function Channel.sealAndDump(ch: ChannelState): (buffer, { Instance })
|
|
83
83
|
if ch.lastId >= 0 then
|
|
84
|
-
buffer.writeu16
|
|
84
|
+
buffer.writeu16(ch.buff, ch.countPos, ch.itemCount)
|
|
85
85
|
ch.lastId = -1
|
|
86
86
|
ch.countPos = 0
|
|
87
87
|
ch.itemCount = 0
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
local cur = ch.cursor
|
|
91
|
-
local out = buffer.create
|
|
92
|
-
buffer.copy
|
|
91
|
+
local out = buffer.create(cur)
|
|
92
|
+
buffer.copy(out, 0, ch.buff, 0, cur)
|
|
93
93
|
|
|
94
94
|
local refs = ch.refs
|
|
95
|
-
return out, if #refs > 0 then table.clone
|
|
95
|
+
return out, if #refs > 0 then table.clone(refs) else {}
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
-- Sets the packet name for overflow diagnostics.
|
|
99
|
-
function Channel.setCurrentPacket
|
|
99
|
+
function Channel.setCurrentPacket(name: string): ()
|
|
100
100
|
_currentPacket = name
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
-- Writes a single value into the batch. Opens a new header on ID change or overflow.
|
|
104
|
-
function Channel.writeBatch
|
|
104
|
+
function Channel.writeBatch(ch: ChannelState, id: number, name: string, codec: any, data: any): ()
|
|
105
105
|
if id ~= ch.lastId or ch.itemCount >= MAX_BATCH then
|
|
106
106
|
if ch.lastId >= 0 then
|
|
107
|
-
buffer.writeu16
|
|
107
|
+
buffer.writeu16(ch.buff, ch.countPos, ch.itemCount)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
_currentPacket = name
|
|
111
|
-
alloc
|
|
111
|
+
alloc(ch, 3)
|
|
112
112
|
local c = ch.cursor
|
|
113
|
-
buffer.writeu8
|
|
113
|
+
buffer.writeu8(ch.buff, c, id)
|
|
114
114
|
ch.countPos = c + 1
|
|
115
115
|
ch.cursor = c + 3
|
|
116
116
|
ch.lastId = id
|
|
@@ -118,11 +118,11 @@ function Channel.writeBatch (ch: ChannelState, id: number, name: string, codec:
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
ch.itemCount += 1
|
|
121
|
-
codec.write
|
|
121
|
+
codec.write(ch, data)
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
-- Appends pre-serialized bytes into a batch. Used by broadcast fan-out.
|
|
125
|
-
function Channel.writeBatchRaw
|
|
125
|
+
function Channel.writeBatchRaw(
|
|
126
126
|
ch: ChannelState,
|
|
127
127
|
id: number,
|
|
128
128
|
src: buffer,
|
|
@@ -131,12 +131,12 @@ function Channel.writeBatchRaw (
|
|
|
131
131
|
): ()
|
|
132
132
|
if id ~= ch.lastId or ch.itemCount >= MAX_BATCH then
|
|
133
133
|
if ch.lastId >= 0 then
|
|
134
|
-
buffer.writeu16
|
|
134
|
+
buffer.writeu16(ch.buff, ch.countPos, ch.itemCount)
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
alloc
|
|
137
|
+
alloc(ch, 3)
|
|
138
138
|
local c = ch.cursor
|
|
139
|
-
buffer.writeu8
|
|
139
|
+
buffer.writeu8(ch.buff, c, id)
|
|
140
140
|
ch.countPos = c + 1
|
|
141
141
|
ch.cursor = c + 3
|
|
142
142
|
ch.lastId = id
|
|
@@ -146,20 +146,20 @@ function Channel.writeBatchRaw (
|
|
|
146
146
|
ch.itemCount += 1
|
|
147
147
|
|
|
148
148
|
if srcLen > 0 then
|
|
149
|
-
alloc
|
|
150
|
-
buffer.copy
|
|
149
|
+
alloc(ch, srcLen)
|
|
150
|
+
buffer.copy(ch.buff, ch.cursor, src, 0, srcLen)
|
|
151
151
|
ch.cursor += srcLen
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
if srcRefs then
|
|
155
155
|
local refs = ch.refs
|
|
156
|
-
table.move
|
|
156
|
+
table.move(srcRefs, 1, #srcRefs, #refs + 1, refs)
|
|
157
157
|
end
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
-
local function sealOpen
|
|
160
|
+
local function sealOpen(ch: ChannelState): ()
|
|
161
161
|
if ch.lastId >= 0 then
|
|
162
|
-
buffer.writeu16
|
|
162
|
+
buffer.writeu16(ch.buff, ch.countPos, ch.itemCount)
|
|
163
163
|
ch.lastId = -1
|
|
164
164
|
ch.countPos = 0
|
|
165
165
|
ch.itemCount = 0
|
|
@@ -168,10 +168,10 @@ end
|
|
|
168
168
|
|
|
169
169
|
--[[
|
|
170
170
|
Writes a query frame. Seals any open batch, then writes:
|
|
171
|
-
id
|
|
171
|
+
id(u8) + correlationId(u16) + status(u8)
|
|
172
172
|
Status 0 = payload follows. Status 1 = nil response.
|
|
173
173
|
]]
|
|
174
|
-
function Channel.writeQuery
|
|
174
|
+
function Channel.writeQuery(
|
|
175
175
|
ch: ChannelState,
|
|
176
176
|
id: number,
|
|
177
177
|
name: string,
|
|
@@ -180,61 +180,61 @@ function Channel.writeQuery (
|
|
|
180
180
|
data: any?
|
|
181
181
|
): ()
|
|
182
182
|
_currentPacket = name
|
|
183
|
-
sealOpen
|
|
183
|
+
sealOpen(ch)
|
|
184
184
|
|
|
185
|
-
alloc
|
|
185
|
+
alloc(ch, 4)
|
|
186
186
|
local c = ch.cursor
|
|
187
|
-
buffer.writeu8
|
|
188
|
-
buffer.writeu16
|
|
187
|
+
buffer.writeu8(ch.buff, c, id)
|
|
188
|
+
buffer.writeu16(ch.buff, c + 1, correlationId)
|
|
189
189
|
|
|
190
190
|
if codec then
|
|
191
|
-
buffer.writeu8
|
|
191
|
+
buffer.writeu8(ch.buff, c + 3, 0)
|
|
192
192
|
ch.cursor = c + 4
|
|
193
|
-
codec.write
|
|
193
|
+
codec.write(ch, data)
|
|
194
194
|
else
|
|
195
|
-
buffer.writeu8
|
|
195
|
+
buffer.writeu8(ch.buff, c + 3, 1)
|
|
196
196
|
ch.cursor = c + 4
|
|
197
197
|
end
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
-- XOR current frame against previous. Produces zero-heavy output for deflate.
|
|
201
|
-
function Channel.xorApply
|
|
202
|
-
local curLen = buffer.len
|
|
201
|
+
function Channel.xorApply(current: buffer, previous: buffer?): buffer
|
|
202
|
+
local curLen = buffer.len(current)
|
|
203
203
|
if not previous then
|
|
204
204
|
return current
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
-
local prevLen = buffer.len
|
|
207
|
+
local prevLen = buffer.len(previous :: buffer)
|
|
208
208
|
if prevLen == 0 then
|
|
209
209
|
return current
|
|
210
210
|
end
|
|
211
211
|
|
|
212
|
-
local result = buffer.create
|
|
213
|
-
local overlap = min
|
|
212
|
+
local result = buffer.create(curLen)
|
|
213
|
+
local overlap = min(curLen, prevLen)
|
|
214
214
|
local prev = previous :: buffer
|
|
215
215
|
|
|
216
|
-
local aligned = band32
|
|
216
|
+
local aligned = band32(overlap, 0xFFFFFFFC)
|
|
217
217
|
for i = 0, aligned - 4, 4 do
|
|
218
|
-
buffer.writeu32
|
|
218
|
+
buffer.writeu32(result, i, bxor(buffer.readu32(current, i), buffer.readu32(prev, i)))
|
|
219
219
|
end
|
|
220
220
|
|
|
221
221
|
for i = aligned, overlap - 1 do
|
|
222
|
-
buffer.writeu8
|
|
222
|
+
buffer.writeu8(result, i, bxor(buffer.readu8(current, i), buffer.readu8(prev, i)))
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
if curLen > overlap then
|
|
226
|
-
buffer.copy
|
|
226
|
+
buffer.copy(result, overlap, current, overlap, curLen - overlap)
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
return result
|
|
230
230
|
end
|
|
231
231
|
|
|
232
|
-
function Channel.reset
|
|
232
|
+
function Channel.reset(ch: ChannelState): ()
|
|
233
233
|
ch.cursor = 0
|
|
234
234
|
ch.lastId = -1
|
|
235
235
|
ch.countPos = 0
|
|
236
236
|
ch.itemCount = 0
|
|
237
|
-
table.clear
|
|
237
|
+
table.clear(ch.refs)
|
|
238
238
|
end
|
|
239
239
|
|
|
240
|
-
return table.freeze
|
|
240
|
+
return table.freeze(Channel)
|