@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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local LogLevel = TS.import(script, script.Parent.Parent, "log-level").LogLevel
|
|
4
|
+
--* @internal
|
|
5
|
+
local port
|
|
6
|
+
--* @internal
|
|
7
|
+
local function installLoggingPort(value)
|
|
8
|
+
local _arg0 = port == nil
|
|
9
|
+
assert(_arg0, "Logging port already selected")
|
|
10
|
+
port = value
|
|
11
|
+
end
|
|
12
|
+
--* @internal
|
|
13
|
+
local createRobloxLoggingPort
|
|
14
|
+
local function loggingPort()
|
|
15
|
+
if port == nil then
|
|
16
|
+
port = createRobloxLoggingPort()
|
|
17
|
+
end
|
|
18
|
+
return port
|
|
19
|
+
end
|
|
20
|
+
local function escape(text)
|
|
21
|
+
return (string.gsub((string.gsub(text, "{", "{{")), "}", "}}"))
|
|
22
|
+
end
|
|
23
|
+
--* @internal
|
|
24
|
+
function createRobloxLoggingPort()
|
|
25
|
+
local gameLogger
|
|
26
|
+
local crucibleLogger
|
|
27
|
+
local fallback = false
|
|
28
|
+
local studio = game:GetService("RunService"):IsStudio()
|
|
29
|
+
local function native(write, plain)
|
|
30
|
+
if not fallback then
|
|
31
|
+
local ok = pcall(function()
|
|
32
|
+
local service = game:GetService("LogService")
|
|
33
|
+
if gameLogger == nil then
|
|
34
|
+
gameLogger = service:GetLogger("Game")
|
|
35
|
+
end
|
|
36
|
+
if crucibleLogger == nil then
|
|
37
|
+
crucibleLogger = service:GetLogger("Crucible")
|
|
38
|
+
end
|
|
39
|
+
write()
|
|
40
|
+
end)
|
|
41
|
+
if ok then
|
|
42
|
+
return nil
|
|
43
|
+
end
|
|
44
|
+
fallback = true
|
|
45
|
+
end
|
|
46
|
+
plain()
|
|
47
|
+
end
|
|
48
|
+
return {
|
|
49
|
+
isStudio = function()
|
|
50
|
+
return studio
|
|
51
|
+
end,
|
|
52
|
+
now = function()
|
|
53
|
+
return os.clock()
|
|
54
|
+
end,
|
|
55
|
+
describeInstance = function(instance)
|
|
56
|
+
return instance:GetFullName()
|
|
57
|
+
end,
|
|
58
|
+
writeGame = function(record)
|
|
59
|
+
local text = `[{record.source}] {record.message}`
|
|
60
|
+
if record.level == LogLevel.Error then
|
|
61
|
+
task.spawn(function()
|
|
62
|
+
local _condition = record.traceback
|
|
63
|
+
if _condition == nil then
|
|
64
|
+
_condition = ""
|
|
65
|
+
end
|
|
66
|
+
return error(`{text}\n{_condition}`, 0)
|
|
67
|
+
end)
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
native(function()
|
|
71
|
+
local logger = gameLogger
|
|
72
|
+
if record.level == LogLevel.Debug then
|
|
73
|
+
logger:Output(escape(text), record.context)
|
|
74
|
+
elseif record.level == LogLevel.Info then
|
|
75
|
+
logger:Info(escape(text), record.context)
|
|
76
|
+
else
|
|
77
|
+
logger:Warn(escape(text), record.context)
|
|
78
|
+
end
|
|
79
|
+
end, function()
|
|
80
|
+
if record.level == LogLevel.Warning then
|
|
81
|
+
warn(text)
|
|
82
|
+
else
|
|
83
|
+
print(text)
|
|
84
|
+
end
|
|
85
|
+
end)
|
|
86
|
+
end,
|
|
87
|
+
writeInternal = function(level, message)
|
|
88
|
+
if level == "error" then
|
|
89
|
+
task.spawn(function()
|
|
90
|
+
return error(`[Crucible] {message}`, 0)
|
|
91
|
+
end)
|
|
92
|
+
else
|
|
93
|
+
native(function()
|
|
94
|
+
return crucibleLogger:Warn(escape(`[Crucible] {message}`), {})
|
|
95
|
+
end, function()
|
|
96
|
+
return warn(`[Crucible] {message}`)
|
|
97
|
+
end)
|
|
98
|
+
end
|
|
99
|
+
end,
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
return {
|
|
103
|
+
installLoggingPort = installLoggingPort,
|
|
104
|
+
loggingPort = loggingPort,
|
|
105
|
+
createRobloxLoggingPort = createRobloxLoggingPort,
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* @internal Ends one engine subscription. Idempotent.
|
|
3
|
+
--* @internal The RunService events the scheduler connects. `BindToRenderStep` lanes have their own entry.
|
|
4
|
+
--[[
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
* Everything the runtime asks of the engine. Coroutine functions are not here: they are the Luau language,
|
|
8
|
+
* identical in Roblox and Lune. The runner cancels a yielded worker with `task.cancel` itself, because the pool
|
|
9
|
+
* works before any port is installed.
|
|
10
|
+
|
|
11
|
+
]]
|
|
12
|
+
return nil
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local hooks = TS.import(script, script.Parent, "hooks").hooks
|
|
4
|
+
local ImplementerSet = TS.import(script, script.Parent, "implementers").ImplementerSet
|
|
5
|
+
local drain = TS.import(script, script.Parent, "lifecycle").drain
|
|
6
|
+
--* @internal
|
|
7
|
+
--* @internal
|
|
8
|
+
--* @internal
|
|
9
|
+
--* @internal
|
|
10
|
+
--* @internal
|
|
11
|
+
--* @internal
|
|
12
|
+
--* @internal
|
|
13
|
+
--* @internal
|
|
14
|
+
--* @internal
|
|
15
|
+
--* @internal
|
|
16
|
+
--* @internal
|
|
17
|
+
--* @internal
|
|
18
|
+
local registered = {}
|
|
19
|
+
local byClass = {}
|
|
20
|
+
local duplicates = {}
|
|
21
|
+
local sets = {}
|
|
22
|
+
local sealed
|
|
23
|
+
--* @internal
|
|
24
|
+
local function define(klass, emitted)
|
|
25
|
+
if sealed ~= nil then
|
|
26
|
+
error(`Crucible: {emitted.id} registered after boot; it would never be constructed or bound`)
|
|
27
|
+
end
|
|
28
|
+
local id = emitted.id
|
|
29
|
+
-- ▼ ReadonlyArray.some ▼
|
|
30
|
+
local _result = false
|
|
31
|
+
local _callback = function(record)
|
|
32
|
+
return record.id == id
|
|
33
|
+
end
|
|
34
|
+
for _k, _v in registered do
|
|
35
|
+
if _callback(_v, _k - 1, registered) then
|
|
36
|
+
_result = true
|
|
37
|
+
break
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
-- ▲ ReadonlyArray.some ▲
|
|
41
|
+
if _result then
|
|
42
|
+
table.insert(duplicates, id)
|
|
43
|
+
end
|
|
44
|
+
local statics = klass
|
|
45
|
+
local _object = {
|
|
46
|
+
id = id,
|
|
47
|
+
klass = klass,
|
|
48
|
+
hooks = hooks().overrides(klass),
|
|
49
|
+
}
|
|
50
|
+
local _left = "deps"
|
|
51
|
+
local _exp = emitted.deps
|
|
52
|
+
-- ▼ ReadonlyArray.map ▼
|
|
53
|
+
local _newValue = table.create(#_exp)
|
|
54
|
+
local _callback_1 = function(dep)
|
|
55
|
+
local _dep = dep
|
|
56
|
+
return if type(_dep) == "string" then {
|
|
57
|
+
id = dep,
|
|
58
|
+
all = false,
|
|
59
|
+
} else {
|
|
60
|
+
id = dep.all,
|
|
61
|
+
all = true,
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
for _k, _v in _exp do
|
|
65
|
+
_newValue[_k] = _callback_1(_v, _k - 1, _exp)
|
|
66
|
+
end
|
|
67
|
+
-- ▲ ReadonlyArray.map ▲
|
|
68
|
+
_object[_left] = _newValue
|
|
69
|
+
local _left_1 = "provides"
|
|
70
|
+
local _array = { id }
|
|
71
|
+
local _length = #_array
|
|
72
|
+
local _exp_1 = emitted.provides
|
|
73
|
+
-- ▼ ReadonlyArray.map ▼
|
|
74
|
+
local _newValue_1 = table.create(#_exp_1)
|
|
75
|
+
local _callback_2 = function(provided)
|
|
76
|
+
return provided
|
|
77
|
+
end
|
|
78
|
+
for _k, _v in _exp_1 do
|
|
79
|
+
_newValue_1[_k] = _callback_2(_v, _k - 1, _exp_1)
|
|
80
|
+
end
|
|
81
|
+
-- ▲ ReadonlyArray.map ▲
|
|
82
|
+
table.move(_newValue_1, 1, #_newValue_1, _length + 1, _array)
|
|
83
|
+
_object[_left_1] = _array
|
|
84
|
+
_object.renderPriority = statics.renderPriority
|
|
85
|
+
_object.resolved = {}
|
|
86
|
+
_object.memberOf = {}
|
|
87
|
+
local base = _object
|
|
88
|
+
local record
|
|
89
|
+
if emitted.kind == "subsystem" then
|
|
90
|
+
local _object_1 = table.clone(base)
|
|
91
|
+
setmetatable(_object_1, nil)
|
|
92
|
+
_object_1.kind = 0
|
|
93
|
+
record = _object_1
|
|
94
|
+
else
|
|
95
|
+
local tag = emitted.tag
|
|
96
|
+
klass.tag = tag
|
|
97
|
+
local attributes
|
|
98
|
+
if emitted.attributes ~= nil then
|
|
99
|
+
attributes = {}
|
|
100
|
+
for name, check in pairs(emitted.attributes) do
|
|
101
|
+
attributes[name] = check
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
local _object_1 = table.clone(base)
|
|
105
|
+
setmetatable(_object_1, nil)
|
|
106
|
+
_object_1.kind = 1
|
|
107
|
+
_object_1.tag = tag
|
|
108
|
+
_object_1.instanceClasses = emitted.instance
|
|
109
|
+
_object_1.attributes = attributes
|
|
110
|
+
_object_1.bound = {}
|
|
111
|
+
_object_1.suppressed = {}
|
|
112
|
+
record = _object_1
|
|
113
|
+
end
|
|
114
|
+
local _record = record
|
|
115
|
+
table.insert(registered, _record)
|
|
116
|
+
local _klass = klass
|
|
117
|
+
local _record_1 = record
|
|
118
|
+
byClass[_klass] = _record_1
|
|
119
|
+
end
|
|
120
|
+
--* @internal
|
|
121
|
+
local function plan(records, side)
|
|
122
|
+
local problems = {}
|
|
123
|
+
local providers = {}
|
|
124
|
+
for _, record in records do
|
|
125
|
+
for _1, id in record.provides do
|
|
126
|
+
local list = providers[id]
|
|
127
|
+
if list == nil then
|
|
128
|
+
local _arg1 = { record }
|
|
129
|
+
providers[id] = _arg1
|
|
130
|
+
else
|
|
131
|
+
table.insert(list, record)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
local single = {}
|
|
136
|
+
for _, record in records do
|
|
137
|
+
local edges = {}
|
|
138
|
+
for _1, dep in record.deps do
|
|
139
|
+
if dep.all then
|
|
140
|
+
continue
|
|
141
|
+
end
|
|
142
|
+
local _id = dep.id
|
|
143
|
+
local _condition = providers[_id]
|
|
144
|
+
if _condition == nil then
|
|
145
|
+
_condition = {}
|
|
146
|
+
end
|
|
147
|
+
local candidates = _condition
|
|
148
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
149
|
+
local _newValue = {}
|
|
150
|
+
local _callback = function(candidate)
|
|
151
|
+
return candidate.kind == 0
|
|
152
|
+
end
|
|
153
|
+
local _length = 0
|
|
154
|
+
for _k, _v in candidates do
|
|
155
|
+
if _callback(_v, _k - 1, candidates) == true then
|
|
156
|
+
_length += 1
|
|
157
|
+
_newValue[_length] = _v
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
161
|
+
local subsystems = _newValue
|
|
162
|
+
if #candidates == 0 then
|
|
163
|
+
local _arg0 = {
|
|
164
|
+
kind = "missing",
|
|
165
|
+
needer = record.id,
|
|
166
|
+
dep = dep.id,
|
|
167
|
+
}
|
|
168
|
+
table.insert(problems, _arg0)
|
|
169
|
+
elseif #subsystems == 0 then
|
|
170
|
+
local _arg0 = {
|
|
171
|
+
kind = "behaviour-dependency",
|
|
172
|
+
needer = record.id,
|
|
173
|
+
dep = dep.id,
|
|
174
|
+
}
|
|
175
|
+
table.insert(problems, _arg0)
|
|
176
|
+
elseif #candidates > 1 then
|
|
177
|
+
local _object = {
|
|
178
|
+
kind = "ambiguous",
|
|
179
|
+
needer = record.id,
|
|
180
|
+
dep = dep.id,
|
|
181
|
+
}
|
|
182
|
+
local _left = "providers"
|
|
183
|
+
-- ▼ ReadonlyArray.map ▼
|
|
184
|
+
local _newValue_1 = table.create(#candidates)
|
|
185
|
+
local _callback_1 = function(c)
|
|
186
|
+
return c.id
|
|
187
|
+
end
|
|
188
|
+
for _k, _v in candidates do
|
|
189
|
+
_newValue_1[_k] = _callback_1(_v, _k - 1, candidates)
|
|
190
|
+
end
|
|
191
|
+
-- ▲ ReadonlyArray.map ▲
|
|
192
|
+
_object[_left] = _newValue_1
|
|
193
|
+
table.insert(problems, _object)
|
|
194
|
+
else
|
|
195
|
+
local _arg0 = subsystems[1]
|
|
196
|
+
table.insert(edges, _arg0)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
single[record] = edges
|
|
200
|
+
local renders = (bit32.band(record.hooks, (bit32.lshift(1, 0)))) ~= 0 or record.renderPriority ~= nil
|
|
201
|
+
if not side.renders and renders then
|
|
202
|
+
local _arg0 = {
|
|
203
|
+
kind = "render-on-server",
|
|
204
|
+
id = record.id,
|
|
205
|
+
priority = record.renderPriority,
|
|
206
|
+
}
|
|
207
|
+
table.insert(problems, _arg0)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
local order = {}
|
|
211
|
+
local colour = {}
|
|
212
|
+
local path = {}
|
|
213
|
+
local visit
|
|
214
|
+
visit = function(record)
|
|
215
|
+
local _record = record
|
|
216
|
+
local seen = colour[_record]
|
|
217
|
+
if seen == "black" then
|
|
218
|
+
return nil
|
|
219
|
+
end
|
|
220
|
+
if seen == "grey" then
|
|
221
|
+
local _record_1 = record
|
|
222
|
+
local from = (table.find(path, _record_1) or 0) - 1
|
|
223
|
+
local cycle = {}
|
|
224
|
+
do
|
|
225
|
+
local i = from
|
|
226
|
+
local _shouldIncrement = false
|
|
227
|
+
while true do
|
|
228
|
+
if _shouldIncrement then
|
|
229
|
+
i += 1
|
|
230
|
+
else
|
|
231
|
+
_shouldIncrement = true
|
|
232
|
+
end
|
|
233
|
+
if not (i < #path) then
|
|
234
|
+
break
|
|
235
|
+
end
|
|
236
|
+
local _id = path[i + 1].id
|
|
237
|
+
table.insert(cycle, _id)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
local _id = record.id
|
|
241
|
+
table.insert(cycle, _id)
|
|
242
|
+
local _arg0 = {
|
|
243
|
+
kind = "cycle",
|
|
244
|
+
path = cycle,
|
|
245
|
+
}
|
|
246
|
+
table.insert(problems, _arg0)
|
|
247
|
+
return nil
|
|
248
|
+
end
|
|
249
|
+
local _record_1 = record
|
|
250
|
+
colour[_record_1] = "grey"
|
|
251
|
+
local _record_2 = record
|
|
252
|
+
table.insert(path, _record_2)
|
|
253
|
+
local _record_3 = record
|
|
254
|
+
local _condition = single[_record_3]
|
|
255
|
+
if _condition == nil then
|
|
256
|
+
_condition = {}
|
|
257
|
+
end
|
|
258
|
+
for _, dep in _condition do
|
|
259
|
+
visit(dep)
|
|
260
|
+
end
|
|
261
|
+
path[#path] = nil
|
|
262
|
+
local _record_4 = record
|
|
263
|
+
colour[_record_4] = "black"
|
|
264
|
+
local _record_5 = record
|
|
265
|
+
table.insert(order, _record_5)
|
|
266
|
+
end
|
|
267
|
+
for _, record in records do
|
|
268
|
+
if record.kind == 0 then
|
|
269
|
+
visit(record)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
if #problems > 0 then
|
|
273
|
+
return {
|
|
274
|
+
ok = false,
|
|
275
|
+
problems = problems,
|
|
276
|
+
}
|
|
277
|
+
end
|
|
278
|
+
return {
|
|
279
|
+
ok = true,
|
|
280
|
+
plan = {
|
|
281
|
+
providers = providers,
|
|
282
|
+
subsystemOrder = order,
|
|
283
|
+
},
|
|
284
|
+
}
|
|
285
|
+
end
|
|
286
|
+
local function describe(problem)
|
|
287
|
+
local _exp = problem.kind
|
|
288
|
+
repeat
|
|
289
|
+
if _exp == "duplicate" then
|
|
290
|
+
return `{problem.id} is registered twice`
|
|
291
|
+
end
|
|
292
|
+
if _exp == "missing" then
|
|
293
|
+
return `{problem.needer} needs {problem.dep}, which nothing provides`
|
|
294
|
+
end
|
|
295
|
+
if _exp == "ambiguous" then
|
|
296
|
+
return `{problem.needer} needs one {problem.dep}, but {table.concat(problem.providers, ", ")} all provide it`
|
|
297
|
+
end
|
|
298
|
+
if _exp == "behaviour-dependency" then
|
|
299
|
+
return `{problem.needer} needs {problem.dep}, which only behaviours provide; take All<T> or call X.get(instance)`
|
|
300
|
+
end
|
|
301
|
+
if _exp == "cycle" then
|
|
302
|
+
return `dependency cycle {table.concat(problem.path, " -> ")}; break it with All<T>`
|
|
303
|
+
end
|
|
304
|
+
if _exp == "render-on-server" then
|
|
305
|
+
return `{problem.id} renders but is loaded on the server`
|
|
306
|
+
end
|
|
307
|
+
until true
|
|
308
|
+
end
|
|
309
|
+
--* @internal
|
|
310
|
+
local setFor
|
|
311
|
+
local function seal(side)
|
|
312
|
+
if sealed ~= nil then
|
|
313
|
+
error("Crucible: boot already ran on this side")
|
|
314
|
+
end
|
|
315
|
+
local result = plan(registered, side)
|
|
316
|
+
local problems = {}
|
|
317
|
+
for _, id in duplicates do
|
|
318
|
+
local _arg0 = {
|
|
319
|
+
kind = "duplicate",
|
|
320
|
+
id = id,
|
|
321
|
+
}
|
|
322
|
+
table.insert(problems, _arg0)
|
|
323
|
+
end
|
|
324
|
+
if not result.ok then
|
|
325
|
+
for _, problem in result.problems do
|
|
326
|
+
table.insert(problems, problem)
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
if #problems > 0 then
|
|
330
|
+
-- ▼ ReadonlyArray.map ▼
|
|
331
|
+
local _newValue = table.create(#problems)
|
|
332
|
+
for _k, _v in problems do
|
|
333
|
+
_newValue[_k] = describe(_v, _k - 1, problems)
|
|
334
|
+
end
|
|
335
|
+
-- ▲ ReadonlyArray.map ▲
|
|
336
|
+
error(`Crucible could not boot:\n {table.concat(_newValue, "\n ")}`)
|
|
337
|
+
end
|
|
338
|
+
if not result.ok then
|
|
339
|
+
return {}
|
|
340
|
+
end
|
|
341
|
+
local _binding = result.plan
|
|
342
|
+
local providers = _binding.providers
|
|
343
|
+
local subsystemOrder = _binding.subsystemOrder
|
|
344
|
+
for _, record in registered do
|
|
345
|
+
local _exp = record.deps
|
|
346
|
+
-- ▼ ReadonlyArray.map ▼
|
|
347
|
+
local _newValue = table.create(#_exp)
|
|
348
|
+
local _callback = function(dep)
|
|
349
|
+
if dep.all then
|
|
350
|
+
return {
|
|
351
|
+
all = true,
|
|
352
|
+
set = setFor(dep.id),
|
|
353
|
+
}
|
|
354
|
+
end
|
|
355
|
+
local _object = {
|
|
356
|
+
all = false,
|
|
357
|
+
}
|
|
358
|
+
local _left = "record"
|
|
359
|
+
local _id = dep.id
|
|
360
|
+
local _condition = providers[_id]
|
|
361
|
+
if _condition == nil then
|
|
362
|
+
_condition = {}
|
|
363
|
+
end
|
|
364
|
+
_object[_left] = _condition[1]
|
|
365
|
+
return _object
|
|
366
|
+
end
|
|
367
|
+
for _k, _v in _exp do
|
|
368
|
+
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
369
|
+
end
|
|
370
|
+
-- ▲ ReadonlyArray.map ▲
|
|
371
|
+
record.resolved = _newValue
|
|
372
|
+
local _exp_1 = record.provides
|
|
373
|
+
-- ▼ ReadonlyArray.map ▼
|
|
374
|
+
local _newValue_1 = table.create(#_exp_1)
|
|
375
|
+
for _k, _v in _exp_1 do
|
|
376
|
+
_newValue_1[_k] = setFor(_v, _k - 1, _exp_1)
|
|
377
|
+
end
|
|
378
|
+
-- ▲ ReadonlyArray.map ▲
|
|
379
|
+
record.memberOf = _newValue_1
|
|
380
|
+
end
|
|
381
|
+
sealed = result.plan
|
|
382
|
+
return subsystemOrder
|
|
383
|
+
end
|
|
384
|
+
--* @internal
|
|
385
|
+
local function records()
|
|
386
|
+
return registered
|
|
387
|
+
end
|
|
388
|
+
--* @internal
|
|
389
|
+
local function recordOf(klass)
|
|
390
|
+
local _klass = klass
|
|
391
|
+
return byClass[_klass]
|
|
392
|
+
end
|
|
393
|
+
--* @internal
|
|
394
|
+
local function resolveOne(id)
|
|
395
|
+
drain()
|
|
396
|
+
local plan = sealed or error(`inject<{id}>() called before boot`)
|
|
397
|
+
local _providers = plan.providers
|
|
398
|
+
local _id = id
|
|
399
|
+
local _condition = _providers[_id]
|
|
400
|
+
if _condition == nil then
|
|
401
|
+
_condition = {}
|
|
402
|
+
end
|
|
403
|
+
local candidates = _condition
|
|
404
|
+
local provider = candidates[1]
|
|
405
|
+
if #candidates ~= 1 or provider.kind ~= 0 then
|
|
406
|
+
error(`inject<{id}>(): {#candidates} providers; inject needs exactly one subsystem`)
|
|
407
|
+
end
|
|
408
|
+
local state = provider.state
|
|
409
|
+
local _result = state
|
|
410
|
+
if _result ~= nil then
|
|
411
|
+
_result = _result.phase
|
|
412
|
+
end
|
|
413
|
+
if _result == 5 then
|
|
414
|
+
error(`inject<{id}>(): provider {provider.id} is Faulted`)
|
|
415
|
+
end
|
|
416
|
+
local _object = state
|
|
417
|
+
if _object ~= nil then
|
|
418
|
+
_object = _object.object
|
|
419
|
+
end
|
|
420
|
+
local object = _object
|
|
421
|
+
if state == nil or object == nil or state.phase == 0 or state.phase == 1 then
|
|
422
|
+
error(`inject<{id}>(): {provider.id} is not awake yet; call inject from start or later, or take a constructor parameter`)
|
|
423
|
+
end
|
|
424
|
+
return object
|
|
425
|
+
end
|
|
426
|
+
--* @internal
|
|
427
|
+
function setFor(id)
|
|
428
|
+
local _id = id
|
|
429
|
+
local set = sets[_id]
|
|
430
|
+
if set == nil then
|
|
431
|
+
set = ImplementerSet.new(id)
|
|
432
|
+
local _id_1 = id
|
|
433
|
+
local _set = set
|
|
434
|
+
sets[_id_1] = _set
|
|
435
|
+
end
|
|
436
|
+
return set
|
|
437
|
+
end
|
|
438
|
+
return {
|
|
439
|
+
define = define,
|
|
440
|
+
plan = plan,
|
|
441
|
+
seal = seal,
|
|
442
|
+
records = records,
|
|
443
|
+
recordOf = recordOf,
|
|
444
|
+
resolveOne = resolveOne,
|
|
445
|
+
setFor = setFor,
|
|
446
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* @internal
|
|
3
|
+
--* @internal
|
|
4
|
+
local robloxBindingPort
|
|
5
|
+
local function robloxPort()
|
|
6
|
+
local runService = game:GetService("RunService")
|
|
7
|
+
local events = {
|
|
8
|
+
[0] = runService.PreRender,
|
|
9
|
+
[1] = runService.PreSimulation,
|
|
10
|
+
[2] = runService.PostSimulation,
|
|
11
|
+
[3] = runService.RenderStepped,
|
|
12
|
+
[4] = runService.PreAnimation,
|
|
13
|
+
[5] = runService.Heartbeat,
|
|
14
|
+
}
|
|
15
|
+
local _object = table.clone(robloxBindingPort())
|
|
16
|
+
setmetatable(_object, nil)
|
|
17
|
+
_object.onFrame = function(event, listener)
|
|
18
|
+
local connection = events[event]:Connect(listener)
|
|
19
|
+
return function()
|
|
20
|
+
return connection:Disconnect()
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
_object.bindRenderStep = function(name, priority, listener)
|
|
24
|
+
runService:BindToRenderStep(name, priority, listener)
|
|
25
|
+
return function()
|
|
26
|
+
return runService:UnbindFromRenderStep(name)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
_object.defer = function(callback)
|
|
30
|
+
task.defer(callback)
|
|
31
|
+
end
|
|
32
|
+
_object.cancel = function(thread)
|
|
33
|
+
return task.cancel(thread)
|
|
34
|
+
end
|
|
35
|
+
_object.spawn = function(callback)
|
|
36
|
+
task.spawn(callback)
|
|
37
|
+
end
|
|
38
|
+
_object.clock = function()
|
|
39
|
+
return os.clock()
|
|
40
|
+
end
|
|
41
|
+
_object.wait = function()
|
|
42
|
+
task.wait()
|
|
43
|
+
end
|
|
44
|
+
_object.bindToClose = function(callback)
|
|
45
|
+
return game:BindToClose(callback)
|
|
46
|
+
end
|
|
47
|
+
return _object
|
|
48
|
+
end
|
|
49
|
+
--* @internal
|
|
50
|
+
--* @internal
|
|
51
|
+
function robloxBindingPort()
|
|
52
|
+
local collection = game:GetService("CollectionService")
|
|
53
|
+
local excluded = { game:GetService("ServerStorage"), game:GetService("ReplicatedStorage"), game:GetService("ServerScriptService"), game:GetService("StarterGui"), game:GetService("StarterPack"), game:GetService("StarterPlayer") }
|
|
54
|
+
return {
|
|
55
|
+
hasTag = function(instance, tag)
|
|
56
|
+
return collection:HasTag(instance, tag)
|
|
57
|
+
end,
|
|
58
|
+
tagged = function(tag)
|
|
59
|
+
return collection:GetTagged(tag)
|
|
60
|
+
end,
|
|
61
|
+
onTagAdded = function(tag, listener)
|
|
62
|
+
local c = collection:GetInstanceAddedSignal(tag):Connect(listener)
|
|
63
|
+
return function()
|
|
64
|
+
return c:Disconnect()
|
|
65
|
+
end
|
|
66
|
+
end,
|
|
67
|
+
onTagRemoved = function(tag, listener)
|
|
68
|
+
local c = collection:GetInstanceRemovedSignal(tag):Connect(listener)
|
|
69
|
+
return function()
|
|
70
|
+
return c:Disconnect()
|
|
71
|
+
end
|
|
72
|
+
end,
|
|
73
|
+
inWorld = function(instance)
|
|
74
|
+
return instance:IsDescendantOf(game)
|
|
75
|
+
end,
|
|
76
|
+
isA = function(instance, name)
|
|
77
|
+
return instance:IsA(name)
|
|
78
|
+
end,
|
|
79
|
+
bindingScope = function(instance)
|
|
80
|
+
-- ▼ ReadonlyArray.some ▼
|
|
81
|
+
local _result = false
|
|
82
|
+
local _callback = function(container)
|
|
83
|
+
return instance == container or instance:IsDescendantOf(container)
|
|
84
|
+
end
|
|
85
|
+
for _k, _v in excluded do
|
|
86
|
+
if _callback(_v, _k - 1, excluded) then
|
|
87
|
+
_result = true
|
|
88
|
+
break
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
-- ▲ ReadonlyArray.some ▲
|
|
92
|
+
return not _result
|
|
93
|
+
end,
|
|
94
|
+
onAncestryChanged = function(instance, listener)
|
|
95
|
+
local c = instance.AncestryChanged:Connect(listener)
|
|
96
|
+
return function()
|
|
97
|
+
return c:Disconnect()
|
|
98
|
+
end
|
|
99
|
+
end,
|
|
100
|
+
getAttribute = function(instance, name)
|
|
101
|
+
return instance:GetAttribute(name)
|
|
102
|
+
end,
|
|
103
|
+
onAttributeChanged = function(instance, name, listener)
|
|
104
|
+
local c = instance:GetAttributeChangedSignal(name):Connect(listener)
|
|
105
|
+
return function()
|
|
106
|
+
return c:Disconnect()
|
|
107
|
+
end
|
|
108
|
+
end,
|
|
109
|
+
describe = function(instance)
|
|
110
|
+
return instance:GetFullName()
|
|
111
|
+
end,
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
return {
|
|
115
|
+
robloxPort = robloxPort,
|
|
116
|
+
robloxBindingPort = robloxBindingPort,
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|