@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
@@ -0,0 +1,441 @@
1
+ --!strict
2
+ --!optimize 2
3
+ -- One partition's flush: what it owes the wire, in order, cut to what a section holds.
4
+
5
+ local Coalesce = require (script.Parent.Coalesce)
6
+ local Protocol = require (script.Parent.Parent.wire.Protocol)
7
+ local Sections = require (script.Parent.Sections)
8
+ local Store = require (script.Parent.Store)
9
+ local Wide = require (script.Parent.Parent.kernel.Wide)
10
+
11
+ local Plan = {}
12
+
13
+ -- Constants -----------------------------------------------------------
14
+
15
+ const KEYFRAME = Protocol.SECTION_KEYFRAME
16
+ const DELTA = Protocol.SECTION_DELTA
17
+ const REMOVAL = Protocol.SECTION_REMOVAL
18
+ const CLEAR = Protocol.SECTION_CLEAR
19
+
20
+ -- What one section may carry.
21
+ const BOUND = Protocol.SECTION_BYTES
22
+
23
+ --[[
24
+ What the widest varint spends, which is what a slot is bounded by and so what an entry of a
25
+ removal costs and what the slot half of every other entry costs.
26
+ ]]
27
+ const WIDEST = Protocol.VARINT_GROUPS
28
+
29
+ const BYTE = Protocol.BYTE_BITS
30
+
31
+ const NONE = Wide.NONE
32
+
33
+ -- The stages a partition goes through, which is the order they are applied in.
34
+ const CLEARING = 1
35
+ const DROPPING = CLEARING + 1
36
+ const MAKING = DROPPING + 1
37
+ const MOVING = MAKING + 1
38
+ const SETTLED = MOVING + 1
39
+
40
+ -- What a field's coverage says: it changed on every slot the section lists, or it did not.
41
+ const COVERS = 1
42
+ const SOME = 0
43
+
44
+ -- What a record's field says about itself in a presence run, which is one bit either way.
45
+ const CARRIES = 1
46
+ const EMPTY = 0
47
+
48
+ -- Types ---------------------------------------------------------------
49
+
50
+ -- What one partition owes the wire, as a flush's mutations folded to their net effect.
51
+ export type Dirt = {
52
+ ops: { [number]: Coalesce.Kind },
53
+ masks: { [number]: Wide.Word },
54
+ freed: { [number]: number },
55
+ cleared: boolean,
56
+ }
57
+
58
+ -- One partition: which key it is, what it holds, and what it owes.
59
+ export type Partition = {
60
+ read key: any,
61
+ read store: Store.Store,
62
+ read dirt: Dirt,
63
+ }
64
+
65
+ -- What a flush may spend on state, and what it has spent.
66
+ export type Budget = {
67
+ read target: number,
68
+ spent: number,
69
+ took: boolean,
70
+ }
71
+
72
+ -- One set's planner: what a section of it costs, and the scratch one partition's flush fills.
73
+ export type Plan = {
74
+ read layout: Sections.Layout,
75
+ read bit: { integer },
76
+ read room: number,
77
+ read kinds: { number },
78
+ read cuts: { number },
79
+ read counts: { number },
80
+ read dropped: { number },
81
+ read made: { number },
82
+ read moved: { number },
83
+ read masks: { integer },
84
+ stage: number,
85
+ stop: number,
86
+ at: number,
87
+ }
88
+
89
+ -- Private -------------------------------------------------------------
90
+
91
+ -- A scratch list holding exactly what was put in it, which is what a sort reads its length from.
92
+ local function trimmed (of: { number }, count: number, was: number)
93
+ for index = count + 1, was do
94
+ of[index] = nil
95
+ end
96
+ end
97
+
98
+ -- How many entries of a delta fit one section, worked out per partition from the fields it moved.
99
+ local function fitted (of: Plan, whole: Wide.Word): number
100
+ local gained = of.layout.gained
101
+
102
+ local spent = 0
103
+ local selected = 0
104
+
105
+ local mask = whole
106
+ while Wide.any (mask) do
107
+ spent += gained[Wide.lowest (mask)]
108
+ selected += 1
109
+ mask = Wide.without (mask)
110
+ end
111
+
112
+ return of.room // (BYTE * (WIDEST + spent) + selected)
113
+ end
114
+
115
+ -- A removal's slots, which is the whole of what one carries.
116
+ local function removing (of: Plan, from: number, count: number)
117
+ local frame = of.layout.frame
118
+
119
+ frame.count = count
120
+ table.move (of.dropped, from, from + count - 1, 1, frame.slots)
121
+ end
122
+
123
+ -- A keyframe's slots, the records bound to them, and the generations those bindings stand at.
124
+ local function making (of: Plan, store: Store.Store, from: number, count: number)
125
+ local frame = of.layout.frame
126
+ local gens = store.gens
127
+ local ids = store.ids
128
+
129
+ frame.count = count
130
+ for index = 1, count do
131
+ local slot = of.made[from + index - 1]
132
+
133
+ frame.slots[index] = slot
134
+ frame.ids[index] = ids[slot]
135
+ if gens ~= nil then frame.gens[index] = gens[slot] end
136
+ end
137
+ end
138
+
139
+ -- A delta's slots, the fields they moved between them, and which of them each field reached.
140
+ local function moving (of: Plan, from: number, count: number)
141
+ local frame = of.layout.frame
142
+ local chosen = frame.chosen
143
+ local masks = of.masks
144
+
145
+ frame.count = count
146
+
147
+ local union = NONE
148
+ for index = 1, count do
149
+ local place = from + index - 1
150
+
151
+ frame.slots[index] = of.moved[place]
152
+ union = Wide.union (union, masks[place])
153
+ end
154
+
155
+ local reached = 0
156
+ local mask = union
157
+ while Wide.any (mask) do
158
+ local field = Wide.lowest (mask)
159
+ mask = Wide.without (mask)
160
+
161
+ reached += 1
162
+ chosen.fields[reached] = field
163
+
164
+ local one = of.bit[field]
165
+ local present = frame.present[reached]
166
+ local covered = 0
167
+
168
+ for index = 1, count do
169
+ local on = if Wide.meets (masks[from + index - 1], one) then CARRIES else EMPTY
170
+ present[index] = on
171
+ covered += on
172
+ end
173
+
174
+ chosen.full[reached] = if covered == count then COVERS else SOME
175
+ end
176
+
177
+ chosen.count = reached
178
+ end
179
+
180
+ -- The frame filled for whichever kind is next, which a clear does not have and the rest do.
181
+ local function filled (of: Plan, store: Store.Store, kind: number, from: number, count: number)
182
+ if kind == KEYFRAME then
183
+ making (of, store, from, count)
184
+ elseif kind == DELTA then
185
+ moving (of, from, count)
186
+ elseif kind == REMOVAL then
187
+ removing (of, from, count)
188
+ end
189
+ end
190
+
191
+ -- Whichever section the frame is filled for, laid down at the cursor it was handed.
192
+ local function laid (of: Plan, store: Store.Store, b: buffer, pos: number, kind: number): number
193
+ local layout = of.layout
194
+
195
+ if kind == KEYFRAME then return Sections.keyframe (layout, b, pos, store.columns) end
196
+ if kind == DELTA then return Sections.delta (layout, b, pos, store.columns, store.prev) end
197
+ if kind == REMOVAL then return Sections.removal (layout, b, pos) end
198
+
199
+ return Sections.clear (layout, b, pos)
200
+ end
201
+
202
+ -- The records a removal carried, taken off what the flush still owes.
203
+ local function released (of: Plan, dirt: Dirt, from: number, count: number)
204
+ for index = from, from + count - 1 do
205
+ local slot = of.dropped[index]
206
+ local id = dirt.freed[slot]
207
+ local op = dirt.ops[id]
208
+
209
+ dirt.freed[slot] = nil
210
+ if op == "replace" then
211
+ dirt.ops[id] = "add"
212
+ continue
213
+ end
214
+ if op == "add" then continue end
215
+
216
+ dirt.ops[id] = nil
217
+ dirt.masks[id] = nil
218
+ end
219
+ end
220
+
221
+ -- The records a keyframe or a delta carried, taken off what the flush still owes.
222
+ local function forgotten (
223
+ store: Store.Store,
224
+ dirt: Dirt,
225
+ slots: { number },
226
+ from: number,
227
+ count: number
228
+ )
229
+ for index = from, from + count - 1 do
230
+ local id = store.ids[slots[index] ]
231
+
232
+ dirt.ops[id] = nil
233
+ dirt.masks[id] = nil
234
+ end
235
+ end
236
+
237
+ local function retired (of: Plan, part: Partition, kind: number, from: number, count: number)
238
+ local dirt = part.dirt
239
+
240
+ if kind == CLEAR then
241
+ dirt.cleared = false
242
+ return
243
+ end
244
+
245
+ if kind == REMOVAL then
246
+ released (of, dirt, from, count)
247
+ return
248
+ end
249
+
250
+ forgotten (part.store, dirt, if kind == KEYFRAME then of.made else of.moved, from, count)
251
+ end
252
+
253
+ -- Which section is next and which of the gathered entries it takes, and the cursor moved past it.
254
+ local function staged (of: Plan, dirt: Dirt): (number, number, number)
255
+ if of.stage == CLEARING then
256
+ of.stage = DROPPING
257
+ of.at = 1
258
+
259
+ if dirt.cleared then return CLEAR, 0, 0 end
260
+ end
261
+
262
+ while of.stage <= of.stop do
263
+ local stage = of.stage
264
+ local left = of.counts[stage] - of.at + 1
265
+
266
+ if left > 0 then
267
+ local count = math.min (left, math.max (1, of.cuts[stage]))
268
+ local from = of.at
269
+
270
+ of.at += count
271
+ return of.kinds[stage], from, count
272
+ end
273
+
274
+ of.stage = stage + 1
275
+ of.at = 1
276
+ end
277
+
278
+ return SETTLED, 0, 0
279
+ end
280
+
281
+ -- Public --------------------------------------------------------------
282
+
283
+ -- How many whole records a keyframe of this set fits in the bytes it is handed.
284
+ function Plan.keyframes (of: Sections.Layout, bytes: number): number
285
+ return (math.min (bytes, BOUND) - of.opening) // of.entry
286
+ end
287
+
288
+ -- A set's planner, as the costs a section of it comes to and the scratch a partition fills.
289
+ function Plan.of (layout: Sections.Layout): Plan
290
+ local reach = layout.def.fieldCount
291
+ local bit = table.create (reach) :: { integer }
292
+
293
+ for field = 1, reach do
294
+ bit[field] = Coalesce.touched (NONE, field)
295
+ end
296
+
297
+ local spare = BOUND - layout.opening
298
+
299
+ return {
300
+ layout = layout,
301
+ bit = table.freeze (bit),
302
+ room = (spare - layout.set.widest) * BYTE,
303
+ kinds = table.freeze ({ [DROPPING] = REMOVAL, [MAKING] = KEYFRAME, [MOVING] = DELTA }),
304
+ cuts = {
305
+ [DROPPING] = spare // WIDEST,
306
+ [MAKING] = Plan.keyframes (layout, BOUND),
307
+ [MOVING] = 1,
308
+ },
309
+ counts = { [DROPPING] = 0, [MAKING] = 0, [MOVING] = 0 },
310
+ dropped = {},
311
+ made = {},
312
+ moved = {},
313
+ masks = {},
314
+ stage = SETTLED,
315
+ stop = SETTLED,
316
+ at = 1,
317
+ }
318
+ end
319
+
320
+ -- What a partition owes, empty, which a partition holds one of for as long as it exists.
321
+ function Plan.dirt (): Dirt return { ops = {}, masks = {}, freed = {}, cleared = false } end
322
+
323
+ -- What one flush of one namespace may spend on state, and what it has spent.
324
+ function Plan.budget (bytes: number): Budget return { target = bytes, spent = 0, took = false } end
325
+
326
+ -- The same one again, ready for another flush, for a caller that keeps one rather than making one.
327
+ function Plan.reset (of: Budget, bytes: number): Budget
328
+ local held = of :: { target: number, spent: number, took: boolean }
329
+ held.target, held.spent, held.took = bytes, 0, false
330
+
331
+ return of
332
+ end
333
+
334
+ --[[
335
+ Whether a flush has already spent what it was given, which both openers ask first.
336
+
337
+ What it keeps a full flush from doing is writing sections it is about to throw away, and it is
338
+ exact: the target is spent, so nothing further can fit whatever it costs.
339
+ ]]
340
+ local function spent (of: Budget): boolean return of.took and of.spent >= of.target end
341
+
342
+ -- A plan opened on one partition and one half of the order, which is what both halves share.
343
+ local function opening (of: Plan, part: Partition, from: number, to: number)
344
+ of.layout.frame.key = part.key
345
+ of.stage = from
346
+ of.stop = to
347
+ of.at = 1
348
+ end
349
+
350
+ -- What one partition takes away, gathered and put in order, and whether it takes anything.
351
+ function Plan.dropping (of: Plan, budget: Budget, part: Partition): boolean
352
+ if spent (budget) then return false end
353
+
354
+ local dirt = part.dirt
355
+
356
+ local fell = 0
357
+ for slot in dirt.freed do
358
+ fell += 1
359
+ of.dropped[fell] = slot
360
+ end
361
+
362
+ trimmed (of.dropped, fell, of.counts[DROPPING])
363
+ table.sort (of.dropped)
364
+
365
+ of.counts[DROPPING] = fell
366
+ opening (of, part, CLEARING, DROPPING)
367
+
368
+ return dirt.cleared or fell > 0
369
+ end
370
+
371
+ -- What one partition puts down, gathered and put in order, and whether it puts anything.
372
+ function Plan.making (of: Plan, budget: Budget, part: Partition): boolean
373
+ if spent (budget) then return false end
374
+
375
+ local store = part.store
376
+ local dirt = part.dirt
377
+ local counts = of.counts
378
+
379
+ local builds, shifts = 0, 0
380
+ local whole = NONE
381
+
382
+ for id, op in dirt.ops do
383
+ if op == "remove" then continue end
384
+
385
+ if op == "update" then
386
+ shifts += 1
387
+ of.moved[shifts] = store.slotOf[id]
388
+ whole = Wide.union (whole, dirt.masks[id])
389
+ continue
390
+ end
391
+
392
+ builds += 1
393
+ of.made[builds] = store.slotOf[id]
394
+ end
395
+
396
+ trimmed (of.made, builds, counts[MAKING])
397
+ trimmed (of.moved, shifts, counts[MOVING])
398
+
399
+ table.sort (of.made)
400
+ table.sort (of.moved)
401
+
402
+ for index = 1, shifts do
403
+ of.masks[index] = dirt.masks[store.ids[of.moved[index] ] ]
404
+ end
405
+
406
+ counts[MAKING], counts[MOVING] = builds, shifts
407
+ of.cuts[MOVING] = fitted (of, whole)
408
+ opening (of, part, MAKING, MOVING)
409
+
410
+ return builds + shifts > 0
411
+ end
412
+
413
+ -- The next section of the partition this was opened on, written at the cursor it was handed.
414
+ function Plan.next (
415
+ of: Plan,
416
+ budget: Budget,
417
+ part: Partition,
418
+ b: buffer,
419
+ pos: number
420
+ ): (number?, number)
421
+ local store = part.store
422
+ local kind, from, count = staged (of, part.dirt)
423
+ if kind == SETTLED then return nil, pos end
424
+
425
+ filled (of, store, kind, from, count)
426
+ local ends = laid (of, store, b, pos, kind)
427
+
428
+ local spent = ends - pos
429
+ if budget.took and budget.spent + spent > budget.target then
430
+ of.stage = SETTLED
431
+ return nil, pos
432
+ end
433
+
434
+ budget.spent += spent
435
+ budget.took = true
436
+
437
+ retired (of, part, kind, from, count)
438
+ return kind, ends
439
+ end
440
+
441
+ return table.freeze (Plan)