@trioforge/crucible 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/client/package.json +4 -0
- package/emit/package.json +4 -0
- package/out/all.d.ts +7 -0
- package/out/all.luau +2 -0
- package/out/attribute.d.ts +7 -0
- package/out/attribute.luau +7 -0
- package/out/client/index.d.ts +3 -0
- package/out/client/init.luau +20 -0
- package/out/crucible-behaviour.d.ts +16 -0
- package/out/crucible-behaviour.luau +78 -0
- package/out/crucible-object.d.ts +10 -0
- package/out/crucible-object.luau +69 -0
- package/out/emit/index.d.ts +41 -0
- package/out/emit/init.luau +85 -0
- package/out/index.d.ts +12 -0
- package/out/init.luau +11 -0
- package/out/inject.d.ts +1 -0
- package/out/inject.luau +7 -0
- package/out/internal/binding.d.ts +1 -0
- package/out/internal/binding.luau +610 -0
- package/out/internal/boot.d.ts +1 -0
- package/out/internal/boot.luau +463 -0
- package/out/internal/construction-claim.d.ts +1 -0
- package/out/internal/construction-claim.luau +26 -0
- package/out/internal/dense-list.d.ts +1 -0
- package/out/internal/dense-list.luau +155 -0
- package/out/internal/diagnostics.d.ts +1 -0
- package/out/internal/diagnostics.luau +29 -0
- package/out/internal/hooks.d.ts +1 -0
- package/out/internal/hooks.luau +53 -0
- package/out/internal/implementers.d.ts +1 -0
- package/out/internal/implementers.luau +119 -0
- package/out/internal/lifecycle.d.ts +1 -0
- package/out/internal/lifecycle.luau +867 -0
- package/out/internal/log-output.d.ts +1 -0
- package/out/internal/log-output.luau +106 -0
- package/out/internal/port.d.ts +1 -0
- package/out/internal/port.luau +12 -0
- package/out/internal/registry.d.ts +1 -0
- package/out/internal/registry.luau +446 -0
- package/out/internal/roblox-port.d.ts +1 -0
- package/out/internal/roblox-port.luau +117 -0
- package/out/internal/runner.d.ts +1 -0
- package/out/internal/runner.luau +86 -0
- package/out/internal/scheduler.d.ts +1 -0
- package/out/internal/scheduler.luau +207 -0
- package/out/internal/state.d.ts +1 -0
- package/out/internal/state.luau +41 -0
- package/out/log-level.d.ts +7 -0
- package/out/log-level.luau +21 -0
- package/out/logging.d.ts +34 -0
- package/out/logging.luau +233 -0
- package/out/server/index.d.ts +2 -0
- package/out/server/init.luau +16 -0
- package/out/subsystem.d.ts +4 -0
- package/out/subsystem.luau +30 -0
- package/package.json +41 -5
- package/server/package.json +4 -0
- package/transformer/diagnostics.cjs +19 -0
- package/transformer/index.js +715 -0
- package/transformer/type-id.cjs +80 -0
- package/README.md +0 -3
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local runtimeDiagnostic = TS.import(script, script.Parent, "diagnostics").runtimeDiagnostic
|
|
4
|
+
local Subsystem = TS.import(script, script.Parent.Parent, "subsystem").Subsystem
|
|
5
|
+
local CrucibleBehaviour = TS.import(script, script.Parent.Parent, "crucible-behaviour").CrucibleBehaviour
|
|
6
|
+
local _binding = TS.import(script, script.Parent, "binding")
|
|
7
|
+
local construct = _binding.construct
|
|
8
|
+
local forget = _binding.forget
|
|
9
|
+
local reconcile = _binding.reconcile
|
|
10
|
+
local useEngine = _binding.useEngine
|
|
11
|
+
local watch = _binding.watch
|
|
12
|
+
local _hooks = TS.import(script, script.Parent, "hooks")
|
|
13
|
+
local hooks = _hooks.hooks
|
|
14
|
+
local lifecycleHooks = _hooks.lifecycleHooks
|
|
15
|
+
local shutdownHooks = _hooks.shutdownHooks
|
|
16
|
+
local useImplementerPort = TS.import(script, script.Parent, "implementers").useImplementerPort
|
|
17
|
+
local _lifecycle = TS.import(script, script.Parent, "lifecycle")
|
|
18
|
+
local admit = _lifecycle.admit
|
|
19
|
+
local drain = _lifecycle.drain
|
|
20
|
+
local hasEnded = _lifecycle.hasEnded
|
|
21
|
+
local request = _lifecycle.request
|
|
22
|
+
local track = _lifecycle.track
|
|
23
|
+
local useEffects = _lifecycle.useEffects
|
|
24
|
+
local _registry = TS.import(script, script.Parent, "registry")
|
|
25
|
+
local records = _registry.records
|
|
26
|
+
local seal = _registry.seal
|
|
27
|
+
local robloxPort = TS.import(script, script.Parent, "roblox-port").robloxPort
|
|
28
|
+
local Scheduler = TS.import(script, script.Parent, "scheduler").Scheduler
|
|
29
|
+
--* @internal
|
|
30
|
+
local BOOT_CLASSES = { Subsystem, CrucibleBehaviour }
|
|
31
|
+
--* @internal
|
|
32
|
+
--* @internal
|
|
33
|
+
local PATTERN_PREFIX = "crucible-path:"
|
|
34
|
+
--* @internal
|
|
35
|
+
local SHUTDOWN_DEADLINE_SECONDS = 25
|
|
36
|
+
--* @internal
|
|
37
|
+
local SHUTDOWN_TIMEOUT_SECONDS = 28
|
|
38
|
+
--* @internal
|
|
39
|
+
local function parsePattern(pattern)
|
|
40
|
+
local _pattern = pattern
|
|
41
|
+
local _arg1 = #PATTERN_PREFIX
|
|
42
|
+
if string.sub(_pattern, 1, _arg1) ~= PATTERN_PREFIX then
|
|
43
|
+
error(`Crucible load needs the transformer: {pattern}`)
|
|
44
|
+
end
|
|
45
|
+
local _pattern_1 = pattern
|
|
46
|
+
local _arg0 = #PATTERN_PREFIX + 1
|
|
47
|
+
local segments = string.split(string.sub(_pattern_1, _arg0), "/")
|
|
48
|
+
-- ▼ ReadonlyArray.some ▼
|
|
49
|
+
local _result = false
|
|
50
|
+
local _callback = function(s)
|
|
51
|
+
return s == "" or s == "." or s == ".."
|
|
52
|
+
end
|
|
53
|
+
for _k, _v in segments do
|
|
54
|
+
if _callback(_v, _k - 1, segments) then
|
|
55
|
+
_result = true
|
|
56
|
+
break
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
-- ▲ ReadonlyArray.some ▲
|
|
60
|
+
if _result then
|
|
61
|
+
error(`Invalid Crucible load pattern: {pattern}`)
|
|
62
|
+
end
|
|
63
|
+
return segments
|
|
64
|
+
end
|
|
65
|
+
local function matches(name, pattern)
|
|
66
|
+
local open = string.find(pattern, "{", 1, true)
|
|
67
|
+
if open ~= nil then
|
|
68
|
+
local close = string.find(pattern, "}", open, true)
|
|
69
|
+
if close == nil then
|
|
70
|
+
error(`Invalid Crucible name pattern: {pattern}`)
|
|
71
|
+
end
|
|
72
|
+
local _pattern = pattern
|
|
73
|
+
local _arg0 = open + 1
|
|
74
|
+
local _arg1 = close - 1
|
|
75
|
+
local _exp = string.split(string.sub(_pattern, _arg0, _arg1), ",")
|
|
76
|
+
-- ▼ ReadonlyArray.some ▼
|
|
77
|
+
local _result = false
|
|
78
|
+
local _callback = function(part)
|
|
79
|
+
local _exp_1 = name
|
|
80
|
+
local _pattern_1 = pattern
|
|
81
|
+
local _arg1_1 = open - 1
|
|
82
|
+
local _exp_2 = string.sub(_pattern_1, 1, _arg1_1) .. part
|
|
83
|
+
local _pattern_2 = pattern
|
|
84
|
+
local _arg0_1 = close + 1
|
|
85
|
+
return matches(_exp_1, _exp_2 .. string.sub(_pattern_2, _arg0_1))
|
|
86
|
+
end
|
|
87
|
+
for _k, _v in _exp do
|
|
88
|
+
if _callback(_v, _k - 1, _exp) then
|
|
89
|
+
_result = true
|
|
90
|
+
break
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
-- ▲ ReadonlyArray.some ▲
|
|
94
|
+
return _result
|
|
95
|
+
end
|
|
96
|
+
local star = string.find(pattern, "*", 1, true)
|
|
97
|
+
if star == nil then
|
|
98
|
+
return name == pattern
|
|
99
|
+
end
|
|
100
|
+
local _pattern = pattern
|
|
101
|
+
local _arg1 = star - 1
|
|
102
|
+
local prefix = string.sub(_pattern, 1, _arg1)
|
|
103
|
+
local _name = name
|
|
104
|
+
local _arg1_1 = #prefix
|
|
105
|
+
if string.sub(_name, 1, _arg1_1) ~= prefix then
|
|
106
|
+
return false
|
|
107
|
+
end
|
|
108
|
+
for i = #prefix, #name do
|
|
109
|
+
local _name_1 = name
|
|
110
|
+
local _arg0 = i + 1
|
|
111
|
+
local _exp = string.sub(_name_1, _arg0)
|
|
112
|
+
local _pattern_1 = pattern
|
|
113
|
+
local _arg0_1 = star + 1
|
|
114
|
+
if matches(_exp, string.sub(_pattern_1, _arg0_1)) then
|
|
115
|
+
return true
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
return false
|
|
119
|
+
end
|
|
120
|
+
--* @internal
|
|
121
|
+
local function load(patterns)
|
|
122
|
+
local found = {}
|
|
123
|
+
local function walk(node, segments, index)
|
|
124
|
+
if index == #segments then
|
|
125
|
+
if node:IsA("ModuleScript") then
|
|
126
|
+
local _node = node
|
|
127
|
+
found[_node] = true
|
|
128
|
+
end
|
|
129
|
+
return nil
|
|
130
|
+
end
|
|
131
|
+
local segment = segments[index + 1]
|
|
132
|
+
if segment == "**" then
|
|
133
|
+
walk(node, segments, index + 1)
|
|
134
|
+
end
|
|
135
|
+
for _, child in node:GetChildren() do
|
|
136
|
+
if segment == "**" then
|
|
137
|
+
walk(child, segments, index)
|
|
138
|
+
elseif matches(child.Name, segment) then
|
|
139
|
+
walk(child, segments, index + 1)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
for _, pattern in patterns do
|
|
144
|
+
local segments = parsePattern(pattern)
|
|
145
|
+
walk(game:GetService(segments[1]), segments, 1)
|
|
146
|
+
end
|
|
147
|
+
local _array = {}
|
|
148
|
+
local _length = #_array
|
|
149
|
+
for _v in found do
|
|
150
|
+
_length += 1
|
|
151
|
+
_array[_length] = _v
|
|
152
|
+
end
|
|
153
|
+
local modules = _array
|
|
154
|
+
table.sort(modules, function(a, b)
|
|
155
|
+
return a:GetFullName() < b:GetFullName()
|
|
156
|
+
end)
|
|
157
|
+
for _, module in modules do
|
|
158
|
+
require(module)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
local HOOK_NAMES = { "constructor", "awake", "onEnable", "start", "onDisable", "onDestroy", "a frame hook", "accepts", "an All<T> callback", "settle", "cancel", "internal" }
|
|
162
|
+
local function where(port, s)
|
|
163
|
+
local id = (s.record).id
|
|
164
|
+
return if s.instance == nil then id else `{id} on {port.describe(s.instance)}`
|
|
165
|
+
end
|
|
166
|
+
local function describeFault(port, s)
|
|
167
|
+
local fault = s.fault
|
|
168
|
+
local message = `{where(port, s)} faulted in {HOOK_NAMES[fault.hook + 1]}: {tostring(fault.error)}`
|
|
169
|
+
for _, later in fault.cleanup do
|
|
170
|
+
message ..= `\n then {HOOK_NAMES[later.hook + 1]} failed: {tostring(later.error)}`
|
|
171
|
+
end
|
|
172
|
+
return message
|
|
173
|
+
end
|
|
174
|
+
local function hookCaller(s, hook)
|
|
175
|
+
if hook == 1 then
|
|
176
|
+
return function(s)
|
|
177
|
+
return hooks().awake(s.object, 0)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
if s.record.kind ~= 1 then
|
|
181
|
+
return nil
|
|
182
|
+
end
|
|
183
|
+
if hook == 2 then
|
|
184
|
+
return function(s)
|
|
185
|
+
return lifecycleHooks().onEnable(s.object, 0)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
if hook == 4 then
|
|
189
|
+
return function(s)
|
|
190
|
+
return lifecycleHooks().onDisable(s.object, 0)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
if hook == 5 then
|
|
194
|
+
return function(s)
|
|
195
|
+
return lifecycleHooks().onDestroy(s.object, 0)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
return nil
|
|
199
|
+
end
|
|
200
|
+
local function shutdown(port, order)
|
|
201
|
+
local started = {}
|
|
202
|
+
local finished = {}
|
|
203
|
+
local dependents = {}
|
|
204
|
+
for _, record in order do
|
|
205
|
+
dependents[record] = {}
|
|
206
|
+
end
|
|
207
|
+
for _, record in order do
|
|
208
|
+
for _1, dep in record.resolved do
|
|
209
|
+
if not dep.all then
|
|
210
|
+
local _record = dep.record
|
|
211
|
+
local _exp = dependents[_record]
|
|
212
|
+
table.insert(_exp, record)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
local startTime = port.clock()
|
|
217
|
+
while true do
|
|
218
|
+
-- ▼ ReadonlySet.size ▼
|
|
219
|
+
local _size = 0
|
|
220
|
+
for _ in finished do
|
|
221
|
+
_size += 1
|
|
222
|
+
end
|
|
223
|
+
-- ▲ ReadonlySet.size ▲
|
|
224
|
+
if not (_size < #order) then
|
|
225
|
+
break
|
|
226
|
+
end
|
|
227
|
+
local expired = port.clock() - startTime >= SHUTDOWN_DEADLINE_SECONDS
|
|
228
|
+
for _, record in order do
|
|
229
|
+
local _condition = started[record] ~= nil
|
|
230
|
+
if not _condition then
|
|
231
|
+
local _condition_1 = not expired
|
|
232
|
+
if _condition_1 then
|
|
233
|
+
local _exp = dependents[record]
|
|
234
|
+
-- ▼ ReadonlyArray.every ▼
|
|
235
|
+
local _result = true
|
|
236
|
+
local _callback = function(r)
|
|
237
|
+
local _r = r
|
|
238
|
+
return finished[_r] ~= nil
|
|
239
|
+
end
|
|
240
|
+
for _k, _v in _exp do
|
|
241
|
+
if not _callback(_v, _k - 1, _exp) then
|
|
242
|
+
_result = false
|
|
243
|
+
break
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
-- ▲ ReadonlyArray.every ▲
|
|
247
|
+
_condition_1 = not _result
|
|
248
|
+
end
|
|
249
|
+
_condition = _condition_1
|
|
250
|
+
end
|
|
251
|
+
if _condition then
|
|
252
|
+
continue
|
|
253
|
+
end
|
|
254
|
+
started[record] = true
|
|
255
|
+
port.spawn(function()
|
|
256
|
+
local _object = record.state
|
|
257
|
+
if _object ~= nil then
|
|
258
|
+
_object = _object.object
|
|
259
|
+
end
|
|
260
|
+
local object = _object
|
|
261
|
+
if object ~= nil then
|
|
262
|
+
local ok, err = xpcall(function()
|
|
263
|
+
return shutdownHooks().onShutdown(object)
|
|
264
|
+
end, function(err)
|
|
265
|
+
return debug.traceback(tostring(err), 2)
|
|
266
|
+
end)
|
|
267
|
+
if not ok then
|
|
268
|
+
runtimeDiagnostic("error", `{record.id} onShutdown failed: {err}`)
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
finished[record] = true
|
|
272
|
+
end)
|
|
273
|
+
end
|
|
274
|
+
if port.clock() - startTime >= SHUTDOWN_TIMEOUT_SECONDS then
|
|
275
|
+
return nil
|
|
276
|
+
end
|
|
277
|
+
-- ▼ ReadonlySet.size ▼
|
|
278
|
+
local _size_1 = 0
|
|
279
|
+
for _ in finished do
|
|
280
|
+
_size_1 += 1
|
|
281
|
+
end
|
|
282
|
+
-- ▲ ReadonlySet.size ▲
|
|
283
|
+
if _size_1 < #order then
|
|
284
|
+
port.wait()
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
--* @internal
|
|
289
|
+
local function ignite(port, side, options)
|
|
290
|
+
local singletons = seal({
|
|
291
|
+
renders = side.renders,
|
|
292
|
+
})
|
|
293
|
+
local frame = hooks().frame
|
|
294
|
+
local _exp = port
|
|
295
|
+
local _object = {}
|
|
296
|
+
local _left = "fixedRate"
|
|
297
|
+
local _condition = options.fixedRate
|
|
298
|
+
if _condition == nil then
|
|
299
|
+
_condition = 60
|
|
300
|
+
end
|
|
301
|
+
_object[_left] = _condition
|
|
302
|
+
_object.renders = side.renders
|
|
303
|
+
local scheduler = Scheduler.new(_exp, _object, {
|
|
304
|
+
[0] = function(o, dt)
|
|
305
|
+
return frame[0](o, dt)
|
|
306
|
+
end,
|
|
307
|
+
[1] = function(o, dt)
|
|
308
|
+
return frame[1](o, dt)
|
|
309
|
+
end,
|
|
310
|
+
[2] = function(o, dt)
|
|
311
|
+
return frame[2](o, dt)
|
|
312
|
+
end,
|
|
313
|
+
[3] = function(o, dt)
|
|
314
|
+
return frame[3](o, dt)
|
|
315
|
+
end,
|
|
316
|
+
})
|
|
317
|
+
local owned = {}
|
|
318
|
+
local stage = "booting"
|
|
319
|
+
local failure
|
|
320
|
+
local stop = function() end
|
|
321
|
+
local function reject(message)
|
|
322
|
+
if stage ~= "booting" then
|
|
323
|
+
return nil
|
|
324
|
+
end
|
|
325
|
+
failure = message
|
|
326
|
+
stage = "rollback"
|
|
327
|
+
stop()
|
|
328
|
+
for state in owned do
|
|
329
|
+
request(state, 2)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
useEngine(port)
|
|
333
|
+
useImplementerPort(port)
|
|
334
|
+
useEffects({
|
|
335
|
+
construct = function(s)
|
|
336
|
+
if stage == "booting" then
|
|
337
|
+
local _s = s
|
|
338
|
+
owned[_s] = true
|
|
339
|
+
end
|
|
340
|
+
return construct(s)
|
|
341
|
+
end,
|
|
342
|
+
hook = hookCaller,
|
|
343
|
+
start = function(s)
|
|
344
|
+
return hooks().start(s.object, 0)
|
|
345
|
+
end,
|
|
346
|
+
join = function(s)
|
|
347
|
+
for _, set in (s.record).memberOf do
|
|
348
|
+
set:join(s.object)
|
|
349
|
+
end
|
|
350
|
+
end,
|
|
351
|
+
leave = function(s)
|
|
352
|
+
for _, set in (s.record).memberOf do
|
|
353
|
+
set:leave(s.object)
|
|
354
|
+
end
|
|
355
|
+
end,
|
|
356
|
+
tick = function(s)
|
|
357
|
+
return scheduler:add(s)
|
|
358
|
+
end,
|
|
359
|
+
untick = function(s)
|
|
360
|
+
return scheduler:remove(s)
|
|
361
|
+
end,
|
|
362
|
+
reconcile = function()
|
|
363
|
+
if stage == "rollback" then
|
|
364
|
+
return {}
|
|
365
|
+
end
|
|
366
|
+
local created = reconcile()
|
|
367
|
+
if stage == "booting" then
|
|
368
|
+
for _, s in created do
|
|
369
|
+
owned[s] = true
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
return created
|
|
373
|
+
end,
|
|
374
|
+
ended = function(s)
|
|
375
|
+
forget(s)
|
|
376
|
+
if s.fault == nil then
|
|
377
|
+
return nil
|
|
378
|
+
end
|
|
379
|
+
local message = describeFault(port, s)
|
|
380
|
+
runtimeDiagnostic("error", message)
|
|
381
|
+
if s.record.kind == 0 then
|
|
382
|
+
reject(message)
|
|
383
|
+
end
|
|
384
|
+
end,
|
|
385
|
+
defer = port.defer,
|
|
386
|
+
cancel = port.cancel,
|
|
387
|
+
failed = function(message)
|
|
388
|
+
runtimeDiagnostic("error", message)
|
|
389
|
+
reject(message)
|
|
390
|
+
end,
|
|
391
|
+
diagnose = function(s, hook, err)
|
|
392
|
+
return runtimeDiagnostic("error", `{where(port, s)} {HOOK_NAMES[hook + 1]} failed: {tostring(err)}`)
|
|
393
|
+
end,
|
|
394
|
+
})
|
|
395
|
+
local ok, err = pcall(function()
|
|
396
|
+
local _exp_1 = records()
|
|
397
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
398
|
+
local _newValue = {}
|
|
399
|
+
local _callback = function(r)
|
|
400
|
+
return r.kind == 1
|
|
401
|
+
end
|
|
402
|
+
local _length = 0
|
|
403
|
+
for _k, _v in _exp_1 do
|
|
404
|
+
if _callback(_v, _k - 1, _exp_1) == true then
|
|
405
|
+
_length += 1
|
|
406
|
+
_newValue[_length] = _v
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
410
|
+
stop = watch(_newValue)
|
|
411
|
+
-- ▼ ReadonlyArray.map ▼
|
|
412
|
+
local _newValue_1 = table.create(#singletons)
|
|
413
|
+
local _callback_1 = function(r)
|
|
414
|
+
local s = track(r)
|
|
415
|
+
r.state = s
|
|
416
|
+
owned[s] = true
|
|
417
|
+
return s
|
|
418
|
+
end
|
|
419
|
+
for _k, _v in singletons do
|
|
420
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, singletons)
|
|
421
|
+
end
|
|
422
|
+
-- ▲ ReadonlyArray.map ▲
|
|
423
|
+
local initial = _newValue_1
|
|
424
|
+
admit(initial)
|
|
425
|
+
drain()
|
|
426
|
+
end)
|
|
427
|
+
if not ok then
|
|
428
|
+
reject(tostring(err))
|
|
429
|
+
end
|
|
430
|
+
if failure ~= nil then
|
|
431
|
+
for s in owned do
|
|
432
|
+
if not hasEnded(s) then
|
|
433
|
+
request(s, 2)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
drain()
|
|
437
|
+
table.clear(owned)
|
|
438
|
+
error(`Crucible boot failed: {failure}`, 0)
|
|
439
|
+
end
|
|
440
|
+
stage = "committed"
|
|
441
|
+
table.clear(owned)
|
|
442
|
+
if side.name == "server" then
|
|
443
|
+
port.bindToClose(function()
|
|
444
|
+
return shutdown(port, singletons)
|
|
445
|
+
end)
|
|
446
|
+
end
|
|
447
|
+
side.booted()
|
|
448
|
+
end
|
|
449
|
+
--* @internal
|
|
450
|
+
local function boot(side, options)
|
|
451
|
+
load(options.load)
|
|
452
|
+
ignite(robloxPort(), side, options)
|
|
453
|
+
end
|
|
454
|
+
return {
|
|
455
|
+
parsePattern = parsePattern,
|
|
456
|
+
load = load,
|
|
457
|
+
ignite = ignite,
|
|
458
|
+
boot = boot,
|
|
459
|
+
BOOT_CLASSES = BOOT_CLASSES,
|
|
460
|
+
PATTERN_PREFIX = PATTERN_PREFIX,
|
|
461
|
+
SHUTDOWN_DEADLINE_SECONDS = SHUTDOWN_DEADLINE_SECONDS,
|
|
462
|
+
SHUTDOWN_TIMEOUT_SECONDS = SHUTDOWN_TIMEOUT_SECONDS,
|
|
463
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local claims = {}
|
|
3
|
+
--* @internal
|
|
4
|
+
local function setClaim(state)
|
|
5
|
+
local _arg0 = coroutine.running()
|
|
6
|
+
local _state = state
|
|
7
|
+
claims[_arg0] = _state
|
|
8
|
+
end
|
|
9
|
+
--* @internal
|
|
10
|
+
local function readClaim()
|
|
11
|
+
local _arg0 = coroutine.running()
|
|
12
|
+
return claims[_arg0]
|
|
13
|
+
end
|
|
14
|
+
--* @internal
|
|
15
|
+
local function clearClaim(thread)
|
|
16
|
+
if thread == nil then
|
|
17
|
+
thread = coroutine.running()
|
|
18
|
+
end
|
|
19
|
+
local _thread = thread
|
|
20
|
+
claims[_thread] = nil
|
|
21
|
+
end
|
|
22
|
+
return {
|
|
23
|
+
setClaim = setClaim,
|
|
24
|
+
readClaim = readClaim,
|
|
25
|
+
clearClaim = clearClaim,
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function walk(items, stop, visit)
|
|
3
|
+
do
|
|
4
|
+
local i = 0
|
|
5
|
+
local _shouldIncrement = false
|
|
6
|
+
while true do
|
|
7
|
+
if _shouldIncrement then
|
|
8
|
+
i += 1
|
|
9
|
+
else
|
|
10
|
+
_shouldIncrement = true
|
|
11
|
+
end
|
|
12
|
+
if not (i < stop) then
|
|
13
|
+
break
|
|
14
|
+
end
|
|
15
|
+
local item = items[i + 1]
|
|
16
|
+
if item ~= nil then
|
|
17
|
+
visit(item)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
--[[
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
* Ordered list with O(1) append, O(1) removal by tombstone, and allocation-free iteration. Holes are
|
|
26
|
+
* `end - count`. An append always writes at `end`, so no slot is reused until compaction, which runs outside a
|
|
27
|
+
* walk once holes pass half the slots. Outside a walk `end <= 2 * count`, so a walk touches at most twice the
|
|
28
|
+
* members and compaction costs at most twice the removals. Iteration order is insertion order and survives any
|
|
29
|
+
* mutation from inside a visit. Items appended during `forEach` are visited by the next call, not this one.
|
|
30
|
+
|
|
31
|
+
]]
|
|
32
|
+
local DenseList
|
|
33
|
+
do
|
|
34
|
+
DenseList = setmetatable({}, {
|
|
35
|
+
__tostring = function()
|
|
36
|
+
return "DenseList"
|
|
37
|
+
end,
|
|
38
|
+
})
|
|
39
|
+
DenseList.__index = DenseList
|
|
40
|
+
function DenseList.new(...)
|
|
41
|
+
local self = setmetatable({}, DenseList)
|
|
42
|
+
return self:constructor(...) or self
|
|
43
|
+
end
|
|
44
|
+
function DenseList:constructor()
|
|
45
|
+
self.items = {}
|
|
46
|
+
self.slots = {}
|
|
47
|
+
self["end"] = 0
|
|
48
|
+
self.count = 0
|
|
49
|
+
self.depth = 0
|
|
50
|
+
end
|
|
51
|
+
function DenseList:size()
|
|
52
|
+
return self.count
|
|
53
|
+
end
|
|
54
|
+
function DenseList:has(item)
|
|
55
|
+
local _slots = self.slots
|
|
56
|
+
local _item = item
|
|
57
|
+
return _slots[_item] ~= nil
|
|
58
|
+
end
|
|
59
|
+
function DenseList:add(item)
|
|
60
|
+
local _slots = self.slots
|
|
61
|
+
local _item = item
|
|
62
|
+
if _slots[_item] ~= nil then
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
self.items[self["end"] + 1] = item
|
|
66
|
+
local _slots_1 = self.slots
|
|
67
|
+
local _item_1 = item
|
|
68
|
+
local _arg1 = self["end"]
|
|
69
|
+
_slots_1[_item_1] = _arg1
|
|
70
|
+
self["end"] += 1
|
|
71
|
+
self.count += 1
|
|
72
|
+
return true
|
|
73
|
+
end
|
|
74
|
+
function DenseList:remove(item)
|
|
75
|
+
local _slots = self.slots
|
|
76
|
+
local _item = item
|
|
77
|
+
local slot = _slots[_item]
|
|
78
|
+
if slot == nil then
|
|
79
|
+
return false
|
|
80
|
+
end
|
|
81
|
+
self.items[slot + 1] = nil
|
|
82
|
+
local _slots_1 = self.slots
|
|
83
|
+
local _item_1 = item
|
|
84
|
+
_slots_1[_item_1] = nil
|
|
85
|
+
self.count -= 1
|
|
86
|
+
self:compactIfSparse()
|
|
87
|
+
return true
|
|
88
|
+
end
|
|
89
|
+
function DenseList:forEach(visit)
|
|
90
|
+
self.depth += 1
|
|
91
|
+
local ok, err = pcall(walk, self.items, self["end"], visit)
|
|
92
|
+
self.depth -= 1
|
|
93
|
+
self:compactIfSparse()
|
|
94
|
+
if not ok then
|
|
95
|
+
error(err, 0)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
function DenseList:first()
|
|
99
|
+
do
|
|
100
|
+
local i = 0
|
|
101
|
+
local _shouldIncrement = false
|
|
102
|
+
while true do
|
|
103
|
+
if _shouldIncrement then
|
|
104
|
+
i += 1
|
|
105
|
+
else
|
|
106
|
+
_shouldIncrement = true
|
|
107
|
+
end
|
|
108
|
+
if not (i < self["end"]) then
|
|
109
|
+
break
|
|
110
|
+
end
|
|
111
|
+
local item = self.items[i + 1]
|
|
112
|
+
if item ~= nil then
|
|
113
|
+
return item
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
return nil
|
|
118
|
+
end
|
|
119
|
+
function DenseList:compactIfSparse()
|
|
120
|
+
if self.depth > 0 or self["end"] - self.count <= self["end"] / 2 then
|
|
121
|
+
return nil
|
|
122
|
+
end
|
|
123
|
+
local write = 0
|
|
124
|
+
do
|
|
125
|
+
local read = 0
|
|
126
|
+
local _shouldIncrement = false
|
|
127
|
+
while true do
|
|
128
|
+
if _shouldIncrement then
|
|
129
|
+
read += 1
|
|
130
|
+
else
|
|
131
|
+
_shouldIncrement = true
|
|
132
|
+
end
|
|
133
|
+
if not (read < self["end"]) then
|
|
134
|
+
break
|
|
135
|
+
end
|
|
136
|
+
local item = self.items[read + 1]
|
|
137
|
+
if item == nil then
|
|
138
|
+
continue
|
|
139
|
+
end
|
|
140
|
+
if read ~= write then
|
|
141
|
+
self.items[write + 1] = item
|
|
142
|
+
self.items[read + 1] = nil
|
|
143
|
+
local _slots = self.slots
|
|
144
|
+
local _write = write
|
|
145
|
+
_slots[item] = _write
|
|
146
|
+
end
|
|
147
|
+
write += 1
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
self["end"] = write
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
return {
|
|
154
|
+
DenseList = DenseList,
|
|
155
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local loggingPort = TS.import(script, script.Parent, "log-output").loggingPort
|
|
4
|
+
local emitting = false
|
|
5
|
+
local terminal = false
|
|
6
|
+
--* @internal
|
|
7
|
+
local function runtimeDiagnostic(level, message)
|
|
8
|
+
if not emitting then
|
|
9
|
+
emitting = true
|
|
10
|
+
local ok = pcall(function()
|
|
11
|
+
return loggingPort().writeInternal(level, message)
|
|
12
|
+
end)
|
|
13
|
+
emitting = false
|
|
14
|
+
if ok then
|
|
15
|
+
return nil
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
if terminal then
|
|
19
|
+
return nil
|
|
20
|
+
end
|
|
21
|
+
terminal = true
|
|
22
|
+
pcall(function()
|
|
23
|
+
return warn(`[Crucible] {message}`)
|
|
24
|
+
end)
|
|
25
|
+
terminal = false
|
|
26
|
+
end
|
|
27
|
+
return {
|
|
28
|
+
runtimeDiagnostic = runtimeDiagnostic,
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|