roblox-opencode 1.0.0 → 1.0.1

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 (246) hide show
  1. package/README.md +112 -122
  2. package/commands/setup-game.md +108 -108
  3. package/commands/sync-check.md +53 -53
  4. package/core/roblox-core.md +93 -93
  5. package/dist/server.js +189 -167
  6. package/package.json +35 -35
  7. package/skills/roblox-analytics/SKILL.md +277 -277
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -75
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
  10. package/skills/roblox-architecture/SKILL.md +863 -863
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
  12. package/skills/roblox-code-review/SKILL.md +686 -686
  13. package/skills/roblox-data/SKILL.md +889 -889
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -1729
  15. package/skills/roblox-debug/SKILL.md +98 -98
  16. package/skills/roblox-gui/SKILL.md +1103 -1103
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -150
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -411
  21. package/skills/roblox-luau-mastery/SKILL.md +1519 -1519
  22. package/skills/roblox-monetization/SKILL.md +1084 -1084
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -131
  24. package/skills/roblox-networking/SKILL.md +669 -669
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -193
  26. package/skills/roblox-publish-checklist/SKILL.md +127 -127
  27. package/skills/roblox-runtime/SKILL.md +753 -753
  28. package/skills/roblox-sharp-edges/SKILL.md +294 -294
  29. package/skills/roblox-sync/SKILL.md +126 -126
  30. package/skills/roblox-testing/SKILL.md +943 -943
  31. package/skills/roblox-tooling/SKILL.md +149 -149
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
  34. package/vendor/LICENSES/promise-LICENSE +20 -20
  35. package/vendor/LICENSES/t-LICENSE +21 -21
  36. package/vendor/LICENSES/testez-LICENSE +200 -200
  37. package/vendor/README.md +83 -83
  38. package/vendor/fusion/Animation/ExternalTime.luau +83 -83
  39. package/vendor/fusion/Animation/Spring.luau +321 -321
  40. package/vendor/fusion/Animation/Stopwatch.luau +127 -127
  41. package/vendor/fusion/Animation/Tween.luau +187 -187
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
  44. package/vendor/fusion/Animation/lerpType.luau +163 -163
  45. package/vendor/fusion/Animation/packType.luau +99 -99
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -80
  47. package/vendor/fusion/Animation/unpackType.luau +102 -102
  48. package/vendor/fusion/Colour/Oklab.luau +70 -70
  49. package/vendor/fusion/Colour/sRGB.luau +54 -54
  50. package/vendor/fusion/External.luau +167 -167
  51. package/vendor/fusion/ExternalDebug.luau +69 -69
  52. package/vendor/fusion/Graph/Observer.luau +113 -113
  53. package/vendor/fusion/Graph/castToGraph.luau +28 -28
  54. package/vendor/fusion/Graph/change.luau +80 -80
  55. package/vendor/fusion/Graph/depend.luau +32 -32
  56. package/vendor/fusion/Graph/evaluate.luau +55 -55
  57. package/vendor/fusion/Instances/Attribute.luau +57 -57
  58. package/vendor/fusion/Instances/AttributeChange.luau +46 -46
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -63
  60. package/vendor/fusion/Instances/Child.luau +21 -21
  61. package/vendor/fusion/Instances/Children.luau +147 -147
  62. package/vendor/fusion/Instances/Hydrate.luau +32 -32
  63. package/vendor/fusion/Instances/New.luau +52 -52
  64. package/vendor/fusion/Instances/OnChange.luau +49 -49
  65. package/vendor/fusion/Instances/OnEvent.luau +53 -53
  66. package/vendor/fusion/Instances/Out.luau +69 -69
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -194
  69. package/vendor/fusion/LICENSE +21 -21
  70. package/vendor/fusion/Logging/formatError.luau +48 -48
  71. package/vendor/fusion/Logging/messages.luau +51 -51
  72. package/vendor/fusion/Logging/parseError.luau +24 -24
  73. package/vendor/fusion/Memory/checkLifetime.luau +133 -133
  74. package/vendor/fusion/Memory/deriveScope.luau +23 -23
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
  76. package/vendor/fusion/Memory/doCleanup.luau +78 -78
  77. package/vendor/fusion/Memory/innerScope.luau +33 -33
  78. package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
  79. package/vendor/fusion/Memory/needsDestruction.luau +16 -16
  80. package/vendor/fusion/Memory/poisonScope.luau +33 -33
  81. package/vendor/fusion/Memory/scopePool.luau +54 -54
  82. package/vendor/fusion/Memory/scoped.luau +26 -26
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
  84. package/vendor/fusion/RobloxExternal.luau +97 -97
  85. package/vendor/fusion/State/Computed.luau +138 -138
  86. package/vendor/fusion/State/For/Disassembly.luau +210 -210
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -30
  88. package/vendor/fusion/State/For/init.luau +109 -109
  89. package/vendor/fusion/State/ForKeys.luau +93 -93
  90. package/vendor/fusion/State/ForPairs.luau +96 -96
  91. package/vendor/fusion/State/ForValues.luau +93 -93
  92. package/vendor/fusion/State/Value.luau +87 -87
  93. package/vendor/fusion/State/castToState.luau +25 -25
  94. package/vendor/fusion/State/peek.luau +30 -30
  95. package/vendor/fusion/Types.luau +314 -314
  96. package/vendor/fusion/Utility/Contextual.luau +90 -90
  97. package/vendor/fusion/Utility/Safe.luau +22 -22
  98. package/vendor/fusion/Utility/isSimilar.luau +29 -29
  99. package/vendor/fusion/Utility/merge.luau +35 -35
  100. package/vendor/fusion/Utility/nameOf.luau +34 -34
  101. package/vendor/fusion/Utility/never.luau +13 -13
  102. package/vendor/fusion/Utility/nicknames.luau +10 -10
  103. package/vendor/fusion/Utility/xtypeof.luau +26 -26
  104. package/vendor/fusion/init.luau +82 -82
  105. package/vendor/profilestore/init.luau +2242 -2242
  106. package/vendor/promise/init.luau +1982 -1982
  107. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
  108. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
  109. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
  110. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
  111. package/vendor/rbxutil/buffer-util/Types.luau +60 -60
  112. package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
  113. package/vendor/rbxutil/buffer-util/init.luau +41 -41
  114. package/vendor/rbxutil/buffer-util/package.json +16 -16
  115. package/vendor/rbxutil/buffer-util/wally.toml +9 -9
  116. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
  117. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
  118. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
  119. package/vendor/rbxutil/comm/Client/init.luau +135 -135
  120. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
  121. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
  122. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
  123. package/vendor/rbxutil/comm/Server/init.luau +140 -140
  124. package/vendor/rbxutil/comm/Types.luau +18 -18
  125. package/vendor/rbxutil/comm/Util.luau +27 -27
  126. package/vendor/rbxutil/comm/init.luau +35 -35
  127. package/vendor/rbxutil/comm/wally.toml +13 -13
  128. package/vendor/rbxutil/component/init.luau +759 -759
  129. package/vendor/rbxutil/component/init.test.luau +311 -311
  130. package/vendor/rbxutil/component/wally.toml +14 -14
  131. package/vendor/rbxutil/concur/init.luau +542 -542
  132. package/vendor/rbxutil/concur/init.test.luau +364 -364
  133. package/vendor/rbxutil/concur/wally.toml +8 -8
  134. package/vendor/rbxutil/enum-list/init.luau +101 -101
  135. package/vendor/rbxutil/enum-list/init.test.luau +91 -91
  136. package/vendor/rbxutil/enum-list/wally.toml +8 -8
  137. package/vendor/rbxutil/find/index.d.ts +20 -20
  138. package/vendor/rbxutil/find/init.luau +44 -44
  139. package/vendor/rbxutil/find/package.json +17 -17
  140. package/vendor/rbxutil/find/wally.toml +8 -8
  141. package/vendor/rbxutil/input/Gamepad.luau +559 -559
  142. package/vendor/rbxutil/input/Keyboard.luau +124 -124
  143. package/vendor/rbxutil/input/Mouse.luau +278 -278
  144. package/vendor/rbxutil/input/PreferredInput.luau +91 -91
  145. package/vendor/rbxutil/input/Touch.luau +120 -120
  146. package/vendor/rbxutil/input/init.luau +33 -33
  147. package/vendor/rbxutil/input/wally.toml +12 -12
  148. package/vendor/rbxutil/loader/index.d.ts +15 -15
  149. package/vendor/rbxutil/loader/init.luau +137 -137
  150. package/vendor/rbxutil/loader/wally.toml +8 -8
  151. package/vendor/rbxutil/log/index.d.ts +38 -38
  152. package/vendor/rbxutil/log/init.luau +746 -746
  153. package/vendor/rbxutil/log/wally.toml +8 -8
  154. package/vendor/rbxutil/net/init.luau +190 -190
  155. package/vendor/rbxutil/net/wally.toml +8 -8
  156. package/vendor/rbxutil/option/index.d.ts +44 -44
  157. package/vendor/rbxutil/option/init.luau +489 -489
  158. package/vendor/rbxutil/option/init.test.luau +342 -342
  159. package/vendor/rbxutil/option/wally.toml +8 -8
  160. package/vendor/rbxutil/pid/index.d.ts +53 -53
  161. package/vendor/rbxutil/pid/init.luau +195 -195
  162. package/vendor/rbxutil/pid/package.json +16 -16
  163. package/vendor/rbxutil/pid/wally.toml +9 -9
  164. package/vendor/rbxutil/quaternion/index.d.ts +117 -117
  165. package/vendor/rbxutil/quaternion/init.luau +570 -570
  166. package/vendor/rbxutil/quaternion/package.json +16 -16
  167. package/vendor/rbxutil/quaternion/wally.toml +9 -9
  168. package/vendor/rbxutil/query/index.d.ts +43 -43
  169. package/vendor/rbxutil/query/init.luau +117 -117
  170. package/vendor/rbxutil/query/package.json +18 -18
  171. package/vendor/rbxutil/query/wally.toml +9 -9
  172. package/vendor/rbxutil/sequent/index.d.ts +28 -28
  173. package/vendor/rbxutil/sequent/init.luau +340 -340
  174. package/vendor/rbxutil/sequent/package.json +16 -16
  175. package/vendor/rbxutil/sequent/wally.toml +9 -9
  176. package/vendor/rbxutil/ser/init.luau +175 -175
  177. package/vendor/rbxutil/ser/init.test.luau +50 -50
  178. package/vendor/rbxutil/ser/wally.toml +11 -11
  179. package/vendor/rbxutil/shake/index.d.ts +36 -36
  180. package/vendor/rbxutil/shake/init.luau +532 -532
  181. package/vendor/rbxutil/shake/init.test.luau +267 -267
  182. package/vendor/rbxutil/shake/package.json +16 -16
  183. package/vendor/rbxutil/shake/wally.toml +9 -9
  184. package/vendor/rbxutil/signal/index.d.ts +100 -100
  185. package/vendor/rbxutil/signal/init.luau +432 -432
  186. package/vendor/rbxutil/signal/init.test.luau +190 -190
  187. package/vendor/rbxutil/signal/package.json +17 -17
  188. package/vendor/rbxutil/signal/wally.toml +9 -9
  189. package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
  190. package/vendor/rbxutil/silo/Util.luau +55 -55
  191. package/vendor/rbxutil/silo/init.luau +338 -338
  192. package/vendor/rbxutil/silo/init.test.luau +215 -215
  193. package/vendor/rbxutil/silo/wally.toml +8 -8
  194. package/vendor/rbxutil/spring/index.d.ts +40 -40
  195. package/vendor/rbxutil/spring/init.luau +97 -97
  196. package/vendor/rbxutil/spring/package.json +17 -17
  197. package/vendor/rbxutil/spring/wally.toml +8 -8
  198. package/vendor/rbxutil/stream/index.d.ts +88 -88
  199. package/vendor/rbxutil/stream/init.luau +597 -597
  200. package/vendor/rbxutil/stream/package.json +18 -18
  201. package/vendor/rbxutil/stream/wally.toml +9 -9
  202. package/vendor/rbxutil/streamable/Streamable.luau +202 -202
  203. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
  204. package/vendor/rbxutil/streamable/init.luau +8 -8
  205. package/vendor/rbxutil/streamable/wally.toml +12 -12
  206. package/vendor/rbxutil/symbol/init.luau +56 -56
  207. package/vendor/rbxutil/symbol/init.test.luau +37 -37
  208. package/vendor/rbxutil/symbol/wally.toml +8 -8
  209. package/vendor/rbxutil/table-util/init.luau +938 -938
  210. package/vendor/rbxutil/table-util/init.test.luau +439 -439
  211. package/vendor/rbxutil/task-queue/index.d.ts +27 -27
  212. package/vendor/rbxutil/task-queue/init.luau +97 -97
  213. package/vendor/rbxutil/task-queue/wally.toml +8 -8
  214. package/vendor/rbxutil/timer/index.d.ts +81 -81
  215. package/vendor/rbxutil/timer/init.luau +249 -249
  216. package/vendor/rbxutil/timer/init.test.luau +73 -73
  217. package/vendor/rbxutil/timer/wally.toml +11 -11
  218. package/vendor/rbxutil/tree/index.d.ts +15 -15
  219. package/vendor/rbxutil/tree/init.luau +137 -137
  220. package/vendor/rbxutil/tree/wally.toml +8 -8
  221. package/vendor/rbxutil/trove/index.d.ts +46 -46
  222. package/vendor/rbxutil/trove/init.luau +787 -787
  223. package/vendor/rbxutil/trove/init.test.luau +203 -203
  224. package/vendor/rbxutil/trove/wally.toml +8 -8
  225. package/vendor/rbxutil/typed-remote/init.luau +196 -196
  226. package/vendor/rbxutil/typed-remote/wally.toml +8 -8
  227. package/vendor/rbxutil/wait-for/index.d.ts +17 -17
  228. package/vendor/rbxutil/wait-for/init.luau +257 -257
  229. package/vendor/rbxutil/wait-for/init.test.luau +182 -182
  230. package/vendor/rbxutil/wait-for/wally.toml +11 -11
  231. package/vendor/t/t.lua +1350 -1350
  232. package/vendor/testez/Context.lua +26 -26
  233. package/vendor/testez/Expectation.lua +311 -311
  234. package/vendor/testez/ExpectationContext.lua +38 -38
  235. package/vendor/testez/LifecycleHooks.lua +89 -89
  236. package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
  237. package/vendor/testez/Reporters/TextReporter.lua +105 -105
  238. package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
  239. package/vendor/testez/TestBootstrap.lua +146 -146
  240. package/vendor/testez/TestEnum.lua +27 -27
  241. package/vendor/testez/TestPlan.lua +304 -304
  242. package/vendor/testez/TestPlanner.lua +39 -39
  243. package/vendor/testez/TestResults.lua +111 -111
  244. package/vendor/testez/TestRunner.lua +188 -188
  245. package/vendor/testez/TestSession.lua +243 -243
  246. package/vendor/testez/init.lua +39 -39
