@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
@@ -1,485 +0,0 @@
1
- --!strict
2
- --!native
3
- -- map() and deltaMap(). Keys sorted at encode for stable wire bytes.
4
-
5
- local Base = require(script.Parent.Parent.Base)
6
- local Baseline = require(script.Parent.Parent.Parent.internal.Baseline)
7
- local Log = require(script.Parent.Parent.Parent.util.Log)
8
- local Shared = require(script.Parent.Parent.composite.Shared)
9
- local Types = require(script.Parent.Parent.Parent.Types)
10
- local Varint = require(script.Parent.Parent.primitive.Varint)
11
-
12
- -- Constants --------------------------------------------------------------
13
-
14
- -- deltaMap wire flags. Distinct from Shared's struct/array flag spaces.
15
- local DM_UNCHANGED = 0
16
- local DM_FULL = 1
17
- local DM_DIFF = 2
18
-
19
- -- State ------------------------------------------------------------------
20
-
21
- --[[
22
- Depth-stacked key scratch. A nested Map.write (Map<K, Map<K2, V>>) would
23
- clobber a single shared array mid-iteration; the stack gives each frame
24
- its own slot. _keyTails parallels _keyStacks because `#keys` after
25
- `keys[count] = k` is undefined when count < the prior count.
26
- ]]
27
- local _keyStacks: { { any } } = {}
28
- local _keyTails: { number } = {}
29
- local _keyDepth = 0
30
-
31
- -- Private ----------------------------------------------------------------
32
-
33
- local ensure = Base.ensure
34
- local allocDeltaId = Shared.allocDeltaId
35
- local acquireScratch = Shared.acquireScratch
36
- local releaseScratch = Shared.releaseScratch
37
- local rangeEqual = Shared.rangeEqual
38
- local copyToBuf = Shared.copyToBuf
39
- local containsDelta = Shared.containsDelta
40
- local enforceMaxCount = Shared.enforceMaxCount
41
- local writeu8 = buffer.writeu8
42
- local readu8 = buffer.readu8
43
- local bufCopy = buffer.copy
44
- local bufLen = buffer.len
45
- local varintRead = Varint.read
46
- local varintWrite = Varint.write
47
-
48
- type DeltaMapEntry = { kBuf: buffer, kLen: number, vBuf: buffer, vLen: number }
49
-
50
- local function acquireKeys(): { any }
51
- _keyDepth += 1
52
- local keys = _keyStacks[_keyDepth]
53
- if keys then
54
- return keys
55
- end
56
- keys = {}
57
- _keyStacks[_keyDepth] = keys
58
- return keys
59
- end
60
-
61
- local function releaseKeys(): ()
62
- _keyDepth -= 1
63
- end
64
-
65
- -- Module-level so the mixed-type sort path doesn't allocate a closure per write.
66
- local function tostringLess(a: any, b: any): boolean
67
- return tostring(a) < tostring(b)
68
- end
69
-
70
- local function sortKeys(keys: { any }, canSortDirect: boolean): ()
71
- if canSortDirect then
72
- table.sort(keys :: { any })
73
- else
74
- table.sort(keys, tostringLess)
75
- end
76
- end
77
-
78
- local function collectAndSortKeys(value: { [any]: any }, canSortDirect: boolean): ({ any }, number)
79
- local keys = acquireKeys()
80
- local prevTail = _keyTails[_keyDepth] or 0
81
- local count = 0
82
- for k in value do
83
- count += 1
84
- keys[count] = k
85
- end
86
- if count < prevTail then
87
- for i = count + 1, prevTail do
88
- keys[i] = nil
89
- end
90
- end
91
- _keyTails[_keyDepth] = count
92
- if count > 1 then
93
- sortKeys(keys, canSortDirect)
94
- end
95
- return keys, count
96
- end
97
-
98
- -- Public -----------------------------------------------------------------
99
-
100
- local Map = {}
101
-
102
- function Map.map(
103
- keyCodec: Types.InternalCodec<any>,
104
- valueCodec: Types.InternalCodec<any>,
105
- maxCount: number?
106
- ): Types.InternalCodec<any>
107
- local fixedKey = keyCodec._size
108
- local fixedValue = valueCodec._size
109
- local hasUnknown = keyCodec._hasUnknown or valueCodec._hasUnknown
110
- local hasDelta = containsDelta(keyCodec) or containsDelta(valueCodec)
111
-
112
- --[[
113
- Numbers and strings sort by `<` directly; everything else (Instance,
114
- vector, mixed-type via Auto) routes through tostring. Pinned at codec
115
- creation so writes don't re-sniff the key type.
116
- ]]
117
- local typeCheck = keyCodec._typeCheck
118
- local canSortDirect = typeCheck == "number" or typeCheck == "string"
119
-
120
- local codec: Types.InternalCodec<any> = {
121
- _isMap = true,
122
- _keyCodec = keyCodec,
123
- _valueCodec = valueCodec,
124
- _maxCount = maxCount,
125
-
126
- --[[
127
- Sort keys for deterministic wire layout. Without this, two
128
- structurally-equal maps yield different byte sequences across
129
- frames, which breaks every downstream byte-equality cache (the
130
- XOR baseline and deltaMap).
131
- ]]
132
- write = function(ch: Types.ChannelState, value: { [any]: any }): ()
133
- if typeof(value) ~= "table" then
134
- Log.error(`expected table, got {typeof(value)}`)
135
- end
136
-
137
- local keys, count = collectAndSortKeys(value, canSortDirect)
138
-
139
- varintWrite(ch, count)
140
- if count == 0 then
141
- releaseKeys()
142
- return
143
- end
144
-
145
- -- Single alloc when both halves are fixed-size.
146
- if fixedKey and fixedValue then
147
- ensure(ch, count * (fixedKey + fixedValue))
148
- end
149
-
150
- for i = 1, count do
151
- local k = keys[i]
152
- keyCodec.write(ch, k)
153
- valueCodec.write(ch, value[k])
154
- end
155
- releaseKeys()
156
- end,
157
-
158
- read = function(src: buffer, pos: number, refs: { Instance }?): ({ [any]: any }, number)
159
- local count, lenBytes = varintRead(src, pos)
160
- enforceMaxCount(count, maxCount)
161
-
162
- -- Fixed-size: reject corrupt counts before per-entry decode.
163
- if fixedKey and fixedValue and count > 0 then
164
- local payloadBytes = count * (fixedKey + fixedValue)
165
- if payloadBytes > bufLen(src) - (pos + lenBytes) then
166
- Log.error(`payload {payloadBytes}B exceeds remaining buffer`)
167
- end
168
- elseif count > 0 then
169
- -- Variable-size: each pair is at least 2 bytes (key + value).
170
- if count * 2 > bufLen(src) - (pos + lenBytes) then
171
- Log.error(`map count {count} exceeds remaining buffer`)
172
- end
173
- end
174
-
175
- local result: { [any]: any } = {}
176
- local total = lenBytes
177
- for i = 1, count do
178
- local k, kc = keyCodec.read(src, pos + total, refs)
179
- if kc == 0 then
180
- Log.error(`truncated key at index {i}`)
181
- end
182
- total += kc
183
- local v, vc = valueCodec.read(src, pos + total, refs)
184
- if vc == 0 then
185
- Log.error(`truncated value at index {i}`)
186
- end
187
- total += vc
188
- result[k] = v
189
- end
190
- return result, total
191
- end,
192
- }
193
- if hasUnknown then
194
- codec._hasUnknown = true
195
- end
196
- if hasDelta then
197
- codec._hasDelta = true
198
- end
199
- return table.freeze(codec)
200
- end
201
-
202
- --[[
203
- Per-key deltaMap. Wire:
204
- [0] UNCHANGED (1 byte)
205
- [1] FULL <count varint> <(k,v) pairs ...>
206
- [2] DIFF <removeCount varint> <removed key bytes ...>
207
- <changeCount varint> <(k,v) pair bytes ...>
208
-
209
- Cache: per-key encoded value bytes for byte-equality diffing plus per-key
210
- encoded key bytes so removed-key emission doesn't re-encode the key codec
211
- for keys that no longer live in the map.
212
- ]]
213
- function Map.deltaMap(
214
- keyCodec: Types.InternalCodec<any>,
215
- valueCodec: Types.InternalCodec<any>,
216
- maxCount: number?
217
- ): Types.InternalCodec<any>
218
- -- Inner delta would chain-diff across pairs within a frame, not across frames.
219
- if containsDelta(keyCodec) then
220
- Log.error("deltaMap key codec cannot contain delta state")
221
- end
222
- if containsDelta(valueCodec) then
223
- Log.error("deltaMap value codec cannot contain delta state")
224
- end
225
-
226
- local deltaId = allocDeltaId()
227
- local typeCheck = keyCodec._typeCheck
228
- local canSortDirect = typeCheck == "number" or typeCheck == "string"
229
- local inner = Map.map(keyCodec, valueCodec, maxCount)
230
-
231
- --[[
232
- Encode each (key, value) pair into `scratch` and capture per-pair byte
233
- ranges. Returns the sorted-keys list plus four parallel arrays of
234
- offset/length so the diff path can compare and emit individual entries
235
- without re-encoding.
236
- ]]
237
- local function encodePerKey(
238
- scratch: Types.ChannelState,
239
- value: { [any]: any }
240
- ): ({ any }, { number }, { number }, { number }, { number })
241
- local keys, count = collectAndSortKeys(value, canSortDirect)
242
- local kOff = table.create(count)
243
- local kLen = table.create(count)
244
- local vOff = table.create(count)
245
- local vLen = table.create(count)
246
-
247
- for i = 1, count do
248
- local k = keys[i]
249
- local before = scratch.cursor
250
- keyCodec.write(scratch, k)
251
- local mid = scratch.cursor
252
- kOff[i] = before
253
- kLen[i] = mid - before
254
- valueCodec.write(scratch, value[k])
255
- vOff[i] = mid
256
- vLen[i] = scratch.cursor - mid
257
- end
258
- return keys, kOff, kLen, vOff, vLen
259
- end
260
-
261
- return table.freeze({
262
- _isDelta = true,
263
- _isMap = true,
264
- _keyCodec = keyCodec,
265
- _valueCodec = valueCodec,
266
- _maxCount = maxCount,
267
-
268
- write = function(ch: Types.ChannelState, value: { [any]: any }): ()
269
- if typeof(value) ~= "table" then
270
- Log.error(`expected table, got {typeof(value)}`)
271
- end
272
-
273
- local cache = ch.deltas[deltaId] :: any
274
- local scratch = acquireScratch()
275
- local keys, kOff, kLen, vOff, vLen = encodePerKey(scratch, value)
276
- local count = #keys
277
- local scratchBuf = scratch.buff
278
-
279
- -- First frame: emit FULL. Per-key scratch bytes ARE the inner map payload.
280
- if not cache then
281
- ensure(ch, 1)
282
- writeu8(ch.buff, ch.cursor, DM_FULL)
283
- ch.cursor += 1
284
- varintWrite(ch, count)
285
- local payloadLen = scratch.cursor
286
- ensure(ch, payloadLen)
287
- bufCopy(ch.buff, ch.cursor, scratchBuf, 0, payloadLen)
288
- ch.cursor += payloadLen
289
-
290
- local perKey: { [any]: DeltaMapEntry } = {}
291
- for i = 1, count do
292
- local kbLen = kLen[i]
293
- local vbLen = vLen[i]
294
- perKey[keys[i]] = {
295
- kBuf = copyToBuf(nil, scratchBuf, kOff[i], kbLen),
296
- kLen = kbLen,
297
- vBuf = copyToBuf(nil, scratchBuf, vOff[i], vbLen),
298
- vLen = vbLen,
299
- }
300
- end
301
- ch.deltas[deltaId] = { perKey = perKey } :: any
302
- releaseKeys()
303
- releaseScratch()
304
- return
305
- end
306
-
307
- local cachedPerKey = cache.perKey :: { [any]: DeltaMapEntry }
308
-
309
- local seen: { [any]: boolean } = {}
310
- local changed: { number } = {}
311
- local changedCount = 0
312
- for i = 1, count do
313
- local k = keys[i]
314
- seen[k] = true
315
- local entry = cachedPerKey[k]
316
- local newLen = vLen[i]
317
- if
318
- not entry
319
- or newLen ~= entry.vLen
320
- or not rangeEqual(scratchBuf, vOff[i], entry.vBuf, 0, newLen)
321
- then
322
- changedCount += 1
323
- changed[changedCount] = i
324
- end
325
- end
326
-
327
- local removed: { any } = {}
328
- local removedCount = 0
329
- for k in cachedPerKey do
330
- if not seen[k] then
331
- removedCount += 1
332
- removed[removedCount] = k
333
- end
334
- end
335
-
336
- if removedCount == 0 and changedCount == 0 then
337
- ensure(ch, 1)
338
- writeu8(ch.buff, ch.cursor, DM_UNCHANGED)
339
- ch.cursor += 1
340
- releaseKeys()
341
- releaseScratch()
342
- return
343
- end
344
-
345
- -- Sort removed keys so the XOR baseline can collapse identical drops.
346
- sortKeys(removed, canSortDirect)
347
-
348
- ensure(ch, 1)
349
- writeu8(ch.buff, ch.cursor, DM_DIFF)
350
- ch.cursor += 1
351
-
352
- varintWrite(ch, removedCount)
353
- for i = 1, removedCount do
354
- local entry = cachedPerKey[removed[i]]
355
- local n = entry.kLen
356
- ensure(ch, n)
357
- bufCopy(ch.buff, ch.cursor, entry.kBuf, 0, n)
358
- ch.cursor += n
359
- end
360
-
361
- varintWrite(ch, changedCount)
362
- for i = 1, changedCount do
363
- local idx = changed[i]
364
- local kbLen = kLen[idx]
365
- local vbLen = vLen[idx]
366
- ensure(ch, kbLen + vbLen)
367
- bufCopy(ch.buff, ch.cursor, scratchBuf, kOff[idx], kbLen)
368
- bufCopy(ch.buff, ch.cursor + kbLen, scratchBuf, vOff[idx], vbLen)
369
- ch.cursor += kbLen + vbLen
370
- end
371
-
372
- -- Update cache: drop removed, refresh changed, leave untouched in place.
373
- for i = 1, removedCount do
374
- cachedPerKey[removed[i]] = nil
375
- end
376
- for i = 1, changedCount do
377
- local idx = changed[i]
378
- local k = keys[idx]
379
- local kbLen = kLen[idx]
380
- local vbLen = vLen[idx]
381
- local entry = cachedPerKey[k]
382
- if entry then
383
- entry.kBuf = copyToBuf(entry.kBuf, scratchBuf, kOff[idx], kbLen)
384
- entry.kLen = kbLen
385
- entry.vBuf = copyToBuf(entry.vBuf, scratchBuf, vOff[idx], vbLen)
386
- entry.vLen = vbLen
387
- else
388
- cachedPerKey[k] = {
389
- kBuf = copyToBuf(nil, scratchBuf, kOff[idx], kbLen),
390
- kLen = kbLen,
391
- vBuf = copyToBuf(nil, scratchBuf, vOff[idx], vbLen),
392
- vLen = vbLen,
393
- }
394
- end
395
- end
396
-
397
- releaseKeys()
398
- releaseScratch()
399
- end,
400
-
401
- read = function(src: buffer, pos: number, refs: { Instance }?): ({ [any]: any }, number)
402
- if pos >= bufLen(src) then
403
- Log.error("truncated deltaMap header")
404
- end
405
- local flag = readu8(src, pos)
406
-
407
- if flag == DM_UNCHANGED then
408
- local cached = Baseline.getCache(deltaId)
409
- if cached == nil then
410
- Log.error("UNCHANGED flag before any FULL frame; baseline missing")
411
- end
412
- return cached, 1
413
- end
414
-
415
- if flag == DM_FULL then
416
- local value, consumed = inner.read(src, pos + 1, refs)
417
- Baseline.setCache(deltaId, value)
418
- return value, 1 + consumed
419
- end
420
-
421
- if flag == DM_DIFF then
422
- local cached = Baseline.getCache(deltaId)
423
- if cached == nil then
424
- Log.error("deltaMap DIFF before any FULL frame; baseline missing")
425
- end
426
- local result: { [any]: any } = table.clone(cached)
427
- local total = 1
428
-
429
- local cachedSize = 0
430
- for _ in cached do
431
- cachedSize += 1
432
- end
433
-
434
- local removeCount, rcLen = varintRead(src, pos + total)
435
- if rcLen == 0 then
436
- Log.error("truncated deltaMap remove count")
437
- end
438
- enforceMaxCount(removeCount, maxCount, "removeCount")
439
- if removeCount > cachedSize then
440
- Log.error(`deltaMap removeCount {removeCount} exceeds cached size {cachedSize}`)
441
- end
442
- total += rcLen
443
- for _ = 1, removeCount do
444
- local k, kc = keyCodec.read(src, pos + total, refs)
445
- if kc == 0 then
446
- Log.error("truncated deltaMap removed key")
447
- end
448
- total += kc
449
- result[k] = nil
450
- end
451
-
452
- local changeCount, ccLen = varintRead(src, pos + total)
453
- if ccLen == 0 then
454
- Log.error("truncated deltaMap change count")
455
- end
456
- enforceMaxCount(changeCount, maxCount, "changeCount")
457
- -- Joint bound: post-DIFF size can't exceed maxCount either.
458
- if maxCount and (cachedSize - removeCount + changeCount) > maxCount then
459
- Log.error(`deltaMap DIFF would grow map past maxCount {maxCount}`)
460
- end
461
- total += ccLen
462
- for _ = 1, changeCount do
463
- local k, kc = keyCodec.read(src, pos + total, refs)
464
- if kc == 0 then
465
- Log.error("truncated deltaMap changed key")
466
- end
467
- total += kc
468
- local v, vc = valueCodec.read(src, pos + total, refs)
469
- if vc == 0 then
470
- Log.error("truncated deltaMap changed value")
471
- end
472
- total += vc
473
- result[k] = v
474
- end
475
-
476
- Baseline.setCache(deltaId, result)
477
- return result, total
478
- end
479
-
480
- Log.error(`invalid deltaMap flag {flag}`)
481
- end,
482
- }) :: Types.InternalCodec<any>
483
- end
484
-
485
- return table.freeze(Map)
@@ -1,54 +0,0 @@
1
- --!strict
2
- --!native
3
- -- Optional codec. 1-byte present/absent flag, value only when present.
4
-
5
- local Channel = require(script.Parent.Parent.Parent.internal.Channel)
6
- local Log = require(script.Parent.Parent.Parent.util.Log)
7
- local Shared = require(script.Parent.Parent.composite.Shared)
8
- local Types = require(script.Parent.Parent.Parent.Types)
9
-
10
- -- Private ----------------------------------------------------------------
11
-
12
- local writeByte = Channel.writeByte
13
- local readu8 = buffer.readu8
14
- local bufferLen = buffer.len
15
-
16
- -- Public -----------------------------------------------------------------
17
-
18
- local Optional = {}
19
-
20
- function Optional.optional(inner: Types.InternalCodec<any>): Types.InternalCodec<any>
21
- local codec: Types.InternalCodec<any> = {
22
- _isOptional = true,
23
- _inner = inner,
24
-
25
- write = function(ch: Types.ChannelState, value: any): ()
26
- if value == nil then
27
- writeByte(ch, 0)
28
- return
29
- end
30
- writeByte(ch, 1)
31
- inner.write(ch, value)
32
- end,
33
-
34
- read = function(src: buffer, pos: number, refs: { Instance }?): (any, number)
35
- Log.assert(pos < bufferLen(src), "presence byte missing at end of buffer")
36
- if readu8(src, pos) == 0 then
37
- return nil, 1
38
- end
39
- local value, consumed = inner.read(src, pos + 1, refs)
40
- return value, 1 + consumed
41
- end,
42
- }
43
-
44
- -- Propagate _hasUnknown so Gate skips schema validation upstream.
45
- if inner._hasUnknown then
46
- codec._hasUnknown = true
47
- end
48
- if Shared.containsDelta(inner) then
49
- codec._hasDelta = true
50
- end
51
- return table.freeze(codec)
52
- end
53
-
54
- return table.freeze(Optional)