@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,258 @@
1
+ --!strict
2
+ --!optimize 2
3
+ -- The descriptor: a schema as text, and the sixty-four bits a handshake carries it as.
4
+
5
+ local Base = require (script.Parent.Parent.codec.Base)
6
+ local Order = require (script.Parent.Order)
7
+ local Protocol = require (script.Parent.Parent.wire.Protocol)
8
+ local Wide = require (script.Parent.Parent.kernel.Wide)
9
+
10
+ local Serial = {}
11
+
12
+ -- Constants -----------------------------------------------------------
13
+
14
+ --[[
15
+ Built from hex rather than written as literals, because the basis is past the range a signed
16
+ literal covers and the string form is the one whose value is not parser-dependent.
17
+ ]]
18
+ const BASIS = Wide.parse ("CBF29CE484222325")
19
+ const PRIME = Wide.parse ("00000100000001B3")
20
+
21
+ -- Types ---------------------------------------------------------------
22
+
23
+ --[[
24
+ What a build carries that a descriptor is written from. A build holds the declaration it was
25
+ made from beside the closures it compiled, and only the declaration is read here, so whatever
26
+ else a build grows never moves the text.
27
+ ]]
28
+ export type Described = { read cell: Base.Cell }
29
+
30
+ -- The three ways a frame of a definition travels, and the one a caller gets free.
31
+ export type Delivery = "reliable" | "unreliable" | "newest"
32
+
33
+ --[[
34
+ A definition as the descriptor writes it, which is its codecs and every declaration that decides
35
+ how a frame of it travels.
36
+ ]]
37
+ export type Packet = {
38
+ read kind: "packet",
39
+ read of: Described,
40
+ read delivery: Delivery,
41
+ read hz: number?,
42
+ read timestamped: boolean,
43
+ }
44
+
45
+ export type Query = {
46
+ read kind: "query",
47
+ read of: Described,
48
+ read reply: Described,
49
+ }
50
+
51
+ export type Set = {
52
+ read kind: "set",
53
+ read of: Described,
54
+ read keyField: string?,
55
+ }
56
+
57
+ export type Frame = Packet | Query | Set
58
+
59
+ --[[
60
+ Every text one vocabulary reached, and the number each was first seen under. A rejection carries
61
+ the numbers rather than the words, because composing prose on a decode would pay for it at
62
+ whatever rate the other machine chooses, and the reader that catches one has this to read them
63
+ back out of.
64
+ ]]
65
+ export type Interner = {
66
+ at: { [string]: number },
67
+ texts: { string },
68
+ }
69
+
70
+ -- Private -------------------------------------------------------------
71
+
72
+ --[[
73
+ A number as text it reads back from. Fourteen digits is what a double usually needs and what
74
+ looks like the number a caller wrote, seventeen is what one always needs, and the round trip
75
+ decides which. Two parameters that differ have to differ here or two schemas share one hash.
76
+ ]]
77
+ local function decimal (value: number): string
78
+ if value == 0 then return "0" end
79
+
80
+ local short = string.format ("%.14g", value)
81
+ if tonumber (short) == value then return short end
82
+ return string.format ("%.17g", value)
83
+ end
84
+
85
+ --[[
86
+ A caller's string, quoted and escaped, because a symbol set holds any byte a caller likes and a
87
+ name any character. Left bare, a name holding a comma reads as two names and a field name
88
+ spelling `x=bool();y` reads as two fields, and either way two schemas write one text.
89
+ ]]
90
+ local function quoted (text: string): string
91
+ local slashed = string.gsub (text, "\\", "\\\\")
92
+ local marked = string.gsub (slashed, '"', '\\"')
93
+ return `"{marked}"`
94
+ end
95
+
96
+ -- A parameter holding several values is one slot still, so what it holds is bracketed inside it.
97
+ local function listed (parts: { string }): string return `[{table.concat (parts, ",")}]` end
98
+
99
+ local function vector (of: Vector3): string
100
+ return listed ({ decimal (of.X), decimal (of.Y), decimal (of.Z) })
101
+ end
102
+
103
+ local function colour (of: Color3): string
104
+ return listed ({ decimal (of.R), decimal (of.G), decimal (of.B) })
105
+ end
106
+
107
+ local function labelled (of: { string }): string
108
+ local parts = table.create (#of) :: { string }
109
+ for _, name in of do
110
+ table.insert (parts, quoted (name))
111
+ end
112
+ return listed (parts)
113
+ end
114
+
115
+ local function palette (of: { Color3 }): string
116
+ local parts = table.create (#of) :: { string }
117
+ for _, one in of do
118
+ table.insert (parts, colour (one))
119
+ end
120
+ return listed (parts)
121
+ end
122
+
123
+ --[[
124
+ Every parameter in one order, and the order is the one the surface takes them in, so each kind
125
+ comes out spelled the way a caller wrote it: `int(0,100)`, `str("abc",0,6)`, `vec3(unit,1)`,
126
+ `rotation(axis,[0,1,0],1)`. One list rather than a rule per kind, and it holds for all of them.
127
+ ]]
128
+ const ORDER: { { at: string, write: (any) -> string } } = {
129
+ { at = "form", write = function (of: any): string return of end },
130
+ { at = "symbols", write = quoted },
131
+ { at = "axis", write = vector },
132
+ { at = "min", write = decimal },
133
+ { at = "max", write = decimal },
134
+ { at = "step", write = decimal },
135
+ { at = "field", write = quoted },
136
+ { at = "class", write = quoted },
137
+ { at = "names", write = labelled },
138
+ { at = "colors", write = palette },
139
+ }
140
+
141
+ --[[
142
+ One node's own words: the kind, its parameters, and the marks. Every part comes off the
143
+ declaration and none off what was compiled from it, because two schemas that lower to the same
144
+ bytes are still two schemas.
145
+ ]]
146
+ local function spelled (cell: Base.Cell): string
147
+ local parts = {}
148
+ for _, slot in ORDER do
149
+ local held = (cell.params :: any)[slot.at]
150
+ if held ~= nil then table.insert (parts, slot.write (held)) end
151
+ end
152
+
153
+ local out = { cell.kind, "(", table.concat (parts, ","), ")" }
154
+
155
+ if cell.marker ~= "none" then
156
+ local rate = if cell.newestHz == nil then "" else `({decimal (cell.newestHz)})`
157
+ table.insert (out, `:{cell.marker}{rate}`)
158
+ end
159
+ for _ = 1, #cell.validates do
160
+ table.insert (out, ":validate")
161
+ end
162
+
163
+ return table.concat (out)
164
+ end
165
+
166
+ -- A whole codec as text, which is a node's own words and then its children under theirs.
167
+ local function written (cell: Base.Cell): string
168
+ local children = cell.children
169
+ if children == nil then return spelled (cell) end
170
+
171
+ local out = { spelled (cell), "{" }
172
+ for _, name in Order.names (children) do
173
+ table.insert (out, `{quoted (name)}={written (children[name])}`)
174
+ table.insert (out, ";")
175
+ end
176
+ table.insert (out, "}")
177
+
178
+ return table.concat (out)
179
+ end
180
+
181
+ -- Public --------------------------------------------------------------
182
+
183
+ function Serial.describe (of: Described): string return written (of.cell) end
184
+
185
+ -- A definition as its own text, which is what a handle prints and what a namespace carries it as.
186
+ function Serial.frame (of: Frame): string
187
+ if of.kind == "packet" then
188
+ local rate = decimal (if of.hz == nil then 0 else of.hz)
189
+ return `packet[{of.delivery},{rate},{of.timestamped}]({written (of.of.cell)})`
190
+ end
191
+
192
+ if of.kind == "query" then return `query({written (of.of.cell)})({written (of.reply.cell)})` end
193
+
194
+ local key = if of.keyField == nil then "" else quoted (of.keyField)
195
+ return `set[{key}]({written (of.of.cell)})`
196
+ end
197
+
198
+ --[[
199
+ A namespace as the one text two machines compare: the version, the name, and every definition
200
+ under the name it is reached by, in the order both of them sort those names into. The version
201
+ leads, so the hash binds the protocol version for free and a bump fails every handshake with no
202
+ bytes spent saying so.
203
+ ]]
204
+ function Serial.namespace (name: string, of: { [string]: Frame }): string
205
+ local out = { `{Protocol.VERSION}:{name}` }
206
+ for _, held in Order.names (of) do
207
+ table.insert (out, ";")
208
+ table.insert (out, `{held}={Serial.frame (of[held])}`)
209
+ end
210
+ return table.concat (out)
211
+ end
212
+
213
+ function Serial.interner (): Interner return { at = {}, texts = {} } end
214
+
215
+ --[[
216
+ A text, under the number it is reached by. The same text twice is the same number: a schema
217
+ names one expectation at a hundred fields and a table holding a hundred copies of it would be a
218
+ hundred strings a place keeps for the life of the session.
219
+ ]]
220
+ function Serial.intern (of: Interner, text: string): number
221
+ local held = of.at[text]
222
+ if held ~= nil then return held end
223
+
224
+ local id = #of.texts + 1
225
+ of.texts[id] = text
226
+ of.at[text] = id
227
+ return id
228
+ end
229
+
230
+ -- Where a child is, spelled from where its parent is.
231
+ function Serial.under (at: string, name: string): string return `{at}.{name}` end
232
+
233
+ -- Where a node is and what it wanted, as the two numbers a rejection carries.
234
+ function Serial.tagged (
235
+ paths: Interner,
236
+ expected: Interner,
237
+ at: string,
238
+ cell: Base.Cell
239
+ ): (number, number)
240
+ return Serial.intern (paths, at), Serial.intern (expected, spelled (cell))
241
+ end
242
+
243
+ --[[
244
+ A byte crosses into the carrier's domain before it is folded, because the exclusive or and the
245
+ multiply both refuse a bare number rather than lifting one. It is taken into a local first
246
+ because `string.byte` is typed as answering a variadic, and the crossing takes one number.
247
+ ]]
248
+ function Serial.hash (text: string): Wide.Word
249
+ local h = BASIS
250
+
251
+ for index = 1, #text do
252
+ local byte = string.byte (text, index)
253
+ h = Wide.mul (Wide.bxor (h, Wide.of (byte)), PRIME)
254
+ end
255
+ return h
256
+ end
257
+
258
+ return table.freeze (Serial)
@@ -0,0 +1,89 @@
1
+ --!strict
2
+ --!optimize 2
3
+ -- The windows a run of bit fields is cut into, and where each field sits in them.
4
+
5
+ local Protocol = require (script.Parent.Parent.wire.Protocol)
6
+
7
+ local Words = {}
8
+
9
+ -- Constants -----------------------------------------------------------
10
+
11
+ const BYTE = Protocol.BYTE_BITS
12
+
13
+ -- The windows a run is cut into, widest first, in bytes.
14
+ const WIDE = 4
15
+ const PAIR = 2
16
+ const ONE = 1
17
+
18
+ -- Types ---------------------------------------------------------------
19
+
20
+ --[[
21
+ A part carries its shift, which is how far up its field it starts, because the emitter places
22
+ each piece of a straddling field independently and deriving the shift would make every piece
23
+ depend on the one before it.
24
+ ]]
25
+ export type Part = {
26
+ read field: number,
27
+ read offset: number,
28
+ read width: number,
29
+ read shift: number,
30
+ }
31
+
32
+ export type Word = {
33
+ read bytes: number,
34
+ read at: number,
35
+ read parts: { Part },
36
+ }
37
+
38
+ -- Public --------------------------------------------------------------
39
+
40
+ -- The same three widths, named for whoever else lays a run down.
41
+ Words.WIDE = WIDE
42
+ Words.PAIR = PAIR
43
+ Words.ONE = ONE
44
+
45
+ -- The widest window the bits still fill, then the next, and a single byte for the remainder.
46
+ function Words.plan (widths: { number }): { Word }
47
+ local count = #widths
48
+
49
+ local left = 0
50
+ for _, width in widths do
51
+ left += width
52
+ end
53
+
54
+ local plan: { Word } = {}
55
+ local field, placed, at = 1, 0, 0
56
+
57
+ while left > 0 do
58
+ local bytes = if left >= WIDE * BYTE then WIDE elseif left >= PAIR * BYTE then PAIR else ONE
59
+ local room = bytes * BYTE
60
+
61
+ local parts: { Part } = {}
62
+ local offset = 0
63
+
64
+ while offset < room and field <= count do
65
+ local rest = widths[field] - placed
66
+ if rest == 0 then
67
+ field, placed = field + 1, 0
68
+ continue
69
+ end
70
+
71
+ local width = math.min (rest, room - offset)
72
+ table.insert (parts, { field = field, offset = offset, width = width, shift = placed })
73
+
74
+ offset += width
75
+ placed += width
76
+ if placed == widths[field] then
77
+ field, placed = field + 1, 0
78
+ end
79
+ end
80
+
81
+ table.insert (plan, { bytes = bytes, at = at, parts = parts })
82
+ at += bytes
83
+ left -= room
84
+ end
85
+
86
+ return plan
87
+ end
88
+
89
+ return table.freeze (Words)