@@ -1,58 +1,58 @@
1
- --!strict
2
- --!nolint LocalUnused
3
- --!nolint LocalShadow
4
- local task = nil -- Disable usage of Roblox's task scheduler
5
-
6
- --[[
7
- A special key for property tables, which allows users to apply custom
8
- attributes to instances
9
- ]]
10
-
11
- local Package = script.Parent.Parent
12
- local Types = require(Package.Types)
13
- -- Memory
14
- local checkLifetime = require(Package.Memory.checkLifetime)
15
- -- Graph
16
- local Observer = require(Package.Graph.Observer)
17
- -- State
18
- local castToState = require(Package.State.castToState)
19
- local peek = require(Package.State.peek)
20
-
21
- local keyCache: {[string]: Types.SpecialKey} = {}
22
-
23
- local function Attribute(
24
- attributeName: string
25
- ): Types.SpecialKey
26
- local key = keyCache[attributeName]
27
- if key == nil then
28
- key = {
29
- type = "SpecialKey",
30
- kind = "Attribute",
31
- stage = "self",
32
- apply = function(
33
- self: Types.SpecialKey,
34
- scope: Types.Scope<unknown>,
35
- value: unknown,
36
- applyTo: Instance
37
- )
38
- if castToState(value) then
39
- local value = value :: Types.StateObject<unknown>
40
- checkLifetime.bOutlivesA(
41
- scope, applyTo,
42
- value.scope, value.oldestTask,
43
- checkLifetime.formatters.boundAttribute, attributeName
44
- )
45
- Observer(scope, value :: any):onBind(function()
46
- applyTo:SetAttribute(attributeName, peek(value))
47
- end)
48
- else
49
- applyTo:SetAttribute(attributeName, value)
50
- end
51
- end
52
- }
53
- keyCache[attributeName] = key
54
- end
55
- return key
56
- end
57
-
1
+ --!strict
2
+ --!nolint LocalUnused
3
+ --!nolint LocalShadow
4
+ local task = nil -- Disable usage of Roblox's task scheduler
5
+
6
+ --[[
7
+ A special key for property tables, which allows users to apply custom
8
+ attributes to instances
9
+ ]]
10
+
11
+ local Package = script.Parent.Parent
12
+ local Types = require(Package.Types)
13
+ -- Memory
14
+ local checkLifetime = require(Package.Memory.checkLifetime)
15
+ -- Graph
16
+ local Observer = require(Package.Graph.Observer)
17
+ -- State
18
+ local castToState = require(Package.State.castToState)
19
+ local peek = require(Package.State.peek)
20
+
21
+ local keyCache: {[string]: Types.SpecialKey} = {}
22
+
23
+ local function Attribute(
24
+ attributeName: string
25
+ ): Types.SpecialKey
26
+ local key = keyCache[attributeName]
27
+ if key == nil then
28
+ key = {
29
+ type = "SpecialKey",
30
+ kind = "Attribute",
31
+ stage = "self",
32
+ apply = function(
33
+ self: Types.SpecialKey,
34
+ scope: Types.Scope<unknown>,
35
+ value: unknown,
36
+ applyTo: Instance
37
+ )
38
+ if castToState(value) then
39
+ local value = value :: Types.StateObject<unknown>
40
+ checkLifetime.bOutlivesA(
41
+ scope, applyTo,
42
+ value.scope, value.oldestTask,
43
+ checkLifetime.formatters.boundAttribute, attributeName
44
+ )
45
+ Observer(scope, value :: any):onBind(function()
46
+ applyTo:SetAttribute(attributeName, peek(value))
47
+ end)
48
+ else
49
+ applyTo:SetAttribute(attributeName, value)
50
+ end
51
+ end
52
+ }
53
+ keyCache[attributeName] = key
54
+ end
55
+ return key
56
+ end
57
+
58
58
  return Attribute
