@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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/client/package.json +4 -0
  3. package/emit/package.json +4 -0
  4. package/out/all.d.ts +7 -0
  5. package/out/all.luau +2 -0
  6. package/out/attribute.d.ts +7 -0
  7. package/out/attribute.luau +7 -0
  8. package/out/client/index.d.ts +3 -0
  9. package/out/client/init.luau +20 -0
  10. package/out/crucible-behaviour.d.ts +16 -0
  11. package/out/crucible-behaviour.luau +78 -0
  12. package/out/crucible-object.d.ts +10 -0
  13. package/out/crucible-object.luau +69 -0
  14. package/out/emit/index.d.ts +41 -0
  15. package/out/emit/init.luau +85 -0
  16. package/out/index.d.ts +12 -0
  17. package/out/init.luau +11 -0
  18. package/out/inject.d.ts +1 -0
  19. package/out/inject.luau +7 -0
  20. package/out/internal/binding.d.ts +1 -0
  21. package/out/internal/binding.luau +610 -0
  22. package/out/internal/boot.d.ts +1 -0
  23. package/out/internal/boot.luau +463 -0
  24. package/out/internal/construction-claim.d.ts +1 -0
  25. package/out/internal/construction-claim.luau +26 -0
  26. package/out/internal/dense-list.d.ts +1 -0
  27. package/out/internal/dense-list.luau +155 -0
  28. package/out/internal/diagnostics.d.ts +1 -0
  29. package/out/internal/diagnostics.luau +29 -0
  30. package/out/internal/hooks.d.ts +1 -0
  31. package/out/internal/hooks.luau +53 -0
  32. package/out/internal/implementers.d.ts +1 -0
  33. package/out/internal/implementers.luau +119 -0
  34. package/out/internal/lifecycle.d.ts +1 -0
  35. package/out/internal/lifecycle.luau +867 -0
  36. package/out/internal/log-output.d.ts +1 -0
  37. package/out/internal/log-output.luau +106 -0
  38. package/out/internal/port.d.ts +1 -0
  39. package/out/internal/port.luau +12 -0
  40. package/out/internal/registry.d.ts +1 -0
  41. package/out/internal/registry.luau +446 -0
  42. package/out/internal/roblox-port.d.ts +1 -0
  43. package/out/internal/roblox-port.luau +117 -0
  44. package/out/internal/runner.d.ts +1 -0
  45. package/out/internal/runner.luau +86 -0
  46. package/out/internal/scheduler.d.ts +1 -0
  47. package/out/internal/scheduler.luau +207 -0
  48. package/out/internal/state.d.ts +1 -0
  49. package/out/internal/state.luau +41 -0
  50. package/out/log-level.d.ts +7 -0
  51. package/out/log-level.luau +21 -0
  52. package/out/logging.d.ts +34 -0
  53. package/out/logging.luau +233 -0
  54. package/out/server/index.d.ts +2 -0
  55. package/out/server/init.luau +16 -0
  56. package/out/subsystem.d.ts +4 -0
  57. package/out/subsystem.luau +30 -0
  58. package/package.json +41 -5
  59. package/server/package.json +4 -0
  60. package/transformer/diagnostics.cjs +19 -0
  61. package/transformer/index.js +715 -0
  62. package/transformer/type-id.cjs +80 -0
  63. 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 {};