roblox-opencode 1.0.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/README.md +122 -0
- package/commands/setup-game.md +108 -0
- package/commands/sync-check.md +53 -0
- package/core/roblox-core.md +93 -0
- package/dist/server.js +167 -0
- package/package.json +35 -0
- package/skills/roblox-analytics/SKILL.md +277 -0
- package/skills/roblox-analytics/references/event-batcher.luau +75 -0
- package/skills/roblox-animation-vfx/SKILL.md +1325 -0
- package/skills/roblox-architecture/SKILL.md +863 -0
- package/skills/roblox-architecture/references/combat-systems.md +1381 -0
- package/skills/roblox-code-review/SKILL.md +687 -0
- package/skills/roblox-data/SKILL.md +889 -0
- package/skills/roblox-data/references/inventory-systems.md +1729 -0
- package/skills/roblox-debug/SKILL.md +99 -0
- package/skills/roblox-gui/SKILL.md +1103 -0
- package/skills/roblox-gui-fusion/SKILL.md +150 -0
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
- package/skills/roblox-gui-fusion/references/shop.luau +411 -0
- package/skills/roblox-luau-mastery/SKILL.md +1519 -0
- package/skills/roblox-monetization/SKILL.md +1084 -0
- package/skills/roblox-monetization/references/process-receipt.luau +131 -0
- package/skills/roblox-networking/SKILL.md +669 -0
- package/skills/roblox-networking/references/remote-validator.luau +193 -0
- package/skills/roblox-publish-checklist/SKILL.md +128 -0
- package/skills/roblox-runtime/SKILL.md +753 -0
- package/skills/roblox-sharp-edges/SKILL.md +295 -0
- package/skills/roblox-sync/SKILL.md +126 -0
- package/skills/roblox-testing/SKILL.md +943 -0
- package/skills/roblox-tooling/SKILL.md +150 -0
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
- package/vendor/LICENSES/promise-LICENSE +21 -0
- package/vendor/LICENSES/t-LICENSE +21 -0
- package/vendor/LICENSES/testez-LICENSE +201 -0
- package/vendor/README.md +84 -0
- package/vendor/fusion/Animation/ExternalTime.luau +84 -0
- package/vendor/fusion/Animation/Spring.luau +322 -0
- package/vendor/fusion/Animation/Stopwatch.luau +128 -0
- package/vendor/fusion/Animation/Tween.luau +187 -0
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
- package/vendor/fusion/Animation/lerpType.luau +164 -0
- package/vendor/fusion/Animation/packType.luau +100 -0
- package/vendor/fusion/Animation/springCoefficients.luau +80 -0
- package/vendor/fusion/Animation/unpackType.luau +103 -0
- package/vendor/fusion/Colour/Oklab.luau +70 -0
- package/vendor/fusion/Colour/sRGB.luau +55 -0
- package/vendor/fusion/External.luau +168 -0
- package/vendor/fusion/ExternalDebug.luau +70 -0
- package/vendor/fusion/Graph/Observer.luau +114 -0
- package/vendor/fusion/Graph/castToGraph.luau +29 -0
- package/vendor/fusion/Graph/change.luau +81 -0
- package/vendor/fusion/Graph/depend.luau +33 -0
- package/vendor/fusion/Graph/evaluate.luau +56 -0
- package/vendor/fusion/Instances/Attribute.luau +58 -0
- package/vendor/fusion/Instances/AttributeChange.luau +47 -0
- package/vendor/fusion/Instances/AttributeOut.luau +63 -0
- package/vendor/fusion/Instances/Child.luau +21 -0
- package/vendor/fusion/Instances/Children.luau +148 -0
- package/vendor/fusion/Instances/Hydrate.luau +33 -0
- package/vendor/fusion/Instances/New.luau +53 -0
- package/vendor/fusion/Instances/OnChange.luau +50 -0
- package/vendor/fusion/Instances/OnEvent.luau +54 -0
- package/vendor/fusion/Instances/Out.luau +69 -0
- package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
- package/vendor/fusion/Instances/defaultProps.luau +194 -0
- package/vendor/fusion/LICENSE +21 -0
- package/vendor/fusion/Logging/formatError.luau +49 -0
- package/vendor/fusion/Logging/messages.luau +52 -0
- package/vendor/fusion/Logging/parseError.luau +25 -0
- package/vendor/fusion/Memory/checkLifetime.luau +134 -0
- package/vendor/fusion/Memory/deriveScope.luau +24 -0
- package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
- package/vendor/fusion/Memory/doCleanup.luau +79 -0
- package/vendor/fusion/Memory/innerScope.luau +34 -0
- package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
- package/vendor/fusion/Memory/needsDestruction.luau +17 -0
- package/vendor/fusion/Memory/poisonScope.luau +34 -0
- package/vendor/fusion/Memory/scopePool.luau +55 -0
- package/vendor/fusion/Memory/scoped.luau +27 -0
- package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
- package/vendor/fusion/RobloxExternal.luau +98 -0
- package/vendor/fusion/State/Computed.luau +139 -0
- package/vendor/fusion/State/For/Disassembly.luau +211 -0
- package/vendor/fusion/State/For/ForTypes.luau +30 -0
- package/vendor/fusion/State/For/init.luau +110 -0
- package/vendor/fusion/State/ForKeys.luau +94 -0
- package/vendor/fusion/State/ForPairs.luau +97 -0
- package/vendor/fusion/State/ForValues.luau +94 -0
- package/vendor/fusion/State/Value.luau +88 -0
- package/vendor/fusion/State/castToState.luau +26 -0
- package/vendor/fusion/State/peek.luau +31 -0
- package/vendor/fusion/State/updateAll.luau +1 -0
- package/vendor/fusion/Types.luau +314 -0
- package/vendor/fusion/Utility/Contextual.luau +91 -0
- package/vendor/fusion/Utility/Safe.luau +23 -0
- package/vendor/fusion/Utility/isSimilar.luau +29 -0
- package/vendor/fusion/Utility/merge.luau +35 -0
- package/vendor/fusion/Utility/nameOf.luau +35 -0
- package/vendor/fusion/Utility/never.luau +14 -0
- package/vendor/fusion/Utility/nicknames.luau +11 -0
- package/vendor/fusion/Utility/xtypeof.luau +27 -0
- package/vendor/fusion/init.luau +82 -0
- package/vendor/profilestore/init.luau +2243 -0
- package/vendor/promise/init.luau +1982 -0
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
- package/vendor/rbxutil/buffer-util/Types.luau +60 -0
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
- package/vendor/rbxutil/buffer-util/init.luau +41 -0
- package/vendor/rbxutil/buffer-util/package.json +16 -0
- package/vendor/rbxutil/buffer-util/wally.toml +9 -0
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
- package/vendor/rbxutil/comm/Client/init.luau +135 -0
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
- package/vendor/rbxutil/comm/Server/init.luau +140 -0
- package/vendor/rbxutil/comm/Types.luau +18 -0
- package/vendor/rbxutil/comm/Util.luau +27 -0
- package/vendor/rbxutil/comm/init.luau +35 -0
- package/vendor/rbxutil/comm/wally.toml +13 -0
- package/vendor/rbxutil/component/init.luau +759 -0
- package/vendor/rbxutil/component/init.test.luau +311 -0
- package/vendor/rbxutil/component/wally.toml +14 -0
- package/vendor/rbxutil/concur/init.luau +542 -0
- package/vendor/rbxutil/concur/init.test.luau +364 -0
- package/vendor/rbxutil/concur/wally.toml +8 -0
- package/vendor/rbxutil/enum-list/init.luau +101 -0
- package/vendor/rbxutil/enum-list/init.test.luau +91 -0
- package/vendor/rbxutil/enum-list/wally.toml +8 -0
- package/vendor/rbxutil/find/index.d.ts +20 -0
- package/vendor/rbxutil/find/init.luau +44 -0
- package/vendor/rbxutil/find/package.json +17 -0
- package/vendor/rbxutil/find/wally.toml +8 -0
- package/vendor/rbxutil/input/Gamepad.luau +559 -0
- package/vendor/rbxutil/input/Keyboard.luau +124 -0
- package/vendor/rbxutil/input/Mouse.luau +278 -0
- package/vendor/rbxutil/input/PreferredInput.luau +91 -0
- package/vendor/rbxutil/input/Touch.luau +120 -0
- package/vendor/rbxutil/input/init.luau +33 -0
- package/vendor/rbxutil/input/wally.toml +12 -0
- package/vendor/rbxutil/loader/index.d.ts +15 -0
- package/vendor/rbxutil/loader/init.luau +137 -0
- package/vendor/rbxutil/loader/wally.toml +8 -0
- package/vendor/rbxutil/log/index.d.ts +38 -0
- package/vendor/rbxutil/log/init.luau +746 -0
- package/vendor/rbxutil/log/wally.toml +8 -0
- package/vendor/rbxutil/net/init.luau +190 -0
- package/vendor/rbxutil/net/wally.toml +8 -0
- package/vendor/rbxutil/option/index.d.ts +44 -0
- package/vendor/rbxutil/option/init.luau +489 -0
- package/vendor/rbxutil/option/init.test.luau +342 -0
- package/vendor/rbxutil/option/wally.toml +8 -0
- package/vendor/rbxutil/pid/index.d.ts +53 -0
- package/vendor/rbxutil/pid/init.luau +195 -0
- package/vendor/rbxutil/pid/package.json +16 -0
- package/vendor/rbxutil/pid/wally.toml +9 -0
- package/vendor/rbxutil/quaternion/index.d.ts +117 -0
- package/vendor/rbxutil/quaternion/init.luau +570 -0
- package/vendor/rbxutil/quaternion/package.json +16 -0
- package/vendor/rbxutil/quaternion/wally.toml +9 -0
- package/vendor/rbxutil/query/index.d.ts +43 -0
- package/vendor/rbxutil/query/init.luau +117 -0
- package/vendor/rbxutil/query/package.json +18 -0
- package/vendor/rbxutil/query/wally.toml +9 -0
- package/vendor/rbxutil/sequent/index.d.ts +28 -0
- package/vendor/rbxutil/sequent/init.luau +340 -0
- package/vendor/rbxutil/sequent/package.json +16 -0
- package/vendor/rbxutil/sequent/wally.toml +9 -0
- package/vendor/rbxutil/ser/init.luau +175 -0
- package/vendor/rbxutil/ser/init.test.luau +50 -0
- package/vendor/rbxutil/ser/wally.toml +11 -0
- package/vendor/rbxutil/shake/index.d.ts +36 -0
- package/vendor/rbxutil/shake/init.luau +532 -0
- package/vendor/rbxutil/shake/init.test.luau +267 -0
- package/vendor/rbxutil/shake/package.json +16 -0
- package/vendor/rbxutil/shake/wally.toml +9 -0
- package/vendor/rbxutil/signal/index.d.ts +100 -0
- package/vendor/rbxutil/signal/init.luau +432 -0
- package/vendor/rbxutil/signal/init.test.luau +190 -0
- package/vendor/rbxutil/signal/package.json +17 -0
- package/vendor/rbxutil/signal/wally.toml +9 -0
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
- package/vendor/rbxutil/silo/Util.luau +55 -0
- package/vendor/rbxutil/silo/init.luau +338 -0
- package/vendor/rbxutil/silo/init.test.luau +215 -0
- package/vendor/rbxutil/silo/wally.toml +8 -0
- package/vendor/rbxutil/spring/index.d.ts +40 -0
- package/vendor/rbxutil/spring/init.luau +97 -0
- package/vendor/rbxutil/spring/package.json +17 -0
- package/vendor/rbxutil/spring/wally.toml +8 -0
- package/vendor/rbxutil/stream/index.d.ts +88 -0
- package/vendor/rbxutil/stream/init.luau +597 -0
- package/vendor/rbxutil/stream/package.json +18 -0
- package/vendor/rbxutil/stream/wally.toml +9 -0
- package/vendor/rbxutil/streamable/Streamable.luau +202 -0
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
- package/vendor/rbxutil/streamable/init.luau +8 -0
- package/vendor/rbxutil/streamable/wally.toml +12 -0
- package/vendor/rbxutil/symbol/init.luau +56 -0
- package/vendor/rbxutil/symbol/init.test.luau +37 -0
- package/vendor/rbxutil/symbol/wally.toml +8 -0
- package/vendor/rbxutil/table-util/init.luau +938 -0
- package/vendor/rbxutil/table-util/init.test.luau +439 -0
- package/vendor/rbxutil/table-util/wally.toml +8 -0
- package/vendor/rbxutil/task-queue/index.d.ts +27 -0
- package/vendor/rbxutil/task-queue/init.luau +97 -0
- package/vendor/rbxutil/task-queue/wally.toml +8 -0
- package/vendor/rbxutil/timer/index.d.ts +81 -0
- package/vendor/rbxutil/timer/init.luau +249 -0
- package/vendor/rbxutil/timer/init.test.luau +73 -0
- package/vendor/rbxutil/timer/wally.toml +11 -0
- package/vendor/rbxutil/tree/index.d.ts +15 -0
- package/vendor/rbxutil/tree/init.luau +137 -0
- package/vendor/rbxutil/tree/wally.toml +8 -0
- package/vendor/rbxutil/trove/index.d.ts +46 -0
- package/vendor/rbxutil/trove/init.luau +787 -0
- package/vendor/rbxutil/trove/init.test.luau +203 -0
- package/vendor/rbxutil/trove/wally.toml +8 -0
- package/vendor/rbxutil/typed-remote/init.luau +196 -0
- package/vendor/rbxutil/typed-remote/wally.toml +8 -0
- package/vendor/rbxutil/wait-for/index.d.ts +17 -0
- package/vendor/rbxutil/wait-for/init.luau +257 -0
- package/vendor/rbxutil/wait-for/init.test.luau +182 -0
- package/vendor/rbxutil/wait-for/wally.toml +11 -0
- package/vendor/t/t.lua +1350 -0
- package/vendor/testez/Context.lua +26 -0
- package/vendor/testez/Expectation.lua +311 -0
- package/vendor/testez/ExpectationContext.lua +38 -0
- package/vendor/testez/LifecycleHooks.lua +89 -0
- package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
- package/vendor/testez/Reporters/TextReporter.lua +106 -0
- package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
- package/vendor/testez/TestBootstrap.lua +147 -0
- package/vendor/testez/TestEnum.lua +28 -0
- package/vendor/testez/TestPlan.lua +304 -0
- package/vendor/testez/TestPlanner.lua +40 -0
- package/vendor/testez/TestResults.lua +112 -0
- package/vendor/testez/TestRunner.lua +188 -0
- package/vendor/testez/TestSession.lua +243 -0
- package/vendor/testez/init.lua +40 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
A state object which allows regular Luau code to control its value.
|
|
8
|
+
|
|
9
|
+
https://elttob.uk/Fusion/0.3/api-reference/state/types/value/
|
|
10
|
+
]]
|
|
11
|
+
|
|
12
|
+
local Package = script.Parent.Parent
|
|
13
|
+
local Types = require(Package.Types)
|
|
14
|
+
local External = require(Package.External)
|
|
15
|
+
-- Graph
|
|
16
|
+
local change = require(Package.Graph.change)
|
|
17
|
+
-- Utility
|
|
18
|
+
local isSimilar = require(Package.Utility.isSimilar)
|
|
19
|
+
local never = require(Package.Utility.never)
|
|
20
|
+
local nicknames = require(Package.Utility.nicknames)
|
|
21
|
+
|
|
22
|
+
type Self<T, S> = Types.Value<T, S>
|
|
23
|
+
|
|
24
|
+
local class = {}
|
|
25
|
+
class.type = "State"
|
|
26
|
+
class.kind = "Value"
|
|
27
|
+
class.timeliness = "lazy"
|
|
28
|
+
class.dependencySet = table.freeze {}
|
|
29
|
+
|
|
30
|
+
local METATABLE = table.freeze {__index = class}
|
|
31
|
+
|
|
32
|
+
local function Value<T>(
|
|
33
|
+
scope: Types.Scope<unknown>,
|
|
34
|
+
initialValue: T
|
|
35
|
+
): Types.Value<T, any>
|
|
36
|
+
local createdAt = os.clock()
|
|
37
|
+
if initialValue == nil and (typeof(scope) ~= "table" or (scope[1] == nil and next(scope) ~= nil)) then
|
|
38
|
+
External.logError("scopeMissing", nil, "Value", "myScope:Value(initialValue)")
|
|
39
|
+
end
|
|
40
|
+
local self: Self<T, any> = setmetatable(
|
|
41
|
+
{
|
|
42
|
+
createdAt = createdAt,
|
|
43
|
+
dependentSet = {},
|
|
44
|
+
lastChange = os.clock(),
|
|
45
|
+
scope = scope,
|
|
46
|
+
validity = "valid",
|
|
47
|
+
_EXTREMELY_DANGEROUS_usedAsValue = initialValue
|
|
48
|
+
},
|
|
49
|
+
METATABLE
|
|
50
|
+
) :: any
|
|
51
|
+
local destroy = function()
|
|
52
|
+
self.scope = nil
|
|
53
|
+
end
|
|
54
|
+
self.oldestTask = destroy
|
|
55
|
+
nicknames[self.oldestTask] = "Value"
|
|
56
|
+
table.insert(scope, destroy)
|
|
57
|
+
return self
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
function class:get<T, S>(
|
|
61
|
+
_self: Self<T, S>
|
|
62
|
+
): never
|
|
63
|
+
External.logError("stateGetWasRemoved")
|
|
64
|
+
return never()
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
function class.set<T, S>(
|
|
68
|
+
self: Self<T, S>,
|
|
69
|
+
newValue: S
|
|
70
|
+
): S
|
|
71
|
+
local oldValue = self._EXTREMELY_DANGEROUS_usedAsValue
|
|
72
|
+
if not isSimilar(oldValue, newValue) then
|
|
73
|
+
self._EXTREMELY_DANGEROUS_usedAsValue = newValue :: any
|
|
74
|
+
change(self)
|
|
75
|
+
end
|
|
76
|
+
return newValue
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
function class._evaluate<T, S>(
|
|
80
|
+
_self: Self<T, S>
|
|
81
|
+
): boolean
|
|
82
|
+
-- The similarity test is done in advance when the value is set, so this
|
|
83
|
+
-- should be fine.
|
|
84
|
+
return true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
table.freeze(class)
|
|
88
|
+
return Value :: Types.ValueConstructor
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Returns the input *only* if it is a state object.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.Parent.Parent
|
|
11
|
+
local Types = require(Package.Types)
|
|
12
|
+
|
|
13
|
+
local function castToState<T>(
|
|
14
|
+
target: Types.UsedAs<T>
|
|
15
|
+
): Types.StateObject<T>?
|
|
16
|
+
if
|
|
17
|
+
typeof(target) == "table" and
|
|
18
|
+
target.type == "State"
|
|
19
|
+
then
|
|
20
|
+
return target
|
|
21
|
+
else
|
|
22
|
+
return nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
return castToState
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Extracts a value of type T from its input.
|
|
8
|
+
|
|
9
|
+
https://elttob.uk/Fusion/0.3/api-reference/state/members/peek/
|
|
10
|
+
]]
|
|
11
|
+
|
|
12
|
+
local Package = script.Parent.Parent
|
|
13
|
+
local Types = require(Package.Types)
|
|
14
|
+
-- State
|
|
15
|
+
local castToState = require(Package.State.castToState)
|
|
16
|
+
-- Graph
|
|
17
|
+
local evaluate = require(Package.Graph.evaluate)
|
|
18
|
+
|
|
19
|
+
local function peek<T>(
|
|
20
|
+
target: Types.UsedAs<T>
|
|
21
|
+
): T
|
|
22
|
+
local targetState = castToState(target)
|
|
23
|
+
if targetState ~= nil then
|
|
24
|
+
evaluate(targetState, false)
|
|
25
|
+
return targetState._EXTREMELY_DANGEROUS_usedAsValue :: T
|
|
26
|
+
else
|
|
27
|
+
return target :: T
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
return peek
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
return nil -- dummy file so I can write tests
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Stores common public-facing type information for Fusion APIs.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
export type Error = {
|
|
11
|
+
type: "Error",
|
|
12
|
+
raw: string,
|
|
13
|
+
message: string,
|
|
14
|
+
trace: string,
|
|
15
|
+
context: string?
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
-- Types that can be expressed as vectors of numbers, and so can be animated.
|
|
19
|
+
export type Animatable =
|
|
20
|
+
number |
|
|
21
|
+
CFrame |
|
|
22
|
+
Color3 |
|
|
23
|
+
ColorSequenceKeypoint |
|
|
24
|
+
DateTime |
|
|
25
|
+
NumberRange |
|
|
26
|
+
NumberSequenceKeypoint |
|
|
27
|
+
PhysicalProperties |
|
|
28
|
+
Ray |
|
|
29
|
+
Rect |
|
|
30
|
+
Region3 |
|
|
31
|
+
Region3int16 |
|
|
32
|
+
UDim |
|
|
33
|
+
UDim2 |
|
|
34
|
+
Vector2 |
|
|
35
|
+
Vector2int16 |
|
|
36
|
+
Vector3 |
|
|
37
|
+
Vector3int16
|
|
38
|
+
|
|
39
|
+
-- A task which can be accepted for cleanup.
|
|
40
|
+
export type Task =
|
|
41
|
+
Instance |
|
|
42
|
+
RBXScriptConnection |
|
|
43
|
+
() -> () |
|
|
44
|
+
{destroy: (unknown) -> ()} |
|
|
45
|
+
{Destroy: (unknown) -> ()} |
|
|
46
|
+
{Task}
|
|
47
|
+
|
|
48
|
+
-- A scope of tasks to clean up.
|
|
49
|
+
export type Scope<Constructors = any> = {Task} & Constructors
|
|
50
|
+
|
|
51
|
+
-- An object which uses a scope to dictate how long it lives.
|
|
52
|
+
export type ScopedObject = {
|
|
53
|
+
scope: Scope<unknown>?,
|
|
54
|
+
oldestTask: unknown
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
-- Script-readable version information.
|
|
58
|
+
export type Version = {
|
|
59
|
+
major: number,
|
|
60
|
+
minor: number,
|
|
61
|
+
isRelease: boolean
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
-- An object which stores a value scoped in time.
|
|
65
|
+
export type Contextual<T> = {
|
|
66
|
+
type: "Contextual",
|
|
67
|
+
now: (Contextual<T>) -> T,
|
|
68
|
+
is: (Contextual<T>, T) -> ContextualIsMethods
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type ContextualIsMethods = {
|
|
72
|
+
during: <R, A...>(ContextualIsMethods, (A...) -> R, A...) -> R
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
-- A graph object which can have dependencies and dependencies.
|
|
76
|
+
export type GraphObject = ScopedObject & {
|
|
77
|
+
createdAt: number,
|
|
78
|
+
dependencySet: {[GraphObject]: unknown},
|
|
79
|
+
dependentSet: {[GraphObject]: unknown},
|
|
80
|
+
lastChange: number?,
|
|
81
|
+
timeliness: "lazy" | "eager",
|
|
82
|
+
validity: "valid" | "invalid" | "busy",
|
|
83
|
+
_evaluate: (GraphObject) -> boolean
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
-- An object which stores a piece of reactive state.
|
|
87
|
+
export type StateObject<T> = GraphObject & {
|
|
88
|
+
type: "State",
|
|
89
|
+
kind: string,
|
|
90
|
+
_EXTREMELY_DANGEROUS_usedAsValue: T
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
-- Passing values of this type to `Use` returns `T`.
|
|
94
|
+
export type UsedAs<T> = StateObject<T> | T
|
|
95
|
+
|
|
96
|
+
-- Function signature for use callbacks.
|
|
97
|
+
export type Use = <T>(target: UsedAs<T>) -> T
|
|
98
|
+
|
|
99
|
+
-- A state object whose value can be set at any time by the user.
|
|
100
|
+
export type Value<T, S = T> = StateObject<T> & {
|
|
101
|
+
kind: "State",
|
|
102
|
+
timeliness: "lazy",
|
|
103
|
+
set: (Value<T, S>, newValue: S, force: boolean?) -> S,
|
|
104
|
+
____phantom_setType: (never) -> S -- phantom data so this contains S
|
|
105
|
+
}
|
|
106
|
+
export type ValueConstructor = <T>(
|
|
107
|
+
scope: Scope<unknown>,
|
|
108
|
+
initialValue: T
|
|
109
|
+
) -> Value<T, any>
|
|
110
|
+
|
|
111
|
+
-- A state object whose value is derived from other objects using a callback.
|
|
112
|
+
export type Computed<T> = StateObject<T> & {
|
|
113
|
+
kind: "Computed",
|
|
114
|
+
timeliness: "lazy"
|
|
115
|
+
}
|
|
116
|
+
export type ComputedConstructor = <T, S>(
|
|
117
|
+
scope: S & Scope<unknown>,
|
|
118
|
+
callback: (Use, S) -> T
|
|
119
|
+
) -> Computed<T>
|
|
120
|
+
|
|
121
|
+
-- A state object which maps over keys and/or values in another table.
|
|
122
|
+
export type For<KO, VO> = StateObject<{[KO]: VO}> & {
|
|
123
|
+
kind: "For"
|
|
124
|
+
}
|
|
125
|
+
export type ForPairsConstructor = <KI, KO, VI, VO, S>(
|
|
126
|
+
scope: S & Scope<unknown>,
|
|
127
|
+
inputTable: UsedAs<{[KI]: VI}>,
|
|
128
|
+
processor: (Use, S, key: KI, value: VI) -> (KO, VO)
|
|
129
|
+
) -> For<KO, VO>
|
|
130
|
+
export type ForKeysConstructor = <KI, KO, V, S>(
|
|
131
|
+
scope: S & Scope<unknown>,
|
|
132
|
+
inputTable: UsedAs<{[KI]: V}>,
|
|
133
|
+
processor: (Use, S, key: KI) -> KO
|
|
134
|
+
) -> For<KO, V>
|
|
135
|
+
export type ForValuesConstructor = <K, VI, VO, S>(
|
|
136
|
+
scope: S & Scope<unknown>,
|
|
137
|
+
inputTable: UsedAs<{[K]: VI}>,
|
|
138
|
+
processor: (Use, S, value: VI) -> VO
|
|
139
|
+
) -> For<K, VO>
|
|
140
|
+
|
|
141
|
+
-- An object which can listen for updates on another state object.
|
|
142
|
+
export type Observer = GraphObject & {
|
|
143
|
+
type: "Observer",
|
|
144
|
+
timeliness: "eager",
|
|
145
|
+
onChange: (Observer, callback: () -> ()) -> (() -> ()),
|
|
146
|
+
onBind: (Observer, callback: () -> ()) -> (() -> ())
|
|
147
|
+
}
|
|
148
|
+
export type ObserverConstructor = (
|
|
149
|
+
scope: Scope<unknown>,
|
|
150
|
+
watching: unknown
|
|
151
|
+
) -> Observer
|
|
152
|
+
|
|
153
|
+
-- A state object which follows another state object using tweens.
|
|
154
|
+
export type Tween<T> = StateObject<T> & {
|
|
155
|
+
kind: "Tween"
|
|
156
|
+
}
|
|
157
|
+
export type TweenConstructor = <T>(
|
|
158
|
+
scope: Scope<unknown>,
|
|
159
|
+
goalState: UsedAs<T>,
|
|
160
|
+
tweenInfo: UsedAs<TweenInfo>?
|
|
161
|
+
) -> Tween<T>
|
|
162
|
+
|
|
163
|
+
-- A state object which follows another state object using spring simulation.
|
|
164
|
+
export type Spring<T> = StateObject<T> & {
|
|
165
|
+
kind: "Spring",
|
|
166
|
+
setPosition: (Spring<T>, newPosition: T) -> (),
|
|
167
|
+
setVelocity: (Spring<T>, newVelocity: T) -> (),
|
|
168
|
+
addVelocity: (Spring<T>, deltaVelocity: T) -> ()
|
|
169
|
+
}
|
|
170
|
+
export type SpringConstructor = <T>(
|
|
171
|
+
scope: Scope<unknown>,
|
|
172
|
+
goalState: UsedAs<T>,
|
|
173
|
+
speed: UsedAs<number>?,
|
|
174
|
+
damping: UsedAs<number>?
|
|
175
|
+
) -> Spring<T>
|
|
176
|
+
|
|
177
|
+
-- Denotes children instances in an instance or component's property table.
|
|
178
|
+
export type SpecialKey = {
|
|
179
|
+
type: "SpecialKey",
|
|
180
|
+
kind: string,
|
|
181
|
+
stage: "self" | "descendants" | "ancestor" | "observer",
|
|
182
|
+
apply: (
|
|
183
|
+
self: SpecialKey,
|
|
184
|
+
scope: Scope<unknown>,
|
|
185
|
+
value: unknown,
|
|
186
|
+
applyTo: Instance
|
|
187
|
+
) -> ()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
-- A collection of instances that may be parented to another instance.
|
|
191
|
+
export type Child = Instance | StateObject<Child> | {[unknown]: Child}
|
|
192
|
+
|
|
193
|
+
-- A table that defines an instance's properties, handlers and children.
|
|
194
|
+
export type PropertyTable = {[string | SpecialKey]: unknown}
|
|
195
|
+
|
|
196
|
+
export type NewConstructor = (
|
|
197
|
+
scope: Scope<unknown>,
|
|
198
|
+
className: string
|
|
199
|
+
) -> (propertyTable: PropertyTable) -> Instance
|
|
200
|
+
|
|
201
|
+
export type HydrateConstructor = (
|
|
202
|
+
scope: Scope<unknown>,
|
|
203
|
+
target: Instance
|
|
204
|
+
) -> (propertyTable: PropertyTable) -> Instance
|
|
205
|
+
|
|
206
|
+
-- Is there a sane way to write out this type?
|
|
207
|
+
-- ... I sure hope so.
|
|
208
|
+
|
|
209
|
+
export type DeriveScopeConstructor = (<S>(Scope<S>) -> Scope<S>)
|
|
210
|
+
& (<S, A>(Scope<S>, A & {}) -> Scope<S & A>)
|
|
211
|
+
& (<S, A, B>(Scope<S>, A & {}, B & {}) -> Scope<S & A & B>)
|
|
212
|
+
& (<S, A, B, C>(Scope<S>, A & {}, B & {}, C & {}) -> Scope<S & A & B & C>)
|
|
213
|
+
& (<S, A, B, C, D>(Scope<S>, A & {}, B & {}, C & {}, D & {}) -> Scope<S & A & B & C & D>)
|
|
214
|
+
& (<S, A, B, C, D, E>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}) -> Scope<S & A & B & C & D & E>)
|
|
215
|
+
& (<S, A, B, C, D, E, F>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}) -> Scope<S & A & B & C & D & E & F>)
|
|
216
|
+
& (<S, A, B, C, D, E, F, G>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}) -> Scope<S & A & B & C & D & E & F & G>)
|
|
217
|
+
& (<S, A, B, C, D, E, F, G, H>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}) -> Scope<S & A & B & C & D & E & F & G & H>)
|
|
218
|
+
& (<S, A, B, C, D, E, F, G, H, I>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}) -> Scope<S & A & B & C & D & E & F & G & H & I>)
|
|
219
|
+
& (<S, A, B, C, D, E, F, G, H, I, J>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}) -> Scope<S & A & B & C & D & E & F & G & H & I & J>)
|
|
220
|
+
& (<S, A, B, C, D, E, F, G, H, I, J, K>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}, K & {}) -> Scope<S & A & B & C & D & E & F & G & H & I & J & K>)
|
|
221
|
+
& (<S, A, B, C, D, E, F, G, H, I, J, K, L>(Scope<S>, A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}, K & {}, L & {}) -> Scope<S & A & B & C & D & E & F & G & H & I & J & K & L>)
|
|
222
|
+
|
|
223
|
+
export type ScopedConstructor = (() -> Scope<{}>)
|
|
224
|
+
& (<A>(A & {}) -> Scope<A>)
|
|
225
|
+
& (<A, B>(A & {}, B & {}) -> Scope<A & B>)
|
|
226
|
+
& (<A, B, C>(A & {}, B & {}, C & {}) -> Scope<A & B & C>)
|
|
227
|
+
& (<A, B, C, D>(A & {}, B & {}, C & {}, D & {}) -> Scope<A & B & C & D>)
|
|
228
|
+
& (<A, B, C, D, E>(A & {}, B & {}, C & {}, D & {}, E & {}) -> Scope<A & B & C & D & E>)
|
|
229
|
+
& (<A, B, C, D, E, F>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}) -> Scope<A & B & C & D & E & F>)
|
|
230
|
+
& (<A, B, C, D, E, F, G>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}) -> Scope<A & B & C & D & E & F & G>)
|
|
231
|
+
& (<A, B, C, D, E, F, G, H>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}) -> Scope<A & B & C & D & E & F & G & H>)
|
|
232
|
+
& (<A, B, C, D, E, F, G, H, I>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}) -> Scope<A & B & C & D & E & F & G & H & I>)
|
|
233
|
+
& (<A, B, C, D, E, F, G, H, I, J>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}) -> Scope<A & B & C & D & E & F & G & H & I & J>)
|
|
234
|
+
& (<A, B, C, D, E, F, G, H, I, J, K>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}, K & {}) -> Scope<A & B & C & D & E & F & G & H & I & J & K>)
|
|
235
|
+
& (<A, B, C, D, E, F, G, H, I, J, K, L>(A & {}, B & {}, C & {}, D & {}, E & {}, F & {}, G & {}, H & {}, I & {}, J & {}, K & {}, L & {}) -> Scope<A & B & C & D & E & F & G & H & I & J & K & L>)
|
|
236
|
+
|
|
237
|
+
export type ContextualConstructor = <T>(defaultValue: T) -> Contextual<T>
|
|
238
|
+
|
|
239
|
+
export type Safe = <Success, Fail>(
|
|
240
|
+
callbacks: {
|
|
241
|
+
try: () -> Success,
|
|
242
|
+
fallback: (err: unknown) -> Fail
|
|
243
|
+
}
|
|
244
|
+
) -> Success | Fail
|
|
245
|
+
|
|
246
|
+
export type Fusion = {
|
|
247
|
+
version: Version,
|
|
248
|
+
Contextual: ContextualConstructor,
|
|
249
|
+
Safe: Safe,
|
|
250
|
+
|
|
251
|
+
doCleanup: (Task) -> (),
|
|
252
|
+
scoped: ScopedConstructor,
|
|
253
|
+
deriveScope: DeriveScopeConstructor,
|
|
254
|
+
innerScope: DeriveScopeConstructor,
|
|
255
|
+
|
|
256
|
+
peek: Use,
|
|
257
|
+
Value: ValueConstructor,
|
|
258
|
+
Computed: ComputedConstructor,
|
|
259
|
+
ForPairs: ForPairsConstructor,
|
|
260
|
+
ForKeys: ForKeysConstructor,
|
|
261
|
+
ForValues: ForValuesConstructor,
|
|
262
|
+
Observer: ObserverConstructor,
|
|
263
|
+
|
|
264
|
+
Tween: TweenConstructor,
|
|
265
|
+
Spring: SpringConstructor,
|
|
266
|
+
|
|
267
|
+
New: NewConstructor,
|
|
268
|
+
Hydrate: HydrateConstructor,
|
|
269
|
+
|
|
270
|
+
Child: ({Child}) -> Child,
|
|
271
|
+
Children: SpecialKey,
|
|
272
|
+
Out: (propertyName: string) -> SpecialKey,
|
|
273
|
+
OnEvent: (eventName: string) -> SpecialKey,
|
|
274
|
+
OnChange: (propertyName: string) -> SpecialKey,
|
|
275
|
+
Attribute: (attributeName: string) -> SpecialKey,
|
|
276
|
+
AttributeChange: (attributeName: string) -> SpecialKey,
|
|
277
|
+
AttributeOut: (attributeName: string) -> SpecialKey,
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export type ExternalProvider = {
|
|
281
|
+
policies: {
|
|
282
|
+
allowWebLinks: boolean
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
logErrorNonFatal: (
|
|
286
|
+
errorString: string
|
|
287
|
+
) -> (),
|
|
288
|
+
logWarn: (
|
|
289
|
+
errorString: string
|
|
290
|
+
) -> (),
|
|
291
|
+
|
|
292
|
+
doTaskImmediate: (
|
|
293
|
+
resume: () -> ()
|
|
294
|
+
) -> (),
|
|
295
|
+
doTaskDeferred: (
|
|
296
|
+
resume: () -> ()
|
|
297
|
+
) -> (),
|
|
298
|
+
startScheduler: () -> (),
|
|
299
|
+
stopScheduler: () -> ()
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export type ExternalDebugger = {
|
|
303
|
+
startDebugging: () -> (),
|
|
304
|
+
stopDebugging: () -> (),
|
|
305
|
+
|
|
306
|
+
trackScope: (
|
|
307
|
+
scope: Scope<unknown>
|
|
308
|
+
) -> (),
|
|
309
|
+
untrackScope: (
|
|
310
|
+
scope: Scope<unknown>
|
|
311
|
+
) -> ()
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return nil
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Time-based contextual values, to allow for transparently passing values down
|
|
8
|
+
the call stack.
|
|
9
|
+
]]
|
|
10
|
+
|
|
11
|
+
local Package = script.Parent.Parent
|
|
12
|
+
local Types = require(Package.Types)
|
|
13
|
+
local External = require(Package.External)
|
|
14
|
+
-- Logging
|
|
15
|
+
local parseError = require(Package.Logging.parseError)
|
|
16
|
+
|
|
17
|
+
export type Self<T> = Types.Contextual<T> & {
|
|
18
|
+
_valuesNow: {[thread]: {value: T}},
|
|
19
|
+
_defaultValue: T
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
local class = {}
|
|
23
|
+
class.type = "Contextual"
|
|
24
|
+
|
|
25
|
+
local METATABLE = table.freeze {__index = class}
|
|
26
|
+
local WEAK_KEYS_METATABLE = table.freeze {__mode = "k"}
|
|
27
|
+
|
|
28
|
+
local function Contextual<T>(
|
|
29
|
+
defaultValue: T
|
|
30
|
+
): Types.Contextual<T>
|
|
31
|
+
local self: Self<T> = setmetatable(
|
|
32
|
+
{
|
|
33
|
+
-- if we held strong references to threads here, then if a thread was
|
|
34
|
+
-- killed before this contextual had a chance to finish executing its
|
|
35
|
+
-- callback, it would be held strongly in this table forever
|
|
36
|
+
_valuesNow = setmetatable({}, WEAK_KEYS_METATABLE),
|
|
37
|
+
_defaultValue = defaultValue
|
|
38
|
+
},
|
|
39
|
+
METATABLE
|
|
40
|
+
) :: any
|
|
41
|
+
|
|
42
|
+
return self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
--[[
|
|
46
|
+
Returns the current value of this contextual.
|
|
47
|
+
]]
|
|
48
|
+
function class.now<T>(
|
|
49
|
+
self: Self<T>
|
|
50
|
+
): T
|
|
51
|
+
local thread = coroutine.running()
|
|
52
|
+
local value = self._valuesNow[thread]
|
|
53
|
+
if typeof(value) ~= "table" then
|
|
54
|
+
return self._defaultValue
|
|
55
|
+
else
|
|
56
|
+
return value.value
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
--[[
|
|
61
|
+
Temporarily assigns a value to this contextual.
|
|
62
|
+
]]
|
|
63
|
+
function class.is<T>(
|
|
64
|
+
self: Self<T>,
|
|
65
|
+
newValue: T
|
|
66
|
+
)
|
|
67
|
+
local methods = {}
|
|
68
|
+
|
|
69
|
+
function methods.during<T, A...>(
|
|
70
|
+
_: any, -- during is called with colon syntax but we don't care
|
|
71
|
+
callback: (A...) -> T,
|
|
72
|
+
...: A...
|
|
73
|
+
): T
|
|
74
|
+
local thread = coroutine.running()
|
|
75
|
+
local prevValue = self._valuesNow[thread]
|
|
76
|
+
-- Storing the value in this format allows us to distinguish storing
|
|
77
|
+
-- `nil` from not calling `:during()` at all.
|
|
78
|
+
self._valuesNow[thread] = { value = newValue }
|
|
79
|
+
local ok, value = xpcall(callback, parseError, ...)
|
|
80
|
+
self._valuesNow[thread] = prevValue
|
|
81
|
+
if not ok then
|
|
82
|
+
External.logError("callbackError", value :: any)
|
|
83
|
+
end
|
|
84
|
+
return value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
return methods
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
table.freeze(class)
|
|
91
|
+
return Contextual
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
A variant of xpcall() designed for inline usage, letting you define fallback
|
|
8
|
+
values based on caught errors.
|
|
9
|
+
]]
|
|
10
|
+
|
|
11
|
+
local Package = script.Parent.Parent
|
|
12
|
+
|
|
13
|
+
local function Safe<Success, Fail>(
|
|
14
|
+
callbacks: {
|
|
15
|
+
try: () -> Success,
|
|
16
|
+
fallback: (err: unknown) -> Fail
|
|
17
|
+
}
|
|
18
|
+
): Success | Fail
|
|
19
|
+
local _, value = xpcall(callbacks.try, callbacks.fallback)
|
|
20
|
+
return value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return Safe
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Implements the 'similarity test' used to determine whether two values have
|
|
8
|
+
a meaningful difference.
|
|
9
|
+
|
|
10
|
+
https://elttob.uk/Fusion/0.3/tutorials/best-practices/optimisation/#similarity
|
|
11
|
+
]]
|
|
12
|
+
|
|
13
|
+
local function isSimilar(
|
|
14
|
+
a: unknown,
|
|
15
|
+
b: unknown
|
|
16
|
+
): boolean
|
|
17
|
+
local typeA = typeof(a)
|
|
18
|
+
local isTable = typeA == "table"
|
|
19
|
+
local isUserdata = typeA == "userdata"
|
|
20
|
+
return
|
|
21
|
+
if not (isTable or isUserdata) then
|
|
22
|
+
a == b or a ~= a and b ~= b
|
|
23
|
+
elseif typeA == typeof(b) and (isUserdata or table.isfrozen(a :: any) or getmetatable(a :: any) ~= nil) then
|
|
24
|
+
a == b
|
|
25
|
+
else
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
return isSimilar
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Attempts to merge a variadic number of tables together.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.Parent.Parent
|
|
11
|
+
local External = require(Package.External)
|
|
12
|
+
|
|
13
|
+
local function merge(
|
|
14
|
+
overwrite: boolean,
|
|
15
|
+
into: {[unknown]: unknown},
|
|
16
|
+
...: {[unknown]: unknown}
|
|
17
|
+
): {[unknown]: unknown}
|
|
18
|
+
local fromTables = {...}
|
|
19
|
+
if #fromTables < 1 then
|
|
20
|
+
return into
|
|
21
|
+
else
|
|
22
|
+
for _, fromTable in fromTables do
|
|
23
|
+
for key, value in fromTable do
|
|
24
|
+
if into[key] == nil then
|
|
25
|
+
into[key] = value
|
|
26
|
+
elseif not overwrite then
|
|
27
|
+
External.logError("mergeConflict", nil, tostring(key))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
return into
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return merge
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Returns the most specific custom name for the given object.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.Parent.Parent
|
|
11
|
+
-- Utility
|
|
12
|
+
local nicknames = require(Package.Utility.nicknames)
|
|
13
|
+
|
|
14
|
+
local function nameOf(
|
|
15
|
+
x: unknown,
|
|
16
|
+
defaultName: string
|
|
17
|
+
): string
|
|
18
|
+
local nickname = nicknames[x]
|
|
19
|
+
if typeof(nickname) == "string" then
|
|
20
|
+
return nickname
|
|
21
|
+
end
|
|
22
|
+
if typeof(x) == "table" then
|
|
23
|
+
local x = x :: {[any]: any}
|
|
24
|
+
if typeof(x.name) == "string" then
|
|
25
|
+
return x.name
|
|
26
|
+
elseif typeof(x.kind) == "string" then
|
|
27
|
+
return x.kind
|
|
28
|
+
elseif typeof(x.type) == "string" then
|
|
29
|
+
return x.type
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
return defaultName
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return nameOf
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Never returns.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local function never(): never
|
|
11
|
+
error("This codepath should not be reachable")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
return never
|