@@ -1,47 +1,47 @@
1
- --!strict
2
- --!nolint LocalUnused
3
- --!nolint LocalShadow
4
- local task = nil -- Disable usage of Roblox's task scheduler
5
-
6
- --[[
7
- A special key for property tables, which allows users to connect to
8
- an attribute change on an instance.
9
- ]]
10
-
11
- local Package = script.Parent.Parent
12
- local Types = require(Package.Types)
13
- local External = require(Package.External)
14
-
15
- local keyCache: {[string]: Types.SpecialKey} = {}
16
-
17
- local function AttributeChange(
18
- attributeName: string
19
- ): Types.SpecialKey
20
- local key = keyCache[attributeName]
21
- if key == nil then
22
- key = {
23
- type = "SpecialKey",
24
- kind = "AttributeChange",
25
- stage = "observer",
26
- apply = function(
27
- self: Types.SpecialKey,
28
- scope: Types.Scope<unknown>,
29
- value: unknown,
30
- applyTo: Instance
31
- )
32
- if typeof(value) ~= "function" then
33
- External.logError("invalidAttributeChangeHandler", nil, attributeName)
34
- end
35
- local value = value :: (...unknown) -> (...unknown)
36
- local event = applyTo:GetAttributeChangedSignal(attributeName)
37
- table.insert(scope, event:Connect(function()
38
- value((applyTo :: any):GetAttribute(attributeName))
39
- end))
40
- end
41
- }
42
- keyCache[attributeName] = key
43
- end
44
- return key
45
- end
46
-
1
+ --!strict
2
+ --!nolint LocalUnused
3
+ --!nolint LocalShadow
4
+ local task = nil -- Disable usage of Roblox's task scheduler
5
+
6
+ --[[
7
+ A special key for property tables, which allows users to connect to
8
+ an attribute change on an instance.
9
+ ]]
10
+
11
+ local Package = script.Parent.Parent
12
+ local Types = require(Package.Types)
13
+ local External = require(Package.External)
14
+
15
+ local keyCache: {[string]: Types.SpecialKey} = {}
16
+
17
+ local function AttributeChange(
18
+ attributeName: string
19
+ ): Types.SpecialKey
20
+ local key = keyCache[attributeName]
21
+ if key == nil then
22
+ key = {
23
+ type = "SpecialKey",
24
+ kind = "AttributeChange",
25
+ stage = "observer",
26
+ apply = function(
27
+ self: Types.SpecialKey,
28
+ scope: Types.Scope<unknown>,
29
+ value: unknown,
30
+ applyTo: Instance
31
+ )
32
+ if typeof(value) ~= "function" then
33
+ External.logError("invalidAttributeChangeHandler", nil, attributeName)
34
+ end
35
+ local value = value :: (...unknown) -> (...unknown)
36
+ local event = applyTo:GetAttributeChangedSignal(attributeName)
37
+ table.insert(scope, event:Connect(function()
38
+ value((applyTo :: any):GetAttribute(attributeName))
39
+ end))
40
+ end
41
+ }
42
+ keyCache[attributeName] = key
43
+ end
44
+ return key
45
+ end
46
+
47
47
  return AttributeChange
