@trioforge/crucible 0.1.0 → 0.2.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/out/client/index.d.ts +7 -0
- package/out/client/init.luau +36 -1
- package/out/configs.d.ts +37 -0
- package/out/configs.luau +46 -0
- package/out/data.d.ts +224 -0
- package/out/data.luau +97 -0
- package/out/emit/configs.d.ts +4 -0
- package/out/emit/configs.luau +22 -0
- package/out/emit/data.d.ts +6 -0
- package/out/emit/data.luau +19 -0
- package/out/emit/index.d.ts +5 -1
- package/out/emit/init.luau +23 -7
- package/out/emit/network.d.ts +6 -0
- package/out/emit/network.luau +36 -0
- package/out/emit/replicated.d.ts +4 -0
- package/out/emit/replicated.luau +13 -0
- package/out/index.d.ts +8 -0
- package/out/init.luau +23 -0
- package/out/internal/binding.luau +5 -0
- package/out/internal/boot.luau +107 -8
- package/out/internal/configs/limits.d.ts +10 -0
- package/out/internal/configs/limits.luau +25 -0
- package/out/internal/configs/port.d.ts +29 -0
- package/out/internal/configs/port.luau +99 -0
- package/out/internal/configs/runtime.d.ts +21 -0
- package/out/internal/configs/runtime.luau +981 -0
- package/out/internal/data/admission.d.ts +1 -0
- package/out/internal/data/admission.luau +673 -0
- package/out/internal/data/declarations.d.ts +1 -0
- package/out/internal/data/declarations.luau +384 -0
- package/out/internal/data/envelope.d.ts +1 -0
- package/out/internal/data/envelope.luau +318 -0
- package/out/internal/data/handles.d.ts +1 -0
- package/out/internal/data/handles.luau +255 -0
- package/out/internal/data/inbox-transforms.d.ts +1 -0
- package/out/internal/data/inbox-transforms.luau +458 -0
- package/out/internal/data/inbox.d.ts +1 -0
- package/out/internal/data/inbox.luau +437 -0
- package/out/internal/data/lease.d.ts +1 -0
- package/out/internal/data/lease.luau +304 -0
- package/out/internal/data/limits.d.ts +1 -0
- package/out/internal/data/limits.luau +234 -0
- package/out/internal/data/messages.d.ts +1 -0
- package/out/internal/data/messages.luau +69 -0
- package/out/internal/data/operation-id.d.ts +1 -0
- package/out/internal/data/operation-id.luau +61 -0
- package/out/internal/data/paths.d.ts +2 -0
- package/out/internal/data/paths.luau +323 -0
- package/out/internal/data/port.d.ts +1 -0
- package/out/internal/data/port.luau +290 -0
- package/out/internal/data/profiles.d.ts +1 -0
- package/out/internal/data/profiles.luau +862 -0
- package/out/internal/data/receipts.d.ts +1 -0
- package/out/internal/data/receipts.luau +190 -0
- package/out/internal/data/record-bindings.d.ts +1 -0
- package/out/internal/data/record-bindings.luau +92 -0
- package/out/internal/data/record-declarations.d.ts +1 -0
- package/out/internal/data/record-declarations.luau +140 -0
- package/out/internal/data/records.d.ts +1 -0
- package/out/internal/data/records.luau +400 -0
- package/out/internal/data/runtime.d.ts +1 -0
- package/out/internal/data/runtime.luau +918 -0
- package/out/internal/data/scheduler.d.ts +1 -0
- package/out/internal/data/scheduler.luau +507 -0
- package/out/internal/data/session.d.ts +1 -0
- package/out/internal/data/session.luau +234 -0
- package/out/internal/data/shutdown.d.ts +1 -0
- package/out/internal/data/shutdown.luau +91 -0
- package/out/internal/data/waiters.d.ts +1 -0
- package/out/internal/data/waiters.luau +65 -0
- package/out/internal/lifecycle.luau +45 -0
- package/out/internal/network/catalog.d.ts +26 -0
- package/out/internal/network/catalog.luau +182 -0
- package/out/internal/network/claims.d.ts +1 -0
- package/out/internal/network/claims.luau +154 -0
- package/out/internal/network/client-session.d.ts +1 -0
- package/out/internal/network/client-session.luau +403 -0
- package/out/internal/network/codec.d.ts +63 -0
- package/out/internal/network/codec.luau +1183 -0
- package/out/internal/network/envelope.d.ts +1 -0
- package/out/internal/network/envelope.luau +247 -0
- package/out/internal/network/limits.d.ts +26 -0
- package/out/internal/network/limits.luau +55 -0
- package/out/internal/network/port.d.ts +1 -0
- package/out/internal/network/port.luau +19 -0
- package/out/internal/network/roblox-network-port.d.ts +1 -0
- package/out/internal/network/roblox-network-port.luau +105 -0
- package/out/internal/network/schema.d.ts +72 -0
- package/out/internal/network/schema.luau +386 -0
- package/out/internal/network/server-session.d.ts +1 -0
- package/out/internal/network/server-session.luau +393 -0
- package/out/internal/network/session.d.ts +1 -0
- package/out/internal/network/session.luau +266 -0
- package/out/internal/reactive/context.d.ts +1 -0
- package/out/internal/reactive/context.luau +149 -0
- package/out/internal/reactive/flush.d.ts +1 -0
- package/out/internal/reactive/flush.luau +355 -0
- package/out/internal/reactive/graph.d.ts +1 -0
- package/out/internal/reactive/graph.luau +626 -0
- package/out/internal/reactive/limits.d.ts +1 -0
- package/out/internal/reactive/limits.luau +54 -0
- package/out/internal/reactive/ownership.d.ts +1 -0
- package/out/internal/reactive/ownership.luau +626 -0
- package/out/internal/registry.luau +10 -1
- package/out/internal/sync/client-sync.d.ts +1 -0
- package/out/internal/sync/client-sync.luau +157 -0
- package/out/internal/sync/declarations.d.ts +1 -0
- package/out/internal/sync/declarations.luau +276 -0
- package/out/internal/sync/frame.d.ts +1 -0
- package/out/internal/sync/frame.luau +91 -0
- package/out/internal/sync/server-sync.d.ts +1 -0
- package/out/internal/sync/server-sync.luau +502 -0
- package/out/internal/sync/values.d.ts +1 -0
- package/out/internal/sync/values.luau +930 -0
- package/out/network.d.ts +66 -0
- package/out/network.luau +24 -0
- package/out/reactive.d.ts +76 -0
- package/out/reactive.luau +136 -0
- package/out/replicated.d.ts +38 -0
- package/out/replicated.luau +45 -0
- package/out/server/data.d.ts +54 -0
- package/out/server/data.luau +44 -0
- package/out/server/index.d.ts +16 -0
- package/out/server/init.luau +49 -3
- package/out/server/publish.d.ts +20 -0
- package/out/server/publish.luau +24 -0
- package/out/vide/index.d.ts +7 -0
- package/out/vide/init.luau +50 -0
- package/package.json +13 -2
- package/transformer/data.cjs +72 -0
- package/transformer/declarations.cjs +153 -0
- package/transformer/index.js +37 -11
- package/transformer/network.cjs +961 -0
- package/vide/package.json +4 -0
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local YIELDED = TS.import(script, script.Parent.Parent, "runner").YIELDED
|
|
4
|
+
local _context = TS.import(script, script.Parent, "context")
|
|
5
|
+
local boundary = _context.boundary
|
|
6
|
+
local inBody = _context.inBody
|
|
7
|
+
local pop = _context.pop
|
|
8
|
+
local push = _context.push
|
|
9
|
+
local top = _context.top
|
|
10
|
+
--* @internal
|
|
11
|
+
--* @internal How far an observer is from trusting what it last read.
|
|
12
|
+
--* @internal
|
|
13
|
+
--* @internal
|
|
14
|
+
--* @internal
|
|
15
|
+
--* @internal
|
|
16
|
+
--* @internal
|
|
17
|
+
--* @internal The graph's view of an effect. The flush owns the rest of it.
|
|
18
|
+
--* @internal
|
|
19
|
+
--* @internal
|
|
20
|
+
local ids = 0
|
|
21
|
+
--* @internal Creation order, shared by every node and effect in the realm.
|
|
22
|
+
local function nextId()
|
|
23
|
+
ids += 1
|
|
24
|
+
return ids
|
|
25
|
+
end
|
|
26
|
+
--* @internal Flush rounds sort by it, so an owner's effect runs before the effects its runs created.
|
|
27
|
+
local function createdBefore(a, b)
|
|
28
|
+
return a.id < b.id
|
|
29
|
+
end
|
|
30
|
+
local epoch = 0
|
|
31
|
+
--* @internal Moves on every value-changing write in the realm.
|
|
32
|
+
local function currentEpoch()
|
|
33
|
+
return epoch
|
|
34
|
+
end
|
|
35
|
+
local schedule = function() end
|
|
36
|
+
--* @internal The flush registers how a marked effect is queued.
|
|
37
|
+
local function useScheduler(scheduler)
|
|
38
|
+
schedule = scheduler
|
|
39
|
+
end
|
|
40
|
+
--* @internal
|
|
41
|
+
local function originOf(callback)
|
|
42
|
+
local source, line = debug.info(callback, "sl")
|
|
43
|
+
return `{source}:{line}`
|
|
44
|
+
end
|
|
45
|
+
local thrown
|
|
46
|
+
local function capture(err)
|
|
47
|
+
thrown = {
|
|
48
|
+
reason = tostring(err),
|
|
49
|
+
message = debug.traceback(tostring(err), 2),
|
|
50
|
+
}
|
|
51
|
+
return nil
|
|
52
|
+
end
|
|
53
|
+
--* @internal Throws when the running thread is inside a computed, where `what` is not allowed.
|
|
54
|
+
local function guardPure(what)
|
|
55
|
+
local _pure = top()
|
|
56
|
+
if _pure ~= nil then
|
|
57
|
+
_pure = _pure.pure
|
|
58
|
+
end
|
|
59
|
+
local pure = _pure
|
|
60
|
+
if pure ~= nil then
|
|
61
|
+
error(`{pure} must not {what}`, 0)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
local function track(source)
|
|
65
|
+
local frame = top()
|
|
66
|
+
local _observer = frame
|
|
67
|
+
if _observer ~= nil then
|
|
68
|
+
_observer = _observer.observer
|
|
69
|
+
end
|
|
70
|
+
local observer = _observer
|
|
71
|
+
if observer == nil or observer == source then
|
|
72
|
+
return nil
|
|
73
|
+
end
|
|
74
|
+
local reads = frame.reads
|
|
75
|
+
local _source = source
|
|
76
|
+
if reads[_source] ~= nil then
|
|
77
|
+
return nil
|
|
78
|
+
end
|
|
79
|
+
local _source_1 = source
|
|
80
|
+
reads[_source_1] = true
|
|
81
|
+
local _deps = frame.deps
|
|
82
|
+
local _arg0 = {
|
|
83
|
+
source = source,
|
|
84
|
+
seen = source.version,
|
|
85
|
+
}
|
|
86
|
+
table.insert(_deps, _arg0)
|
|
87
|
+
end
|
|
88
|
+
--* @internal
|
|
89
|
+
local function observerFrame(kind, observer, lifetime)
|
|
90
|
+
return {
|
|
91
|
+
kind = kind,
|
|
92
|
+
observer = observer,
|
|
93
|
+
lifetime = lifetime,
|
|
94
|
+
pure = if kind == 1 then "computed" else nil,
|
|
95
|
+
deps = {},
|
|
96
|
+
reads = {},
|
|
97
|
+
}
|
|
98
|
+
end
|
|
99
|
+
--* @internal Calls `read` with no tracking. Ownership and purity stay those of the frame below.
|
|
100
|
+
local function readUntracked(read, pure)
|
|
101
|
+
local below = top()
|
|
102
|
+
local _object = {
|
|
103
|
+
kind = 2,
|
|
104
|
+
}
|
|
105
|
+
local _left = "lifetime"
|
|
106
|
+
local _result = below
|
|
107
|
+
if _result ~= nil then
|
|
108
|
+
_result = _result.lifetime
|
|
109
|
+
end
|
|
110
|
+
_object[_left] = _result
|
|
111
|
+
local _left_1 = "pure"
|
|
112
|
+
local _condition = pure
|
|
113
|
+
if _condition == nil then
|
|
114
|
+
local _result_1 = below
|
|
115
|
+
if _result_1 ~= nil then
|
|
116
|
+
_result_1 = _result_1.pure
|
|
117
|
+
end
|
|
118
|
+
_condition = _result_1
|
|
119
|
+
end
|
|
120
|
+
_object[_left_1] = _condition
|
|
121
|
+
local frame = _object
|
|
122
|
+
push(frame)
|
|
123
|
+
local ok, result = pcall(read)
|
|
124
|
+
pop(frame)
|
|
125
|
+
if not ok then
|
|
126
|
+
error(result, 0)
|
|
127
|
+
end
|
|
128
|
+
return result
|
|
129
|
+
end
|
|
130
|
+
--* @internal
|
|
131
|
+
local function createStateNode(value)
|
|
132
|
+
return {
|
|
133
|
+
kind = 0,
|
|
134
|
+
id = nextId(),
|
|
135
|
+
version = 0,
|
|
136
|
+
observers = {},
|
|
137
|
+
value = value,
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
--* @internal
|
|
141
|
+
local function readState(node)
|
|
142
|
+
track(node)
|
|
143
|
+
return node.value
|
|
144
|
+
end
|
|
145
|
+
--* @internal The one write path. Stores, bumps versions and marks; never runs user code or an effect.
|
|
146
|
+
local markObservers
|
|
147
|
+
local function write(node, value)
|
|
148
|
+
guardPure("write state")
|
|
149
|
+
if rawequal(value, node.value) then
|
|
150
|
+
return nil
|
|
151
|
+
end
|
|
152
|
+
node.value = value
|
|
153
|
+
node.version += 1
|
|
154
|
+
epoch += 1
|
|
155
|
+
markObservers(node)
|
|
156
|
+
end
|
|
157
|
+
--* @internal A node and the value it will hold.
|
|
158
|
+
--[[
|
|
159
|
+
*
|
|
160
|
+
* @internal
|
|
161
|
+
* Rule 62's write phase for client apply: assignments, version and epoch bumps, and marks that only enqueue. No
|
|
162
|
+
* purity guard, no admission and no user code, so nothing here can fail between two writes of one frame.
|
|
163
|
+
|
|
164
|
+
]]
|
|
165
|
+
local function commitPrepared(writes)
|
|
166
|
+
for _, _binding in writes do
|
|
167
|
+
local node = _binding[1]
|
|
168
|
+
local value = _binding[2]
|
|
169
|
+
if rawequal(value, node.value) then
|
|
170
|
+
continue
|
|
171
|
+
end
|
|
172
|
+
node.value = value
|
|
173
|
+
node.version += 1
|
|
174
|
+
epoch += 1
|
|
175
|
+
markObservers(node)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
--* @internal
|
|
179
|
+
local function update(node, change)
|
|
180
|
+
write(node, readUntracked(function()
|
|
181
|
+
return change(node.value)
|
|
182
|
+
end, "update's callback"))
|
|
183
|
+
end
|
|
184
|
+
function markObservers(source)
|
|
185
|
+
local pending = {}
|
|
186
|
+
local levels = {}
|
|
187
|
+
for o in source.observers do
|
|
188
|
+
table.insert(pending, o)
|
|
189
|
+
table.insert(levels, 2)
|
|
190
|
+
end
|
|
191
|
+
while #pending > 0 do
|
|
192
|
+
-- ▼ Array.pop ▼
|
|
193
|
+
local _length = #pending
|
|
194
|
+
local _result = pending[_length]
|
|
195
|
+
pending[_length] = nil
|
|
196
|
+
-- ▲ Array.pop ▲
|
|
197
|
+
local o = _result
|
|
198
|
+
-- ▼ Array.pop ▼
|
|
199
|
+
local _length_1 = #levels
|
|
200
|
+
local _result_1 = levels[_length_1]
|
|
201
|
+
levels[_length_1] = nil
|
|
202
|
+
-- ▲ Array.pop ▲
|
|
203
|
+
local level = _result_1
|
|
204
|
+
if o.mark >= level then
|
|
205
|
+
continue
|
|
206
|
+
end
|
|
207
|
+
local wasClean = o.mark == 0
|
|
208
|
+
o.mark = level
|
|
209
|
+
if o.kind == 2 then
|
|
210
|
+
schedule(o)
|
|
211
|
+
elseif wasClean then
|
|
212
|
+
for p in o.observers do
|
|
213
|
+
table.insert(pending, p)
|
|
214
|
+
table.insert(levels, 1)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
--* @internal
|
|
220
|
+
local function createComputedNode(read)
|
|
221
|
+
return {
|
|
222
|
+
kind = 1,
|
|
223
|
+
id = nextId(),
|
|
224
|
+
version = 0,
|
|
225
|
+
observers = {},
|
|
226
|
+
dependencies = {},
|
|
227
|
+
mark = 2,
|
|
228
|
+
read = read,
|
|
229
|
+
origin = originOf(read),
|
|
230
|
+
cache = {
|
|
231
|
+
kind = 0,
|
|
232
|
+
},
|
|
233
|
+
validatedAt = -1,
|
|
234
|
+
evaluating = false,
|
|
235
|
+
}
|
|
236
|
+
end
|
|
237
|
+
--* @internal
|
|
238
|
+
local validate
|
|
239
|
+
local function readComputed(node)
|
|
240
|
+
validate(node)
|
|
241
|
+
track(node)
|
|
242
|
+
local cache = node.cache
|
|
243
|
+
if cache.kind == 2 then
|
|
244
|
+
error(cache.message, 0)
|
|
245
|
+
end
|
|
246
|
+
return if cache.kind == 1 then cache.value else nil
|
|
247
|
+
end
|
|
248
|
+
local function cycle(node)
|
|
249
|
+
local message = `computed at {node.origin} reads itself`
|
|
250
|
+
node.cycle = message
|
|
251
|
+
error(message, 0)
|
|
252
|
+
end
|
|
253
|
+
--* @internal After it returns, `node.cache` and `node.version` are current.
|
|
254
|
+
local evaluate
|
|
255
|
+
function validate(node)
|
|
256
|
+
if node.evaluating then
|
|
257
|
+
cycle(node)
|
|
258
|
+
end
|
|
259
|
+
if node.cache.kind == 0 then
|
|
260
|
+
return evaluate(node)
|
|
261
|
+
end
|
|
262
|
+
-- ▼ ReadonlySet.size ▼
|
|
263
|
+
local _size = 0
|
|
264
|
+
for _ in node.observers do
|
|
265
|
+
_size += 1
|
|
266
|
+
end
|
|
267
|
+
-- ▲ ReadonlySet.size ▲
|
|
268
|
+
if _size == 0 then
|
|
269
|
+
if node.mark == 0 and node.validatedAt == epoch then
|
|
270
|
+
return nil
|
|
271
|
+
end
|
|
272
|
+
if node.mark == 0 then
|
|
273
|
+
node.mark = 1
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
if node.mark == 0 then
|
|
277
|
+
return nil
|
|
278
|
+
end
|
|
279
|
+
if node.mark == 1 then
|
|
280
|
+
local at = epoch
|
|
281
|
+
local moved = false
|
|
282
|
+
for _, edge in node.dependencies do
|
|
283
|
+
local source = edge.source
|
|
284
|
+
if source.kind == 1 then
|
|
285
|
+
validate(source)
|
|
286
|
+
end
|
|
287
|
+
if source.version ~= edge.seen then
|
|
288
|
+
moved = true
|
|
289
|
+
break
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
-- A dependency evaluated in its own boundary can drain lifecycle work that writes; then recompute.
|
|
293
|
+
if not moved and epoch == at then
|
|
294
|
+
node.mark = 0
|
|
295
|
+
node.validatedAt = at
|
|
296
|
+
return nil
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
evaluate(node)
|
|
300
|
+
end
|
|
301
|
+
--* Runs `read` under a Pure frame on this thread. A yield suspends the thread; its boundary finishes the node.
|
|
302
|
+
local settle
|
|
303
|
+
local function evaluateInline(evaluation)
|
|
304
|
+
local _binding = evaluation
|
|
305
|
+
local node = _binding.node
|
|
306
|
+
local frame = _binding.frame
|
|
307
|
+
push(frame)
|
|
308
|
+
node.evaluating = true
|
|
309
|
+
thrown = nil
|
|
310
|
+
local ok, result = xpcall(node.read, capture)
|
|
311
|
+
pop(frame)
|
|
312
|
+
local failure = if ok then nil else (thrown or {
|
|
313
|
+
reason = tostring(result),
|
|
314
|
+
message = tostring(result),
|
|
315
|
+
})
|
|
316
|
+
thrown = nil
|
|
317
|
+
settle(node, frame, result, failure)
|
|
318
|
+
end
|
|
319
|
+
local finishOpen
|
|
320
|
+
function evaluate(node)
|
|
321
|
+
local evaluation = {
|
|
322
|
+
node = node,
|
|
323
|
+
frame = observerFrame(1, node),
|
|
324
|
+
}
|
|
325
|
+
if inBody() then
|
|
326
|
+
evaluateInline(evaluation)
|
|
327
|
+
else
|
|
328
|
+
boundary(nil, nil, evaluateInline, evaluation, finishOpen)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
--* @internal Finishes every computed a body left open: its evaluation failed with the body's error.
|
|
332
|
+
function finishOpen(completion)
|
|
333
|
+
if #completion.open == 0 then
|
|
334
|
+
return nil
|
|
335
|
+
end
|
|
336
|
+
local message = tostring(completion.value)
|
|
337
|
+
local failure = {
|
|
338
|
+
reason = if completion.result == 2 then YIELDED else message,
|
|
339
|
+
message = message,
|
|
340
|
+
}
|
|
341
|
+
for _, frame in completion.open do
|
|
342
|
+
if frame.kind == 1 then
|
|
343
|
+
settle(frame.observer, frame, nil, failure)
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
local rewire
|
|
348
|
+
function settle(node, frame, result, thrownFailure)
|
|
349
|
+
node.evaluating = false
|
|
350
|
+
local failure = thrownFailure
|
|
351
|
+
if node.cycle ~= nil then
|
|
352
|
+
failure = {
|
|
353
|
+
reason = node.cycle,
|
|
354
|
+
message = node.cycle,
|
|
355
|
+
}
|
|
356
|
+
node.cycle = nil
|
|
357
|
+
end
|
|
358
|
+
local reads = frame.deps
|
|
359
|
+
local kept = reads
|
|
360
|
+
if failure ~= nil then
|
|
361
|
+
local _array = {}
|
|
362
|
+
local _length = #_array
|
|
363
|
+
table.move(reads, 1, #reads, _length + 1, _array)
|
|
364
|
+
kept = _array
|
|
365
|
+
for _, edge in node.dependencies do
|
|
366
|
+
local _reads = frame.reads
|
|
367
|
+
local _source = edge.source
|
|
368
|
+
if not (_reads[_source] ~= nil) then
|
|
369
|
+
local _kept = kept
|
|
370
|
+
local _arg0 = {
|
|
371
|
+
source = edge.source,
|
|
372
|
+
seen = edge.source.version,
|
|
373
|
+
}
|
|
374
|
+
table.insert(_kept, _arg0)
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
-- ▼ ReadonlySet.size ▼
|
|
379
|
+
local _size = 0
|
|
380
|
+
for _ in node.observers do
|
|
381
|
+
_size += 1
|
|
382
|
+
end
|
|
383
|
+
-- ▲ ReadonlySet.size ▲
|
|
384
|
+
if _size > 0 then
|
|
385
|
+
rewire(node, node.dependencies, kept)
|
|
386
|
+
end
|
|
387
|
+
node.dependencies = kept
|
|
388
|
+
local cache = node.cache
|
|
389
|
+
if failure ~= nil then
|
|
390
|
+
if cache.kind ~= 2 or cache.reason ~= failure.reason then
|
|
391
|
+
node.cache = {
|
|
392
|
+
kind = 2,
|
|
393
|
+
reason = failure.reason,
|
|
394
|
+
message = failure.message,
|
|
395
|
+
}
|
|
396
|
+
node.version += 1
|
|
397
|
+
end
|
|
398
|
+
elseif cache.kind ~= 1 or not rawequal(cache.value, result) then
|
|
399
|
+
node.cache = {
|
|
400
|
+
kind = 1,
|
|
401
|
+
value = result,
|
|
402
|
+
}
|
|
403
|
+
node.version += 1
|
|
404
|
+
end
|
|
405
|
+
node.mark = 0
|
|
406
|
+
node.validatedAt = epoch
|
|
407
|
+
end
|
|
408
|
+
--* A computed that gains its first observer registers on its sources, transitively.
|
|
409
|
+
local function attach(root)
|
|
410
|
+
local pending = { root }
|
|
411
|
+
while #pending > 0 do
|
|
412
|
+
-- ▼ Array.pop ▼
|
|
413
|
+
local _length = #pending
|
|
414
|
+
local _result = pending[_length]
|
|
415
|
+
pending[_length] = nil
|
|
416
|
+
-- ▲ Array.pop ▲
|
|
417
|
+
local node = _result
|
|
418
|
+
if node.mark == 0 and node.validatedAt ~= epoch then
|
|
419
|
+
node.mark = 1
|
|
420
|
+
end
|
|
421
|
+
for _, edge in node.dependencies do
|
|
422
|
+
local source = edge.source
|
|
423
|
+
-- ▼ ReadonlySet.size ▼
|
|
424
|
+
local _size = 0
|
|
425
|
+
for _1 in source.observers do
|
|
426
|
+
_size += 1
|
|
427
|
+
end
|
|
428
|
+
-- ▲ ReadonlySet.size ▲
|
|
429
|
+
local first = _size == 0
|
|
430
|
+
source.observers[node] = true
|
|
431
|
+
if first and source.kind == 1 then
|
|
432
|
+
table.insert(pending, source)
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
--* A computed that loses its last observer leaves its sources, transitively, and keeps its dependency list.
|
|
438
|
+
local function detach(root)
|
|
439
|
+
local pending = { root }
|
|
440
|
+
while #pending > 0 do
|
|
441
|
+
-- ▼ Array.pop ▼
|
|
442
|
+
local _length = #pending
|
|
443
|
+
local _result = pending[_length]
|
|
444
|
+
pending[_length] = nil
|
|
445
|
+
-- ▲ Array.pop ▲
|
|
446
|
+
local node = _result
|
|
447
|
+
if node.mark == 0 then
|
|
448
|
+
node.validatedAt = epoch
|
|
449
|
+
end
|
|
450
|
+
for _, edge in node.dependencies do
|
|
451
|
+
local source = edge.source
|
|
452
|
+
if not (source.observers[node] ~= nil) then
|
|
453
|
+
continue
|
|
454
|
+
end
|
|
455
|
+
source.observers[node] = nil
|
|
456
|
+
local _condition = source.kind == 1
|
|
457
|
+
if _condition then
|
|
458
|
+
-- ▼ ReadonlySet.size ▼
|
|
459
|
+
local _size = 0
|
|
460
|
+
for _1 in source.observers do
|
|
461
|
+
_size += 1
|
|
462
|
+
end
|
|
463
|
+
-- ▲ ReadonlySet.size ▲
|
|
464
|
+
_condition = _size == 0
|
|
465
|
+
end
|
|
466
|
+
if _condition then
|
|
467
|
+
table.insert(pending, source)
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
local function link(observer, source)
|
|
473
|
+
-- ▼ ReadonlySet.size ▼
|
|
474
|
+
local _size = 0
|
|
475
|
+
for _ in source.observers do
|
|
476
|
+
_size += 1
|
|
477
|
+
end
|
|
478
|
+
-- ▲ ReadonlySet.size ▲
|
|
479
|
+
local first = _size == 0
|
|
480
|
+
local _observers = source.observers
|
|
481
|
+
local _observer = observer
|
|
482
|
+
_observers[_observer] = true
|
|
483
|
+
if first and source.kind == 1 then
|
|
484
|
+
attach(source)
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
local function unlink(observer, source)
|
|
488
|
+
local _observers = source.observers
|
|
489
|
+
local _observer = observer
|
|
490
|
+
if not (_observers[_observer] ~= nil) then
|
|
491
|
+
return nil
|
|
492
|
+
end
|
|
493
|
+
local _observers_1 = source.observers
|
|
494
|
+
local _observer_1 = observer
|
|
495
|
+
_observers_1[_observer_1] = nil
|
|
496
|
+
local _condition = source.kind == 1
|
|
497
|
+
if _condition then
|
|
498
|
+
-- ▼ ReadonlySet.size ▼
|
|
499
|
+
local _size = 0
|
|
500
|
+
for _ in source.observers do
|
|
501
|
+
_size += 1
|
|
502
|
+
end
|
|
503
|
+
-- ▲ ReadonlySet.size ▲
|
|
504
|
+
_condition = _size == 0
|
|
505
|
+
end
|
|
506
|
+
if _condition then
|
|
507
|
+
detach(source)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
--* A rerun that read the same sources in the same order keeps every registration.
|
|
511
|
+
local function sameSources(previous, following)
|
|
512
|
+
local size = #previous
|
|
513
|
+
if #following ~= size then
|
|
514
|
+
return false
|
|
515
|
+
end
|
|
516
|
+
do
|
|
517
|
+
local i = 0
|
|
518
|
+
local _shouldIncrement = false
|
|
519
|
+
while true do
|
|
520
|
+
if _shouldIncrement then
|
|
521
|
+
i += 1
|
|
522
|
+
else
|
|
523
|
+
_shouldIncrement = true
|
|
524
|
+
end
|
|
525
|
+
if not (i < size) then
|
|
526
|
+
break
|
|
527
|
+
end
|
|
528
|
+
if previous[i + 1].source ~= following[i + 1].source then
|
|
529
|
+
return false
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
return true
|
|
534
|
+
end
|
|
535
|
+
--* @internal Moves an attached observer's registrations from `previous` to `following`.
|
|
536
|
+
function rewire(observer, previous, following)
|
|
537
|
+
if sameSources(previous, following) then
|
|
538
|
+
return nil
|
|
539
|
+
end
|
|
540
|
+
local had = {}
|
|
541
|
+
for _, edge in previous do
|
|
542
|
+
local _source = edge.source
|
|
543
|
+
had[_source] = true
|
|
544
|
+
end
|
|
545
|
+
local keep = {}
|
|
546
|
+
for _, edge in following do
|
|
547
|
+
local _source = edge.source
|
|
548
|
+
keep[_source] = true
|
|
549
|
+
local _source_1 = edge.source
|
|
550
|
+
if not (had[_source_1] ~= nil) then
|
|
551
|
+
link(observer, edge.source)
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
for _, edge in previous do
|
|
555
|
+
local _source = edge.source
|
|
556
|
+
if not (keep[_source] ~= nil) then
|
|
557
|
+
unlink(observer, edge.source)
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
--* @internal Leaves every source. Used when an effect stops.
|
|
562
|
+
local function releaseEdges(observer)
|
|
563
|
+
for _, edge in observer.dependencies do
|
|
564
|
+
unlink(observer, edge.source)
|
|
565
|
+
end
|
|
566
|
+
observer.dependencies = {}
|
|
567
|
+
end
|
|
568
|
+
--* @internal How far an effect is from current after a run: a source it read may have moved during the run.
|
|
569
|
+
local function staleAfterRun(effect)
|
|
570
|
+
local level = 0
|
|
571
|
+
for _, edge in effect.dependencies do
|
|
572
|
+
local source = edge.source
|
|
573
|
+
if source.version ~= edge.seen then
|
|
574
|
+
return 2
|
|
575
|
+
end
|
|
576
|
+
if source.kind == 1 and source.mark ~= 0 then
|
|
577
|
+
level = 1
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
return level
|
|
581
|
+
end
|
|
582
|
+
--* @internal Raises an effect's mark and queues it.
|
|
583
|
+
local function markEffect(effect, level)
|
|
584
|
+
if effect.mark >= level then
|
|
585
|
+
return nil
|
|
586
|
+
end
|
|
587
|
+
effect.mark = level
|
|
588
|
+
schedule(effect)
|
|
589
|
+
end
|
|
590
|
+
--* @internal Pulls an effect's computed dependencies current in read order. True when any of them moved.
|
|
591
|
+
local function dependenciesMoved(effect)
|
|
592
|
+
for _, edge in effect.dependencies do
|
|
593
|
+
local source = edge.source
|
|
594
|
+
if source.kind == 1 then
|
|
595
|
+
validate(source)
|
|
596
|
+
end
|
|
597
|
+
if source.version ~= edge.seen then
|
|
598
|
+
return true
|
|
599
|
+
end
|
|
600
|
+
end
|
|
601
|
+
return false
|
|
602
|
+
end
|
|
603
|
+
return {
|
|
604
|
+
nextId = nextId,
|
|
605
|
+
createdBefore = createdBefore,
|
|
606
|
+
currentEpoch = currentEpoch,
|
|
607
|
+
useScheduler = useScheduler,
|
|
608
|
+
originOf = originOf,
|
|
609
|
+
guardPure = guardPure,
|
|
610
|
+
observerFrame = observerFrame,
|
|
611
|
+
readUntracked = readUntracked,
|
|
612
|
+
createStateNode = createStateNode,
|
|
613
|
+
readState = readState,
|
|
614
|
+
write = write,
|
|
615
|
+
commitPrepared = commitPrepared,
|
|
616
|
+
update = update,
|
|
617
|
+
createComputedNode = createComputedNode,
|
|
618
|
+
readComputed = readComputed,
|
|
619
|
+
validate = validate,
|
|
620
|
+
finishOpen = finishOpen,
|
|
621
|
+
rewire = rewire,
|
|
622
|
+
releaseEdges = releaseEdges,
|
|
623
|
+
staleAfterRun = staleAfterRun,
|
|
624
|
+
markEffect = markEffect,
|
|
625
|
+
dependenciesMoved = dependenciesMoved,
|
|
626
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* @internal Runs one effect may make in one flush before it stops as a feedback loop.
|
|
3
|
+
local MAX_RUNS_PER_EFFECT = 64
|
|
4
|
+
--* @internal Effect runs in one flush, first runs included, before the rest waits for the next flush.
|
|
5
|
+
local MAX_EFFECT_RUNS_PER_FLUSH = 65_536
|
|
6
|
+
--* @internal Rounds in one flush before the rest waits for the next flush.
|
|
7
|
+
local MAX_FLUSH_ROUNDS = 256
|
|
8
|
+
--* @internal Live direct children of one generation lifetime before one warning names the owner.
|
|
9
|
+
local OWNER_CHILDREN_WARNING = 4_096
|
|
10
|
+
--* @internal Reserved for the UI layer's render commit, `Enum.RenderPriority.Last.Value + 1`. Nothing binds it yet.
|
|
11
|
+
local RENDER_COMMIT_PRIORITY = 2_001
|
|
12
|
+
--* @internal Replicated declarations one realm admits.
|
|
13
|
+
local MAX_REPLICATED_DECLARATIONS = 256
|
|
14
|
+
--* @internal Table nesting one replicated value may use, at compile time and at admission.
|
|
15
|
+
local SYNC_VALUE_DEPTH = 28
|
|
16
|
+
--* @internal Bytes in one string of a replicated value.
|
|
17
|
+
local SYNC_STRING_BYTES = 49_152
|
|
18
|
+
--* @internal Bytes in one whole sync frame packet. One value can never exceed it.
|
|
19
|
+
local SYNC_FRAME_BYTES = 196_608
|
|
20
|
+
--* @internal Collection entries in one sync frame.
|
|
21
|
+
local SYNC_FRAME_COLLECTION_ENTRIES = 12_000
|
|
22
|
+
--* @internal Codec value visits in one sync frame. Also bounds one structural comparison.
|
|
23
|
+
local SYNC_FRAME_VALUE_VISITS = 48_000
|
|
24
|
+
--* @internal Admission visits for one value: value nodes plus every table key touched.
|
|
25
|
+
local SYNC_ADMISSION_VISITS = 96_000
|
|
26
|
+
--* @internal Visits one peer examination may spend, the snapshot included.
|
|
27
|
+
local SYNC_PEER_VISITS = 262_144
|
|
28
|
+
--* @internal Frame bytes one Heartbeat sends to all peers, at least one frame.
|
|
29
|
+
local SYNC_HEARTBEAT_BYTES = 1_048_576
|
|
30
|
+
--* @internal Peers one Heartbeat examines, at least one.
|
|
31
|
+
local SYNC_HEARTBEAT_PEERS = 64
|
|
32
|
+
--* @internal A peer starts only while the Heartbeat has spent fewer visits than this. A threshold, not a ceiling.
|
|
33
|
+
local SYNC_HEARTBEAT_VISITS = 65_536
|
|
34
|
+
--* @internal The last revision a peer's frames may carry.
|
|
35
|
+
local SYNC_MAX_REVISION = 4_294_967_295
|
|
36
|
+
return {
|
|
37
|
+
MAX_RUNS_PER_EFFECT = MAX_RUNS_PER_EFFECT,
|
|
38
|
+
MAX_EFFECT_RUNS_PER_FLUSH = MAX_EFFECT_RUNS_PER_FLUSH,
|
|
39
|
+
MAX_FLUSH_ROUNDS = MAX_FLUSH_ROUNDS,
|
|
40
|
+
OWNER_CHILDREN_WARNING = OWNER_CHILDREN_WARNING,
|
|
41
|
+
RENDER_COMMIT_PRIORITY = RENDER_COMMIT_PRIORITY,
|
|
42
|
+
MAX_REPLICATED_DECLARATIONS = MAX_REPLICATED_DECLARATIONS,
|
|
43
|
+
SYNC_VALUE_DEPTH = SYNC_VALUE_DEPTH,
|
|
44
|
+
SYNC_STRING_BYTES = SYNC_STRING_BYTES,
|
|
45
|
+
SYNC_FRAME_BYTES = SYNC_FRAME_BYTES,
|
|
46
|
+
SYNC_FRAME_COLLECTION_ENTRIES = SYNC_FRAME_COLLECTION_ENTRIES,
|
|
47
|
+
SYNC_FRAME_VALUE_VISITS = SYNC_FRAME_VALUE_VISITS,
|
|
48
|
+
SYNC_ADMISSION_VISITS = SYNC_ADMISSION_VISITS,
|
|
49
|
+
SYNC_PEER_VISITS = SYNC_PEER_VISITS,
|
|
50
|
+
SYNC_HEARTBEAT_BYTES = SYNC_HEARTBEAT_BYTES,
|
|
51
|
+
SYNC_HEARTBEAT_PEERS = SYNC_HEARTBEAT_PEERS,
|
|
52
|
+
SYNC_HEARTBEAT_VISITS = SYNC_HEARTBEAT_VISITS,
|
|
53
|
+
SYNC_MAX_REVISION = SYNC_MAX_REVISION,
|
|
54
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|