@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
package/out/index.d.ts
CHANGED
|
@@ -10,3 +10,11 @@ export interface BootOptions {
|
|
|
10
10
|
}
|
|
11
11
|
export { Logging, LogLevel } from "./logging";
|
|
12
12
|
export type { Logger, LogRecord, LogSink, SinkSubscription, LogContext, LogProperties } from "./logging";
|
|
13
|
+
export { state, computed, effect, watch, untracked, scope, onCleanup, own } from "./reactive";
|
|
14
|
+
export type { Readable, State, Ownable } from "./reactive";
|
|
15
|
+
export { replicated, replicatedPerPlayer, syncStatus } from "./replicated";
|
|
16
|
+
export type { Replicated, ReplicatedPerPlayer, SyncStatus } from "./replicated";
|
|
17
|
+
export { toServer, toClient, askServer, receive, ClientReady } from "./network";
|
|
18
|
+
export type { ToServer, ToClient, AskServer, Receiver, ReceiveTarget, ReceiveCallback, AskResult, AskFailure, AskOptions, PayloadArgs, f32, f64, u8, u16, u32, } from "./network";
|
|
19
|
+
export { profileStore, serverOnly, replicatedPaths } from "./data";
|
|
20
|
+
export type { ProfileStore, ProfileOptions, ServerOnly, ProfileData, ClientData, Profile, ClientProfile, DataHandle, ReadHandle, WriteHandle, ArrayWrites, ReservedName, Json, JsonRecord, Migration, } from "./data";
|
package/out/init.luau
CHANGED
|
@@ -8,4 +8,27 @@ exports.CrucibleBehaviour = TS.import(script, script, "crucible-behaviour").Cruc
|
|
|
8
8
|
local _logging = TS.import(script, script, "logging")
|
|
9
9
|
exports.Logging = _logging.Logging
|
|
10
10
|
exports.LogLevel = _logging.LogLevel
|
|
11
|
+
local _reactive = TS.import(script, script, "reactive")
|
|
12
|
+
exports.state = _reactive.state
|
|
13
|
+
exports.computed = _reactive.computed
|
|
14
|
+
exports.effect = _reactive.effect
|
|
15
|
+
exports.watch = _reactive.watch
|
|
16
|
+
exports.untracked = _reactive.untracked
|
|
17
|
+
exports.scope = _reactive.scope
|
|
18
|
+
exports.onCleanup = _reactive.onCleanup
|
|
19
|
+
exports.own = _reactive.own
|
|
20
|
+
local _replicated = TS.import(script, script, "replicated")
|
|
21
|
+
exports.replicated = _replicated.replicated
|
|
22
|
+
exports.replicatedPerPlayer = _replicated.replicatedPerPlayer
|
|
23
|
+
exports.syncStatus = _replicated.syncStatus
|
|
24
|
+
local _network = TS.import(script, script, "network")
|
|
25
|
+
exports.toServer = _network.toServer
|
|
26
|
+
exports.toClient = _network.toClient
|
|
27
|
+
exports.askServer = _network.askServer
|
|
28
|
+
exports.receive = _network.receive
|
|
29
|
+
exports.ClientReady = _network.ClientReady
|
|
30
|
+
local _data = TS.import(script, script, "data")
|
|
31
|
+
exports.profileStore = _data.profileStore
|
|
32
|
+
exports.serverOnly = _data.serverOnly
|
|
33
|
+
exports.replicatedPaths = _data.replicatedPaths
|
|
11
34
|
return exports
|
|
@@ -27,6 +27,10 @@ local scopeTarget
|
|
|
27
27
|
local function port()
|
|
28
28
|
return installed or error("Crucible binding used before boot")
|
|
29
29
|
end
|
|
30
|
+
--* @internal The port boot installed, for framework Subsystems that connect engine events.
|
|
31
|
+
local function enginePort()
|
|
32
|
+
return port()
|
|
33
|
+
end
|
|
30
34
|
--* @internal
|
|
31
35
|
local function useEngine(engine)
|
|
32
36
|
installed = engine
|
|
@@ -597,6 +601,7 @@ local function forget(state)
|
|
|
597
601
|
end
|
|
598
602
|
end
|
|
599
603
|
return {
|
|
604
|
+
enginePort = enginePort,
|
|
600
605
|
useEngine = useEngine,
|
|
601
606
|
defaultAccepts = defaultAccepts,
|
|
602
607
|
construct = construct,
|
package/out/internal/boot.luau
CHANGED
|
@@ -26,6 +26,14 @@ local records = _registry.records
|
|
|
26
26
|
local seal = _registry.seal
|
|
27
27
|
local robloxPort = TS.import(script, script.Parent, "roblox-port").robloxPort
|
|
28
28
|
local Scheduler = TS.import(script, script.Parent, "scheduler").Scheduler
|
|
29
|
+
local _flush = TS.import(script, script.Parent, "reactive", "flush")
|
|
30
|
+
local holdBarrier = _flush.holdBarrier
|
|
31
|
+
local releaseBarrier = _flush.releaseBarrier
|
|
32
|
+
local useReactivePort = _flush.useReactivePort
|
|
33
|
+
local endInterval = TS.import(script, script.Parent, "reactive", "ownership").endInterval
|
|
34
|
+
local _declarations = TS.import(script, script.Parent, "sync", "declarations")
|
|
35
|
+
local rollbackDeclarations = _declarations.rollbackDeclarations
|
|
36
|
+
local sealDeclarations = _declarations.sealDeclarations
|
|
29
37
|
--* @internal
|
|
30
38
|
local BOOT_CLASSES = { Subsystem, CrucibleBehaviour }
|
|
31
39
|
--* @internal
|
|
@@ -35,6 +43,45 @@ local PATTERN_PREFIX = "crucible-path:"
|
|
|
35
43
|
local SHUTDOWN_DEADLINE_SECONDS = 25
|
|
36
44
|
--* @internal
|
|
37
45
|
local SHUTDOWN_TIMEOUT_SECONDS = 28
|
|
46
|
+
local clock
|
|
47
|
+
local sweep
|
|
48
|
+
--* @internal
|
|
49
|
+
--* @internal The one monotonic clock, core's and data's (data rules 25, 105).
|
|
50
|
+
local function bootClock()
|
|
51
|
+
return (clock or os.clock)()
|
|
52
|
+
end
|
|
53
|
+
--* @internal Undefined until the sweep has begun.
|
|
54
|
+
local function shutdownProgress(subsystem)
|
|
55
|
+
if sweep == nil then
|
|
56
|
+
return nil
|
|
57
|
+
end
|
|
58
|
+
local pending = 0
|
|
59
|
+
local notStarted = 0
|
|
60
|
+
for _, record in sweep.order do
|
|
61
|
+
local _condition = sweep.finished[record] ~= nil
|
|
62
|
+
if not _condition then
|
|
63
|
+
local _result = record.state
|
|
64
|
+
if _result ~= nil then
|
|
65
|
+
_result = _result.object
|
|
66
|
+
end
|
|
67
|
+
_condition = _result == subsystem
|
|
68
|
+
end
|
|
69
|
+
if _condition then
|
|
70
|
+
continue
|
|
71
|
+
end
|
|
72
|
+
pending += 1
|
|
73
|
+
if not (sweep.started[record] ~= nil) then
|
|
74
|
+
notStarted += 1
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
return {
|
|
78
|
+
startedAt = sweep.startTime,
|
|
79
|
+
forceStartAt = sweep.startTime + SHUTDOWN_DEADLINE_SECONDS,
|
|
80
|
+
deadline = sweep.startTime + SHUTDOWN_TIMEOUT_SECONDS,
|
|
81
|
+
pending = pending,
|
|
82
|
+
notStarted = notStarted,
|
|
83
|
+
}
|
|
84
|
+
end
|
|
38
85
|
--* @internal
|
|
39
86
|
local function parsePattern(pattern)
|
|
40
87
|
local _pattern = pattern
|
|
@@ -214,6 +261,12 @@ local function shutdown(port, order)
|
|
|
214
261
|
end
|
|
215
262
|
end
|
|
216
263
|
local startTime = port.clock()
|
|
264
|
+
sweep = {
|
|
265
|
+
startTime = startTime,
|
|
266
|
+
order = order,
|
|
267
|
+
started = started,
|
|
268
|
+
finished = finished,
|
|
269
|
+
}
|
|
217
270
|
while true do
|
|
218
271
|
-- ▼ ReadonlySet.size ▼
|
|
219
272
|
local _size = 0
|
|
@@ -287,6 +340,8 @@ local function shutdown(port, order)
|
|
|
287
340
|
end
|
|
288
341
|
--* @internal
|
|
289
342
|
local function ignite(port, side, options)
|
|
343
|
+
clock = port.clock
|
|
344
|
+
sweep = nil
|
|
290
345
|
local singletons = seal({
|
|
291
346
|
renders = side.renders,
|
|
292
347
|
})
|
|
@@ -330,6 +385,8 @@ local function ignite(port, side, options)
|
|
|
330
385
|
end
|
|
331
386
|
end
|
|
332
387
|
useEngine(port)
|
|
388
|
+
holdBarrier()
|
|
389
|
+
useReactivePort(port)
|
|
333
390
|
useImplementerPort(port)
|
|
334
391
|
useEffects({
|
|
335
392
|
construct = function(s)
|
|
@@ -391,6 +448,7 @@ local function ignite(port, side, options)
|
|
|
391
448
|
diagnose = function(s, hook, err)
|
|
392
449
|
return runtimeDiagnostic("error", `{where(port, s)} {HOOK_NAMES[hook + 1]} failed: {tostring(err)}`)
|
|
393
450
|
end,
|
|
451
|
+
disabled = endInterval,
|
|
394
452
|
})
|
|
395
453
|
local ok, err = pcall(function()
|
|
396
454
|
local _exp_1 = records()
|
|
@@ -427,6 +485,36 @@ local function ignite(port, side, options)
|
|
|
427
485
|
if not ok then
|
|
428
486
|
reject(tostring(err))
|
|
429
487
|
end
|
|
488
|
+
if failure == nil then
|
|
489
|
+
local unbooted = nil
|
|
490
|
+
local finalized, finalizeErr = pcall(function()
|
|
491
|
+
-- Roblox cannot unbind BindToClose, so the callback checks that this boot committed.
|
|
492
|
+
if side.name == "server" then
|
|
493
|
+
port.bindToClose(function()
|
|
494
|
+
if stage ~= "committed" then
|
|
495
|
+
return nil
|
|
496
|
+
end
|
|
497
|
+
shutdown(port, singletons)
|
|
498
|
+
side.network:close()
|
|
499
|
+
end)
|
|
500
|
+
end
|
|
501
|
+
unbooted = side.booted()
|
|
502
|
+
if side.name == "client" then
|
|
503
|
+
sealDeclarations()
|
|
504
|
+
end
|
|
505
|
+
side.network:commit()
|
|
506
|
+
end)
|
|
507
|
+
if not finalized then
|
|
508
|
+
local undo = unbooted
|
|
509
|
+
if undo ~= nil then
|
|
510
|
+
local undone, undoErr = pcall(undo)
|
|
511
|
+
if not undone then
|
|
512
|
+
runtimeDiagnostic("error", `Crucible: undoing booted failed: {tostring(undoErr)}`)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
reject(`boot finalization failed: {tostring(finalizeErr)}`)
|
|
516
|
+
end
|
|
517
|
+
end
|
|
430
518
|
if failure ~= nil then
|
|
431
519
|
for s in owned do
|
|
432
520
|
if not hasEnded(s) then
|
|
@@ -435,23 +523,34 @@ local function ignite(port, side, options)
|
|
|
435
523
|
end
|
|
436
524
|
drain()
|
|
437
525
|
table.clear(owned)
|
|
526
|
+
releaseBarrier()
|
|
438
527
|
error(`Crucible boot failed: {failure}`, 0)
|
|
439
528
|
end
|
|
440
529
|
stage = "committed"
|
|
441
530
|
table.clear(owned)
|
|
442
|
-
|
|
443
|
-
port.bindToClose(function()
|
|
444
|
-
return shutdown(port, singletons)
|
|
445
|
-
end)
|
|
446
|
-
end
|
|
447
|
-
side.booted()
|
|
531
|
+
releaseBarrier()
|
|
448
532
|
end
|
|
449
533
|
--* @internal
|
|
450
534
|
local function boot(side, options)
|
|
451
|
-
|
|
452
|
-
|
|
535
|
+
local ok, err = pcall(function()
|
|
536
|
+
side.network:open()
|
|
537
|
+
load(options.load)
|
|
538
|
+
side.network:loaded()
|
|
539
|
+
if side.name == "server" then
|
|
540
|
+
sealDeclarations()
|
|
541
|
+
end
|
|
542
|
+
ignite(robloxPort(), side, options)
|
|
543
|
+
end)
|
|
544
|
+
if ok then
|
|
545
|
+
return nil
|
|
546
|
+
end
|
|
547
|
+
side.network:close()
|
|
548
|
+
rollbackDeclarations()
|
|
549
|
+
error(err, 0)
|
|
453
550
|
end
|
|
454
551
|
return {
|
|
552
|
+
bootClock = bootClock,
|
|
553
|
+
shutdownProgress = shutdownProgress,
|
|
455
554
|
parsePattern = parsePattern,
|
|
456
555
|
load = load,
|
|
457
556
|
ignite = ignite,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const MAX_CONFIG_DECLARATIONS = 1000;
|
|
2
|
+
export declare const CONFIG_NAME_MAX_BYTES = 64;
|
|
3
|
+
export declare const CONFIG_VALUE_MAX_BYTES = 100000;
|
|
4
|
+
export declare const CONFIG_ADMISSION_VISITS = 100000;
|
|
5
|
+
export declare const CONFIG_REQUEST_CONCURRENCY = 4;
|
|
6
|
+
export declare const CONFIG_FETCH_RETRY_BASE_SECONDS = 1;
|
|
7
|
+
export declare const CONFIG_FETCH_RETRY_CAP_SECONDS = 30;
|
|
8
|
+
export declare const CONFIG_REFRESH_TIMEOUT_SECONDS = 10;
|
|
9
|
+
export declare const CONFIG_VALUE_DEPTH = 28;
|
|
10
|
+
export declare const CONFIG_STRING_MAX_BYTES = 65536;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local MAX_CONFIG_DECLARATIONS = 1_000
|
|
3
|
+
local CONFIG_NAME_MAX_BYTES = 64
|
|
4
|
+
local CONFIG_VALUE_MAX_BYTES = 100_000
|
|
5
|
+
local CONFIG_ADMISSION_VISITS = 100_000
|
|
6
|
+
local CONFIG_REQUEST_CONCURRENCY = 4
|
|
7
|
+
local CONFIG_FETCH_RETRY_BASE_SECONDS = 1
|
|
8
|
+
local CONFIG_FETCH_RETRY_CAP_SECONDS = 30
|
|
9
|
+
local CONFIG_REFRESH_TIMEOUT_SECONDS = 10
|
|
10
|
+
-- Rule 97 admits configs by rule 76's walk, whose depth and string bounds are data's PERSIST_DEPTH and
|
|
11
|
+
-- PERSIST_STRING_BYTES. Data's limits module is not under configs yet, so the values are restated here.
|
|
12
|
+
local CONFIG_VALUE_DEPTH = 28
|
|
13
|
+
local CONFIG_STRING_MAX_BYTES = 65_536
|
|
14
|
+
return {
|
|
15
|
+
MAX_CONFIG_DECLARATIONS = MAX_CONFIG_DECLARATIONS,
|
|
16
|
+
CONFIG_NAME_MAX_BYTES = CONFIG_NAME_MAX_BYTES,
|
|
17
|
+
CONFIG_VALUE_MAX_BYTES = CONFIG_VALUE_MAX_BYTES,
|
|
18
|
+
CONFIG_ADMISSION_VISITS = CONFIG_ADMISSION_VISITS,
|
|
19
|
+
CONFIG_REQUEST_CONCURRENCY = CONFIG_REQUEST_CONCURRENCY,
|
|
20
|
+
CONFIG_FETCH_RETRY_BASE_SECONDS = CONFIG_FETCH_RETRY_BASE_SECONDS,
|
|
21
|
+
CONFIG_FETCH_RETRY_CAP_SECONDS = CONFIG_FETCH_RETRY_CAP_SECONDS,
|
|
22
|
+
CONFIG_REFRESH_TIMEOUT_SECONDS = CONFIG_REFRESH_TIMEOUT_SECONDS,
|
|
23
|
+
CONFIG_VALUE_DEPTH = CONFIG_VALUE_DEPTH,
|
|
24
|
+
CONFIG_STRING_MAX_BYTES = CONFIG_STRING_MAX_BYTES,
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Disconnect } from "../port";
|
|
2
|
+
export interface ConfigSnapshotPort {
|
|
3
|
+
/** `GetValue`: nil for a missing key. A JSON config may arrive as a table or as its text. */
|
|
4
|
+
readonly get: (key: string) => unknown;
|
|
5
|
+
/** `Refresh`. Yields and may throw. */
|
|
6
|
+
readonly refresh: () => void;
|
|
7
|
+
/** Unmeasured in Studio: whether this turns true without `UpdateAvailable`. Runtime treats the two as independent. */
|
|
8
|
+
readonly outdated: () => boolean;
|
|
9
|
+
/** `Error` is `LoadFailed`. */
|
|
10
|
+
readonly failed: () => boolean;
|
|
11
|
+
readonly onUpdateAvailable: (listener: () => void) => Disconnect;
|
|
12
|
+
}
|
|
13
|
+
/** What configs ask of the engine. Requests yield and may throw. */
|
|
14
|
+
export interface ConfigPort {
|
|
15
|
+
readonly global: () => ConfigSnapshotPort;
|
|
16
|
+
readonly forPlayer: (player: Player) => ConfigSnapshotPort;
|
|
17
|
+
readonly players: () => readonly Player[];
|
|
18
|
+
readonly onPlayerAdded: (listener: (player: Player) => void) => Disconnect;
|
|
19
|
+
readonly onPlayerRemoving: (listener: (player: Player) => void) => Disconnect;
|
|
20
|
+
readonly wait: (seconds: number) => void;
|
|
21
|
+
/** Uniform in [0, 1). */
|
|
22
|
+
readonly random: () => number;
|
|
23
|
+
readonly decodeJson: (text: string) => unknown;
|
|
24
|
+
/** The JSON text length of a decoded value. Throws for a value JSON cannot hold. */
|
|
25
|
+
readonly jsonBytes: (value: object) => number;
|
|
26
|
+
}
|
|
27
|
+
export declare function installConfigPort(value: ConfigPort): void;
|
|
28
|
+
export declare function configPort(): ConfigPort;
|
|
29
|
+
export declare function createRobloxConfigPort(): ConfigPort;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
--* What configs ask of the engine. Requests yield and may throw.
|
|
3
|
+
local port
|
|
4
|
+
local function installConfigPort(value)
|
|
5
|
+
local _arg0 = port == nil
|
|
6
|
+
assert(_arg0, "Config port already selected")
|
|
7
|
+
port = value
|
|
8
|
+
end
|
|
9
|
+
local createRobloxConfigPort
|
|
10
|
+
local function configPort()
|
|
11
|
+
if port == nil then
|
|
12
|
+
port = createRobloxConfigPort()
|
|
13
|
+
end
|
|
14
|
+
return port
|
|
15
|
+
end
|
|
16
|
+
local EMPTY = table.freeze({
|
|
17
|
+
get = function()
|
|
18
|
+
return nil
|
|
19
|
+
end,
|
|
20
|
+
refresh = function() end,
|
|
21
|
+
outdated = function()
|
|
22
|
+
return false
|
|
23
|
+
end,
|
|
24
|
+
failed = function()
|
|
25
|
+
return false
|
|
26
|
+
end,
|
|
27
|
+
onUpdateAvailable = function()
|
|
28
|
+
return function() end
|
|
29
|
+
end,
|
|
30
|
+
})
|
|
31
|
+
local function snapshotPort(snapshot)
|
|
32
|
+
return {
|
|
33
|
+
get = function(key)
|
|
34
|
+
return snapshot:GetValue(key)
|
|
35
|
+
end,
|
|
36
|
+
refresh = function()
|
|
37
|
+
return snapshot:Refresh()
|
|
38
|
+
end,
|
|
39
|
+
outdated = function()
|
|
40
|
+
return snapshot.Outdated
|
|
41
|
+
end,
|
|
42
|
+
failed = function()
|
|
43
|
+
return snapshot.Error == Enum.ConfigSnapshotErrorState.LoadFailed
|
|
44
|
+
end,
|
|
45
|
+
onUpdateAvailable = function(listener)
|
|
46
|
+
local connection = snapshot.UpdateAvailable:Connect(listener)
|
|
47
|
+
return function()
|
|
48
|
+
return connection:Disconnect()
|
|
49
|
+
end
|
|
50
|
+
end,
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
function createRobloxConfigPort()
|
|
54
|
+
local players = game:GetService("Players")
|
|
55
|
+
local http = game:GetService("HttpService")
|
|
56
|
+
local live = not game:GetService("RunService"):IsStudio() or game:GetService("ServerStorage"):GetAttribute("CrucibleLiveData") == true
|
|
57
|
+
local service = if live then game:GetService("ConfigService") else nil
|
|
58
|
+
local random = Random.new()
|
|
59
|
+
return {
|
|
60
|
+
global = function()
|
|
61
|
+
return if service == nil then EMPTY else snapshotPort(service:GetConfigAsync())
|
|
62
|
+
end,
|
|
63
|
+
forPlayer = function(player)
|
|
64
|
+
return if service == nil then EMPTY else snapshotPort(service:GetConfigForPlayerAsync(player))
|
|
65
|
+
end,
|
|
66
|
+
players = function()
|
|
67
|
+
return players:GetPlayers()
|
|
68
|
+
end,
|
|
69
|
+
onPlayerAdded = function(listener)
|
|
70
|
+
local connection = players.PlayerAdded:Connect(listener)
|
|
71
|
+
return function()
|
|
72
|
+
return connection:Disconnect()
|
|
73
|
+
end
|
|
74
|
+
end,
|
|
75
|
+
onPlayerRemoving = function(listener)
|
|
76
|
+
local connection = players.PlayerRemoving:Connect(listener)
|
|
77
|
+
return function()
|
|
78
|
+
return connection:Disconnect()
|
|
79
|
+
end
|
|
80
|
+
end,
|
|
81
|
+
wait = function(seconds)
|
|
82
|
+
task.wait(seconds)
|
|
83
|
+
end,
|
|
84
|
+
random = function()
|
|
85
|
+
return random:NextNumber()
|
|
86
|
+
end,
|
|
87
|
+
decodeJson = function(text)
|
|
88
|
+
return http:JSONDecode(text)
|
|
89
|
+
end,
|
|
90
|
+
jsonBytes = function(value)
|
|
91
|
+
return #http:JSONEncode(value)
|
|
92
|
+
end,
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
return {
|
|
96
|
+
installConfigPort = installConfigPort,
|
|
97
|
+
configPort = configPort,
|
|
98
|
+
createRobloxConfigPort = createRobloxConfigPort,
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Node } from "../network/schema";
|
|
2
|
+
import { type StateNode } from "../reactive/graph";
|
|
3
|
+
export type ConfigKind = "global" | "player";
|
|
4
|
+
/** One value a reader sees. Commit is its only writer. */
|
|
5
|
+
/** A config value as reactive state, so a read is tracked (rule 93) and a commit wakes its readers once. */
|
|
6
|
+
type Cell = StateNode;
|
|
7
|
+
export interface Declaration {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly kind: ConfigKind;
|
|
10
|
+
readonly node: Node;
|
|
11
|
+
readonly fallback: unknown;
|
|
12
|
+
/** The value admitted from the global snapshot. */
|
|
13
|
+
readonly global: Cell;
|
|
14
|
+
}
|
|
15
|
+
export declare function declare(name: string, kind: ConfigKind, fallback: unknown, node: Node): Declaration;
|
|
16
|
+
export declare function readGlobal(declaration: Declaration): unknown;
|
|
17
|
+
export declare function readPlayer(declaration: Declaration, player: Player): unknown;
|
|
18
|
+
export declare function ready(player?: Player): boolean;
|
|
19
|
+
export declare function refresh(): boolean;
|
|
20
|
+
export declare function installConfigRuntime(): void;
|
|
21
|
+
export {};
|