@@ -1,63 +1,63 @@
1
- --!strict
2
- --!nolint LocalUnused
3
- --!nolint LocalShadow
4
- local task = nil -- Disable usage of Roblox's task scheduler
5
-
6
- --[[
7
- A special key for property tables, which allows users to save instance attributes
8
- into state objects
9
- ]]
10
-
11
- local Package = script.Parent.Parent
12
- local Types = require(Package.Types)
13
- local External = require(Package.External)
14
- -- Memory
15
- local checkLifetime = require(Package.Memory.checkLifetime)
16
- -- State
17
- local castToState = require(Package.State.castToState)
18
-
19
- local keyCache: {[string]: Types.SpecialKey} = {}
20
-
21
- local function AttributeOut(
22
- attributeName: string
23
- ): Types.SpecialKey
24
- local key = keyCache[attributeName]
25
- if key == nil then
26
- key = {
27
- type = "SpecialKey",
28
- kind = "AttributeOut",
29
- stage = "observer",
30
- apply = function(
31
- self: Types.SpecialKey,
32
- scope: Types.Scope<unknown>,
33
- value: unknown,
34
- applyTo: Instance
35
- )
36
- local event = applyTo:GetAttributeChangedSignal(attributeName)
37
-
38
- if not castToState(value) then
39
- External.logError("invalidAttributeOutType")
40
- end
41
- local value = value :: Types.StateObject<unknown>
42
- if value.kind ~= "Value" then
43
- External.logError("invalidAttributeOutType")
44
- end
45
- local value = value :: Types.Value<unknown>
46
- checkLifetime.bOutlivesA(
47
- scope, applyTo,
48
- value.scope, value.oldestTask,
49
- checkLifetime.formatters.attributeOutputsTo, attributeName
50
- )
51
-
52
- value:set((applyTo :: any):GetAttribute(attributeName))
53
- table.insert(scope, event:Connect(function()
54
- value:set((applyTo :: any):GetAttribute(attributeName))
55
- end))
56
- end
57
- }
58
- keyCache[attributeName] = key
59
- end
60
- return key
61
- end
62
-
63
- return AttributeOut
1
+ --!strict
2
+ --!nolint LocalUnused
3
+ --!nolint LocalShadow
4
+ local task = nil -- Disable usage of Roblox's task scheduler
5
+
6
+ --[[
7
+ A special key for property tables, which allows users to save instance attributes
8
+ into state objects
9
+ ]]
10
+
11
+ local Package = script.Parent.Parent
12
+ local Types = require(Package.Types)
13
+ local External = require(Package.External)
14
+ -- Memory
15
+ local checkLifetime = require(Package.Memory.checkLifetime)
16
+ -- State
17
+ local castToState = require(Package.State.castToState)
18
+
19
+ local keyCache: {[string]: Types.SpecialKey} = {}
20
+
21
+ local function AttributeOut(
22
+ attributeName: string
23
+ ): Types.SpecialKey
24
+ local key = keyCache[attributeName]
25
+ if key == nil then
26
+ key = {
27
+ type = "SpecialKey",
28
+ kind = "AttributeOut",
29
+ stage = "observer",
30
+ apply = function(
31
+ self: Types.SpecialKey,
32
+ scope: Types.Scope<unknown>,
33
+ value: unknown,
34
+ applyTo: Instance
35
+ )
36
+ local event = applyTo:GetAttributeChangedSignal(attributeName)
37
+
38
+ if not castToState(value) then
39
+ External.logError("invalidAttributeOutType")
40
+ end
41
+ local value = value :: Types.StateObject<unknown>
42
+ if value.kind ~= "Value" then
43
+ External.logError("invalidAttributeOutType")
44
+ end
45
+ local value = value :: Types.Value<unknown>
46
+ checkLifetime.bOutlivesA(
47
+ scope, applyTo,
48
+ value.scope, value.oldestTask,
49
+ checkLifetime.formatters.attributeOutputsTo, attributeName
50
+ )
51
+
52
+ value:set((applyTo :: any):GetAttribute(attributeName))
53
+ table.insert(scope, event:Connect(function()
54
+ value:set((applyTo :: any):GetAttribute(attributeName))
55
+ end))
56
+ end
57
+ }
58
+ keyCache[attributeName] = key
59
+ end
60
+ return key
61
+ end
62
+
63
+ return AttributeOut
@@ -1,21 +1,21 @@
1
- --!strict
2
- --!nolint LocalUnused
3
- --!nolint LocalShadow
4
- local task = nil -- Disable usage of Roblox's task scheduler
5
-
6
- --[[
7
- Helper function for type checking purposes. Casts the input to a `Child`
8
- type, while constraining the input to be an array of `Child` - this prevents
9
- Luau from erroneously inferring a different array type for the input.
10
- ]]
11
-
12
- local Package = script.Parent.Parent
13
- local Types = require(Package.Types)
14
-
15
- local function Child(
16
- x: {Types.Child}
17
- ): Types.Child
18
- return x
19
- end
20
-
21
- return Child
1
+ --!strict
2
+ --!nolint LocalUnused
3
+ --!nolint LocalShadow
4
+ local task = nil -- Disable usage of Roblox's task scheduler
5
+
6
+ --[[
7
+ Helper function for type checking purposes. Casts the input to a `Child`
8
+ type, while constraining the input to be an array of `Child` - this prevents
9
+ Luau from erroneously inferring a different array type for the input.
10
+ ]]
11
+
12
+ local Package = script.Parent.Parent
13
+ local Types = require(Package.Types)
14
+
15
+ local function Child(
16
+ x: {Types.Child}
17
+ ): Types.Child
18
+ return x
19
+ end
20
+
21
+ return Child
@@ -1,148 +1,148 @@
1
- --!strict
2
- --!nolint LocalUnused
3
- --!nolint LocalShadow
4
- local task = nil -- Disable usage of Roblox's task scheduler
5
-
6
- --[[
7
- A special key for property tables, which parents any given descendants into
8
- an instance.
9
- ]]
10
-
11
- local Package = script.Parent.Parent
12
- local Types = require(Package.Types)
13
- local External = require(Package.External)
14
- local Observer = require(Package.Graph.Observer)
15
- local peek = require(Package.State.peek)
16
- local castToState = require(Package.State.castToState)
17
- local doCleanup = require(Package.Memory.doCleanup)
18
-
19
- type Set<T> = {[T]: unknown}
20
-
21
- -- Experimental flag: name children based on the key used in the [Children] table
22
- local EXPERIMENTAL_AUTO_NAMING = false
23
-
24
- return {
25
- type = "SpecialKey",
26
- kind = "Children",
27
- stage = "descendants",
28
- apply = function(
29
- self: Types.SpecialKey,
30
- scope: Types.Scope<unknown>,
31
- value: unknown,
32
- applyTo: Instance
33
- )
34
- local newParented: Set<Instance> = {}
35
- local oldParented: Set<Instance> = {}
36
-
37
- -- save scopes for state object observers
38
- local newScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}
39
- local oldScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}
40
-
41
- -- Rescans this key's value to find new instances to parent and state objects
42
- -- to observe for changes; then unparents instances no longer found and
43
- -- disconnects observers for state objects no longer present.
44
- local function updateChildren()
45
- oldParented, newParented = newParented, oldParented
46
- oldScopes, newScopes = newScopes, oldScopes
47
-
48
- local function processChild(
49
- child: unknown,
50
- autoName: string?
51
- )
52
- local childType = typeof(child)
53
-
54
- if childType == "Instance" then
55
- -- case 1; single instance
56
- local child = child :: Instance
57
-
58
- newParented[child] = true
59
- if oldParented[child] == nil then
60
- -- wasn't previously present
61
-
62
- -- TODO: check for ancestry conflicts here
63
- child.Parent = applyTo
64
- else
65
- -- previously here; we want to reuse, so remove from old
66
- -- set so we don't encounter it during unparenting
67
- oldParented[child] = nil
68
- end
69
-
70
- if EXPERIMENTAL_AUTO_NAMING and autoName ~= nil then
71
- child.Name = autoName
72
- end
73
-
74
- elseif castToState(child) then
75
- -- case 2; state object
76
- local child = child :: Types.StateObject<unknown>
77
-
78
- local value = peek(child)
79
- -- allow nil to represent the absence of a child
80
- if value ~= nil then
81
- processChild(value, autoName)
82
- end
83
-
84
- local childScope = oldScopes[child]
85
- if childScope == nil then
86
- -- wasn't previously present
87
- childScope = {}
88
- Observer(childScope, child):onChange(updateChildren)
89
- else
90
- -- previously here; we want to reuse, so remove from old
91
- -- set so we don't encounter it during unparenting
92
- oldScopes[child] = nil
93
- end
94
-
95
- newScopes[child] = childScope
96
-
97
- elseif childType == "table" then
98
- -- case 3; table of objects
99
- local child = child :: {[unknown]: unknown}
100
-
101
- for key, subChild in pairs(child) do
102
- local keyType = typeof(key)
103
- local subAutoName: string? = nil
104
-
105
- if keyType == "string" then
106
- local key = key :: string
107
- subAutoName = key
108
- elseif keyType == "number" and autoName ~= nil then
109
- local key = key :: number
110
- subAutoName = autoName .. "_" .. key
111
- end
112
-
113
- processChild(subChild, subAutoName)
114
- end
115
-
116
- else
117
- External.logWarn("unrecognisedChildType", childType)
118
- end
119
- end
120
-
121
- if value ~= nil then
122
- -- `propValue` is set to nil on cleanup, so we don't process children
123
- -- in that case
124
- processChild(value)
125
- end
126
-
127
- -- unparent any children that are no longer present
128
- for oldInstance in pairs(oldParented) do
129
- oldInstance.Parent = nil
130
- end
131
- table.clear(oldParented)
132
-
133
- -- disconnect observers which weren't reused
134
- for oldState, childScope in pairs(oldScopes) do
135
- doCleanup(childScope)
136
- end
137
- table.clear(oldScopes)
138
- end
139
-
140
- table.insert(scope, function()
141
- value = nil
142
- updateChildren()
143
- end)
144
-
145
- -- perform initial child parenting
146
- updateChildren()
147
- end
1
+ --!strict
2
+ --!nolint LocalUnused
3
+ --!nolint LocalShadow
4
+ local task = nil -- Disable usage of Roblox's task scheduler
5
+
6
+ --[[
7
+ A special key for property tables, which parents any given descendants into
8
+ an instance.
9
+ ]]
10
+
11
+ local Package = script.Parent.Parent
12
+ local Types = require(Package.Types)
13
+ local External = require(Package.External)
14
+ local Observer = require(Package.Graph.Observer)
15
+ local peek = require(Package.State.peek)
16
+ local castToState = require(Package.State.castToState)
17
+ local doCleanup = require(Package.Memory.doCleanup)
18
+
19
+ type Set<T> = {[T]: unknown}
20
+
21
+ -- Experimental flag: name children based on the key used in the [Children] table
22
+ local EXPERIMENTAL_AUTO_NAMING = false
23
+
24
+ return {
25
+ type = "SpecialKey",
26
+ kind = "Children",
27
+ stage = "descendants",
28
+ apply = function(
29
+ self: Types.SpecialKey,
30
+ scope: Types.Scope<unknown>,
31
+ value: unknown,
32
+ applyTo: Instance
33
+ )
34
+ local newParented: Set<Instance> = {}
35
+ local oldParented: Set<Instance> = {}
36
+
37
+ -- save scopes for state object observers
38
+ local newScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}
39
+ local oldScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}
40
+
41
+ -- Rescans this key's value to find new instances to parent and state objects
42
+ -- to observe for changes; then unparents instances no longer found and
43
+ -- disconnects observers for state objects no longer present.
44
+ local function updateChildren()
45
+ oldParented, newParented = newParented, oldParented
46
+ oldScopes, newScopes = newScopes, oldScopes
47
+
48
+ local function processChild(
49
+ child: unknown,
50
+ autoName: string?
51
+ )
52
+ local childType = typeof(child)
53
+
54
+ if childType == "Instance" then
55
+ -- case 1; single instance
56
+ local child = child :: Instance
57
+
58
+ newParented[child] = true
59
+ if oldParented[child] == nil then
60
+ -- wasn't previously present
61
+
62
+ -- TODO: check for ancestry conflicts here
63
+ child.Parent = applyTo
64
+ else
65
+ -- previously here; we want to reuse, so remove from old
66
+ -- set so we don't encounter it during unparenting
67
+ oldParented[child] = nil
68
+ end
69
+
70
+ if EXPERIMENTAL_AUTO_NAMING and autoName ~= nil then
71
+ child.Name = autoName
72
+ end
73
+
74
+ elseif castToState(child) then
75
+ -- case 2; state object
76
+ local child = child :: Types.StateObject<unknown>
77
+
78
+ local value = peek(child)
79
+ -- allow nil to represent the absence of a child
80
+ if value ~= nil then
81
+ processChild(value, autoName)
82
+ end
83
+
84
+ local childScope = oldScopes[child]
85
+ if childScope == nil then
86
+ -- wasn't previously present
87
+ childScope = {}
88
+ Observer(childScope, child):onChange(updateChildren)
89
+ else
90
+ -- previously here; we want to reuse, so remove from old
91
+ -- set so we don't encounter it during unparenting
92
+ oldScopes[child] = nil
93
+ end
94
+
95
+ newScopes[child] = childScope
96
+
97
+ elseif childType == "table" then
98
+ -- case 3; table of objects
99
+ local child = child :: {[unknown]: unknown}
100
+
101
+ for key, subChild in pairs(child) do
102
+ local keyType = typeof(key)
103
+ local subAutoName: string? = nil
104
+
105
+ if keyType == "string" then
106
+ local key = key :: string
107
+ subAutoName = key
108
+ elseif keyType == "number" and autoName ~= nil then
109
+ local key = key :: number
110
+ subAutoName = autoName .. "_" .. key
111
+ end
112
+
113
+ processChild(subChild, subAutoName)
114
+ end
115
+
116
+ else
117
+ External.logWarn("unrecognisedChildType", childType)
118
+ end
119
+ end
120
+
121
+ if value ~= nil then
122
+ -- `propValue` is set to nil on cleanup, so we don't process children
123
+ -- in that case
124
+ processChild(value)
125
+ end
126
+
127
+ -- unparent any children that are no longer present
128
+ for oldInstance in pairs(oldParented) do
129
+ oldInstance.Parent = nil
130
+ end
131
+ table.clear(oldParented)
132
+
133
+ -- disconnect observers which weren't reused
134
+ for oldState, childScope in pairs(oldScopes) do
135
+ doCleanup(childScope)
136
+ end
137
+ table.clear(oldScopes)
138
+ end
139
+
140
+ table.insert(scope, function()
141
+ value = nil
142
+ updateChildren()
143
+ end)
144
+
145
+ -- perform initial child parenting
146
+ updateChildren()
147
+ end
148
148
  } :: Types.SpecialKey