@rbxts/app-forge 0.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.
- package/LICENSE.md +9 -0
- package/README.md +0 -0
- package/out/container.d.ts +5 -0
- package/out/container.luau +48 -0
- package/out/decorator.d.ts +9 -0
- package/out/decorator.luau +32 -0
- package/out/global.d.ts +9 -0
- package/out/helpers.d.ts +6 -0
- package/out/helpers.luau +18 -0
- package/out/index.d.ts +21 -0
- package/out/init.luau +138 -0
- package/out/rules.d.ts +11 -0
- package/out/rules.luau +195 -0
- package/out/types.d.ts +34 -0
- package/package.json +60 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Littensy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
-- Services
|
|
4
|
+
local RunService = TS.import(script, TS.getModule(script, "@rbxts", "services")).RunService
|
|
5
|
+
-- Packages
|
|
6
|
+
local _loners_pretty_react_hooks = TS.import(script, TS.getModule(script, "@rbxts", "loners-pretty-react-hooks").out)
|
|
7
|
+
local useBindingListener = _loners_pretty_react_hooks.useBindingListener
|
|
8
|
+
local useSpring = _loners_pretty_react_hooks.useSpring
|
|
9
|
+
local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
10
|
+
local React = _react
|
|
11
|
+
local useState = _react.useState
|
|
12
|
+
-- Types
|
|
13
|
+
local function AppContainer(props)
|
|
14
|
+
local _binding = props
|
|
15
|
+
local name = _binding.name
|
|
16
|
+
local manager = _binding.manager
|
|
17
|
+
local binding, _ = manager:createBinding(name)
|
|
18
|
+
local spring = useSpring(binding:map(function(v)
|
|
19
|
+
return if v then 0 else 1
|
|
20
|
+
end), {
|
|
21
|
+
frequency = 0.4,
|
|
22
|
+
damping = 0.8,
|
|
23
|
+
})
|
|
24
|
+
local _isVisible, setisVisible = useState(binding:getValue())
|
|
25
|
+
local element = manager:createInstance(props, name)
|
|
26
|
+
if not element then
|
|
27
|
+
error(`Failed to create instance for app "{name}"`)
|
|
28
|
+
end
|
|
29
|
+
useBindingListener(spring, function(v)
|
|
30
|
+
setisVisible(v == 0)
|
|
31
|
+
end)
|
|
32
|
+
if RunService:IsRunning() then
|
|
33
|
+
return React.createElement("screengui", {
|
|
34
|
+
key = name,
|
|
35
|
+
ZIndexBehavior = "Sibling",
|
|
36
|
+
ResetOnSpawn = false,
|
|
37
|
+
}, element)
|
|
38
|
+
else
|
|
39
|
+
return React.createElement("frame", {
|
|
40
|
+
key = name,
|
|
41
|
+
BackgroundTransparency = 1,
|
|
42
|
+
Size = UDim2.fromScale(1, 1),
|
|
43
|
+
}, element)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
return {
|
|
47
|
+
AppContainer = AppContainer,
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "@rbxts/react";
|
|
2
|
+
import type Types from "./types";
|
|
3
|
+
export declare const AppRegistry: Map<string, Types.AppRegistry>;
|
|
4
|
+
export declare function App(props: Types.AppRegistryProps): <T extends new (props: AppProps) => Args>(constructor: T) => T;
|
|
5
|
+
export declare abstract class Args {
|
|
6
|
+
readonly props: AppProps;
|
|
7
|
+
constructor(props: AppProps);
|
|
8
|
+
abstract render(): React.Element;
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
-- Packages
|
|
3
|
+
-- Types
|
|
4
|
+
local AppRegistry = {}
|
|
5
|
+
local function App(props)
|
|
6
|
+
return function(constructor)
|
|
7
|
+
local _name = props.name
|
|
8
|
+
if AppRegistry[_name] ~= nil then
|
|
9
|
+
error(`Duplicate registered App name "{props.name}"`)
|
|
10
|
+
end
|
|
11
|
+
local _name_1 = props.name
|
|
12
|
+
local _arg1 = {
|
|
13
|
+
constructor = constructor,
|
|
14
|
+
visible = props.visible,
|
|
15
|
+
rules = props.rules,
|
|
16
|
+
}
|
|
17
|
+
AppRegistry[_name_1] = _arg1
|
|
18
|
+
return constructor
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
local Args
|
|
22
|
+
do
|
|
23
|
+
Args = {}
|
|
24
|
+
function Args:constructor(props)
|
|
25
|
+
self.props = props
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
return {
|
|
29
|
+
App = App,
|
|
30
|
+
AppRegistry = AppRegistry,
|
|
31
|
+
Args = Args,
|
|
32
|
+
}
|
package/out/global.d.ts
ADDED
package/out/helpers.d.ts
ADDED
package/out/helpers.luau
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
-- Types
|
|
3
|
+
local function Render(_param)
|
|
4
|
+
local props = _param.props
|
|
5
|
+
local manager = _param.manager
|
|
6
|
+
local names = _param.names
|
|
7
|
+
if names ~= "" and names then
|
|
8
|
+
if type(names) == "table" then
|
|
9
|
+
return manager:renderApps(props, names)
|
|
10
|
+
else
|
|
11
|
+
return manager:renderApp(props, names)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
return manager:renderAll(props)
|
|
15
|
+
end
|
|
16
|
+
return {
|
|
17
|
+
Render = Render,
|
|
18
|
+
}
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "@rbxts/react";
|
|
2
|
+
import { Args, App } from "./decorator";
|
|
3
|
+
export default class AppManager {
|
|
4
|
+
private binds;
|
|
5
|
+
private loaded;
|
|
6
|
+
private rulesManager;
|
|
7
|
+
private getAllNames;
|
|
8
|
+
createBinding(name: AppNames[number]): LuaTuple<[React.Binding<boolean>, (newValue: boolean) => void]>;
|
|
9
|
+
createInstance(props: AppProps, name: AppNames[number]): React.Element<any, string | React.JSXElementConstructor<any>>;
|
|
10
|
+
getBind(name: AppNames[number]): React.Binding<boolean>;
|
|
11
|
+
getState(name: AppNames[number]): boolean;
|
|
12
|
+
set(name: AppNames[number], value: boolean): void;
|
|
13
|
+
open(name: AppNames[number]): void;
|
|
14
|
+
close(name: AppNames[number]): void;
|
|
15
|
+
toggle(name: AppNames[number]): void;
|
|
16
|
+
renderApp(props: AppProps, name: AppNames[number]): JSX.Element;
|
|
17
|
+
renderApps(props: AppProps, names: AppNames[number][]): JSX.Element[];
|
|
18
|
+
renderAll(props: AppProps): JSX.Element[];
|
|
19
|
+
}
|
|
20
|
+
export { App, Args };
|
|
21
|
+
export { Render } from "./helpers";
|
package/out/init.luau
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
-- Packages
|
|
5
|
+
local _react = TS.import(script, TS.getModule(script, "@rbxts", "react"))
|
|
6
|
+
local React = _react
|
|
7
|
+
local cloneElement = _react.cloneElement
|
|
8
|
+
local useBinding = _react.useBinding
|
|
9
|
+
local Object = TS.import(script, TS.getModule(script, "@rbxts", "object-utils"))
|
|
10
|
+
-- Components
|
|
11
|
+
local _decorator = TS.import(script, script, "decorator")
|
|
12
|
+
local AppRegistry = _decorator.AppRegistry
|
|
13
|
+
local Args = _decorator.Args
|
|
14
|
+
local App = _decorator.App
|
|
15
|
+
local AppContainer = TS.import(script, script, "container").AppContainer
|
|
16
|
+
local RulesManager = TS.import(script, script, "rules").default
|
|
17
|
+
local AppManager
|
|
18
|
+
do
|
|
19
|
+
AppManager = setmetatable({}, {
|
|
20
|
+
__tostring = function()
|
|
21
|
+
return "AppManager"
|
|
22
|
+
end,
|
|
23
|
+
})
|
|
24
|
+
AppManager.__index = AppManager
|
|
25
|
+
function AppManager.new(...)
|
|
26
|
+
local self = setmetatable({}, AppManager)
|
|
27
|
+
return self:constructor(...) or self
|
|
28
|
+
end
|
|
29
|
+
function AppManager:constructor()
|
|
30
|
+
self.binds = {}
|
|
31
|
+
self.loaded = {}
|
|
32
|
+
self.rulesManager = RulesManager.new(self)
|
|
33
|
+
end
|
|
34
|
+
function AppManager:getAllNames()
|
|
35
|
+
return Object.keys(AppRegistry)
|
|
36
|
+
end
|
|
37
|
+
function AppManager:createBinding(name)
|
|
38
|
+
local _name = name
|
|
39
|
+
local app = AppRegistry[_name]
|
|
40
|
+
if not app then
|
|
41
|
+
error(`App "{name}" not registered`)
|
|
42
|
+
end
|
|
43
|
+
local _condition = app.visible
|
|
44
|
+
if _condition == nil then
|
|
45
|
+
_condition = false
|
|
46
|
+
end
|
|
47
|
+
local binding = { useBinding(_condition) }
|
|
48
|
+
local _binds = self.binds
|
|
49
|
+
local _name_1 = name
|
|
50
|
+
_binds[_name_1] = binding
|
|
51
|
+
return unpack(binding)
|
|
52
|
+
end
|
|
53
|
+
function AppManager:createInstance(props, name)
|
|
54
|
+
local _name = name
|
|
55
|
+
local appClass = AppRegistry[_name]
|
|
56
|
+
if not appClass then
|
|
57
|
+
error(`App "{name}" not registered`)
|
|
58
|
+
end
|
|
59
|
+
local _loaded = self.loaded
|
|
60
|
+
local _name_1 = name
|
|
61
|
+
if not (_loaded[_name_1] ~= nil) then
|
|
62
|
+
local instance = appClass.constructor.new(props)
|
|
63
|
+
local element = cloneElement(instance:render(), {
|
|
64
|
+
key = "Main",
|
|
65
|
+
})
|
|
66
|
+
local _loaded_1 = self.loaded
|
|
67
|
+
local _name_2 = name
|
|
68
|
+
_loaded_1[_name_2] = element
|
|
69
|
+
end
|
|
70
|
+
local _loaded_1 = self.loaded
|
|
71
|
+
local _name_2 = name
|
|
72
|
+
return _loaded_1[_name_2]
|
|
73
|
+
end
|
|
74
|
+
function AppManager:getBind(name)
|
|
75
|
+
local _binds = self.binds
|
|
76
|
+
local _name = name
|
|
77
|
+
if not (_binds[_name] ~= nil) then
|
|
78
|
+
error(`App "{name}" has no binding`)
|
|
79
|
+
end
|
|
80
|
+
local _binds_1 = self.binds
|
|
81
|
+
local _name_1 = name
|
|
82
|
+
return _binds_1[_name_1][1]
|
|
83
|
+
end
|
|
84
|
+
function AppManager:getState(name)
|
|
85
|
+
return self:getBind(name):getValue()
|
|
86
|
+
end
|
|
87
|
+
function AppManager:set(name, value)
|
|
88
|
+
if not self.rulesManager:applyRules(name, value) then
|
|
89
|
+
return nil
|
|
90
|
+
end
|
|
91
|
+
local _binds = self.binds
|
|
92
|
+
local _name = name
|
|
93
|
+
local _binding = _binds[_name]
|
|
94
|
+
local _ = _binding[1]
|
|
95
|
+
local setBinding = _binding[2]
|
|
96
|
+
setBinding(value)
|
|
97
|
+
end
|
|
98
|
+
function AppManager:open(name)
|
|
99
|
+
self:set(name, true)
|
|
100
|
+
end
|
|
101
|
+
function AppManager:close(name)
|
|
102
|
+
self:set(name, false)
|
|
103
|
+
end
|
|
104
|
+
function AppManager:toggle(name)
|
|
105
|
+
self:set(name, not self:getState(name))
|
|
106
|
+
end
|
|
107
|
+
function AppManager:renderApp(props, name)
|
|
108
|
+
local _attributes = {
|
|
109
|
+
key = `{name}_Container`,
|
|
110
|
+
name = name,
|
|
111
|
+
manager = self,
|
|
112
|
+
}
|
|
113
|
+
for _k, _v in props do
|
|
114
|
+
_attributes[_k] = _v
|
|
115
|
+
end
|
|
116
|
+
return React.createElement(AppContainer, _attributes)
|
|
117
|
+
end
|
|
118
|
+
function AppManager:renderApps(props, names)
|
|
119
|
+
-- ▼ ReadonlyArray.map ▼
|
|
120
|
+
local _newValue = table.create(#names)
|
|
121
|
+
local _callback = function(n)
|
|
122
|
+
return self:renderApp(props, n)
|
|
123
|
+
end
|
|
124
|
+
for _k, _v in names do
|
|
125
|
+
_newValue[_k] = _callback(_v, _k - 1, names)
|
|
126
|
+
end
|
|
127
|
+
-- ▲ ReadonlyArray.map ▲
|
|
128
|
+
return _newValue
|
|
129
|
+
end
|
|
130
|
+
function AppManager:renderAll(props)
|
|
131
|
+
return self:renderApps(props, self:getAllNames())
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
exports.Render = TS.import(script, script, "helpers").Render
|
|
135
|
+
exports.default = AppManager
|
|
136
|
+
exports.App = App
|
|
137
|
+
exports.Args = Args
|
|
138
|
+
return exports
|
package/out/rules.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import AppManager from ".";
|
|
2
|
+
export default class RulesManager {
|
|
3
|
+
private appManager;
|
|
4
|
+
constructor(appManager: AppManager);
|
|
5
|
+
applyRules(name: AppNames[number], value: boolean): boolean;
|
|
6
|
+
private inSameGroup;
|
|
7
|
+
private blockedBy;
|
|
8
|
+
private blocks;
|
|
9
|
+
private exclusive;
|
|
10
|
+
private layer;
|
|
11
|
+
}
|
package/out/rules.luau
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
-- Packages
|
|
4
|
+
local Object = TS.import(script, TS.getModule(script, "@rbxts", "object-utils"))
|
|
5
|
+
-- Components
|
|
6
|
+
local AppRegistry = TS.import(script, script.Parent, "decorator").AppRegistry
|
|
7
|
+
-- Types
|
|
8
|
+
local function asTable(value)
|
|
9
|
+
local _value = value
|
|
10
|
+
if type(_value) == "table" then
|
|
11
|
+
return value
|
|
12
|
+
else
|
|
13
|
+
local t = {}
|
|
14
|
+
t[2] = value
|
|
15
|
+
return t
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
local RulesManager
|
|
19
|
+
do
|
|
20
|
+
RulesManager = setmetatable({}, {
|
|
21
|
+
__tostring = function()
|
|
22
|
+
return "RulesManager"
|
|
23
|
+
end,
|
|
24
|
+
})
|
|
25
|
+
RulesManager.__index = RulesManager
|
|
26
|
+
function RulesManager.new(...)
|
|
27
|
+
local self = setmetatable({}, RulesManager)
|
|
28
|
+
return self:constructor(...) or self
|
|
29
|
+
end
|
|
30
|
+
function RulesManager:constructor(appManager)
|
|
31
|
+
self.appManager = appManager
|
|
32
|
+
end
|
|
33
|
+
function RulesManager:applyRules(name, value)
|
|
34
|
+
local _name = name
|
|
35
|
+
local appData = AppRegistry[_name]
|
|
36
|
+
local _rules = appData
|
|
37
|
+
if _rules ~= nil then
|
|
38
|
+
_rules = _rules.rules
|
|
39
|
+
end
|
|
40
|
+
local rules = _rules
|
|
41
|
+
local _result = rules
|
|
42
|
+
if _result ~= nil then
|
|
43
|
+
_result = _result.groups
|
|
44
|
+
end
|
|
45
|
+
if _result == "Core" then
|
|
46
|
+
return true
|
|
47
|
+
end
|
|
48
|
+
if value then
|
|
49
|
+
local allNames = Object.keys(AppRegistry)
|
|
50
|
+
-- ▼ ReadonlyArray.forEach ▼
|
|
51
|
+
local _callback = function(n)
|
|
52
|
+
if not (n ~= "" and n) or n == name then
|
|
53
|
+
return nil
|
|
54
|
+
end
|
|
55
|
+
local _n = n
|
|
56
|
+
local otherApp = AppRegistry[_n]
|
|
57
|
+
local _result_1 = otherApp
|
|
58
|
+
if _result_1 ~= nil then
|
|
59
|
+
_result_1 = _result_1.rules
|
|
60
|
+
if _result_1 ~= nil then
|
|
61
|
+
_result_1 = _result_1.groups
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
local groups = if _result_1 ~= "" and _result_1 then asTable(otherApp.rules.groups) else {}
|
|
65
|
+
-- ▼ ReadonlyArray.find ▼
|
|
66
|
+
local _callback_1 = function(g)
|
|
67
|
+
return g == "Core"
|
|
68
|
+
end
|
|
69
|
+
local _result_2
|
|
70
|
+
for _i, _v in groups do
|
|
71
|
+
if _callback_1(_v, _i - 1, groups) == true then
|
|
72
|
+
_result_2 = _v
|
|
73
|
+
break
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
-- ▲ ReadonlyArray.find ▲
|
|
77
|
+
if _result_2 then
|
|
78
|
+
return nil
|
|
79
|
+
end
|
|
80
|
+
if self.appManager:getState(n) then
|
|
81
|
+
self.appManager:set(n, false)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
for _k, _v in allNames do
|
|
85
|
+
_callback(_v, _k - 1, allNames)
|
|
86
|
+
end
|
|
87
|
+
-- ▲ ReadonlyArray.forEach ▲
|
|
88
|
+
end
|
|
89
|
+
if not rules then
|
|
90
|
+
return true
|
|
91
|
+
end
|
|
92
|
+
local _condition = value
|
|
93
|
+
if _condition then
|
|
94
|
+
_condition = rules.blockedBy
|
|
95
|
+
if _condition ~= "" and _condition then
|
|
96
|
+
_condition = not self:blockedBy(name, rules.blockedBy)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
if _condition ~= "" and _condition then
|
|
100
|
+
return false
|
|
101
|
+
end
|
|
102
|
+
local _value = value and rules.blocks
|
|
103
|
+
if _value ~= "" and _value then
|
|
104
|
+
self:blocks(name, rules.blocks)
|
|
105
|
+
end
|
|
106
|
+
if value and rules.layer ~= nil then
|
|
107
|
+
self:layer(name, rules.layer)
|
|
108
|
+
end
|
|
109
|
+
if value and rules.exclusive then
|
|
110
|
+
self:exclusive(name)
|
|
111
|
+
end
|
|
112
|
+
return true
|
|
113
|
+
end
|
|
114
|
+
function RulesManager:inSameGroup(a, b)
|
|
115
|
+
local _a = a
|
|
116
|
+
local appA = AppRegistry[_a]
|
|
117
|
+
local _b = b
|
|
118
|
+
local appB = AppRegistry[_b]
|
|
119
|
+
if not appA or not appB then
|
|
120
|
+
return false
|
|
121
|
+
end
|
|
122
|
+
local _result = appA.rules
|
|
123
|
+
if _result ~= nil then
|
|
124
|
+
_result = _result.groups
|
|
125
|
+
end
|
|
126
|
+
local _condition = _result
|
|
127
|
+
if _condition == nil then
|
|
128
|
+
_condition = {}
|
|
129
|
+
end
|
|
130
|
+
local groupsA = asTable(_condition)
|
|
131
|
+
local _result_1 = appB.rules
|
|
132
|
+
if _result_1 ~= nil then
|
|
133
|
+
_result_1 = _result_1.groups
|
|
134
|
+
end
|
|
135
|
+
local _condition_1 = _result_1
|
|
136
|
+
if _condition_1 == nil then
|
|
137
|
+
_condition_1 = {}
|
|
138
|
+
end
|
|
139
|
+
local groupsB = asTable(_condition_1)
|
|
140
|
+
for i = 1, #groupsA do
|
|
141
|
+
for j = 1, #groupsB do
|
|
142
|
+
if groupsA[i + 1] == groupsB[j + 1] then
|
|
143
|
+
return true
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
return false
|
|
148
|
+
end
|
|
149
|
+
function RulesManager:blockedBy(name, rule)
|
|
150
|
+
local blockers = asTable(rule)
|
|
151
|
+
for i = 1, #blockers do
|
|
152
|
+
local blocker = blockers[i + 1]
|
|
153
|
+
if self:inSameGroup(name, blocker) or not (blocker ~= "" and blocker) then
|
|
154
|
+
continue
|
|
155
|
+
end
|
|
156
|
+
if self.appManager:getState(blocker) then
|
|
157
|
+
return false
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
return true
|
|
161
|
+
end
|
|
162
|
+
function RulesManager:blocks(name, rule)
|
|
163
|
+
local blocked = asTable(rule)
|
|
164
|
+
for i = 1, #blocked do
|
|
165
|
+
local b = blocked[i + 1]
|
|
166
|
+
if self:inSameGroup(name, b) or not (b ~= "" and b) then
|
|
167
|
+
continue
|
|
168
|
+
end
|
|
169
|
+
if self.appManager:getState(b) then
|
|
170
|
+
self.appManager:set(b, false)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
function RulesManager:exclusive(name)
|
|
175
|
+
local names = Object.keys(AppRegistry)
|
|
176
|
+
for i = 1, #names do
|
|
177
|
+
local other = names[i + 1]
|
|
178
|
+
if other == name or not (other ~= "" and other) then
|
|
179
|
+
continue
|
|
180
|
+
end
|
|
181
|
+
if self:inSameGroup(name, other) then
|
|
182
|
+
continue
|
|
183
|
+
end
|
|
184
|
+
if self.appManager:getState(other) then
|
|
185
|
+
self.appManager:set(other, false)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
function RulesManager:layer(_name, _layer)
|
|
190
|
+
-- TODO: implement priority / layering
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
return {
|
|
194
|
+
default = RulesManager,
|
|
195
|
+
}
|
package/out/types.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
import type { Args } from "./decorator";
|
|
3
|
+
|
|
4
|
+
declare namespace Types {
|
|
5
|
+
type AppRegistryProps = {
|
|
6
|
+
name: AppNames[number];
|
|
7
|
+
visible?: boolean;
|
|
8
|
+
rules?: Rules.All;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type AppRegistry = {
|
|
12
|
+
constructor: new (props: AppProps) => Args;
|
|
13
|
+
visible?: boolean;
|
|
14
|
+
rules?: Rules.All;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
namespace Rules {
|
|
18
|
+
type Groups = AppGroups[number] | "Core" | "Core"[] | AppGroups[number][];
|
|
19
|
+
type BlockedBy = AppNames[number] | AppNames[number][];
|
|
20
|
+
type Blocks = AppNames[number] | AppNames[number][];
|
|
21
|
+
type Exclusive = boolean;
|
|
22
|
+
type Layer = number;
|
|
23
|
+
|
|
24
|
+
type All = {
|
|
25
|
+
blockedBy?: BlockedBy;
|
|
26
|
+
exclusive?: Exclusive;
|
|
27
|
+
groups?: Groups;
|
|
28
|
+
blocks?: Blocks;
|
|
29
|
+
layer?: Layer;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default Types;
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rbxts/app-forge",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "An App Manager for react",
|
|
5
|
+
"main": "out/init.lua",
|
|
6
|
+
"packageManager": "bun@1.3.1",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rbxtsc",
|
|
9
|
+
"dev": "rbxtsc -w --type game --rojo test.project.json",
|
|
10
|
+
"login": "bunx npm login --auth-type=legacy"
|
|
11
|
+
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"roact",
|
|
15
|
+
"react",
|
|
16
|
+
"roblox-ts"
|
|
17
|
+
],
|
|
18
|
+
"author": "Add your name here",
|
|
19
|
+
"license": "Add your license here etc. MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "Add your repository url here"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "add your issues url here"
|
|
26
|
+
},
|
|
27
|
+
"types": "out/index.d.ts",
|
|
28
|
+
"files": [
|
|
29
|
+
"out",
|
|
30
|
+
"!**/*.tsbuildinfo",
|
|
31
|
+
"!**/*.spec.lua",
|
|
32
|
+
"!**/*.spec.d.ts"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@rbxts/compiler-types": "3.0.0-types.0",
|
|
39
|
+
"@rbxts/react": "17.3.0-alpha.1",
|
|
40
|
+
"@rbxts/react-roblox": "17.3.0-alpha.1",
|
|
41
|
+
"@rbxts/types": "^1.0.891",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
43
|
+
"@typescript-eslint/parser": "^8.46.4",
|
|
44
|
+
"roblox-ts": "3.0.0",
|
|
45
|
+
"typescript": "^5.9.3"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@rbxts/charm": "^0.10.0",
|
|
49
|
+
"@rbxts/loners-pretty-react-hooks": "^0.0.3",
|
|
50
|
+
"@rbxts/react-charm": "^0.3.0",
|
|
51
|
+
"@rbxts/ripple": "^0.9.3",
|
|
52
|
+
"@rbxts/services": "^1.6.0",
|
|
53
|
+
"@rbxts/set-timeout": "^1.1.2"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@rbxts/object-utils": "*",
|
|
57
|
+
"@rbxts/react-roblox": "*",
|
|
58
|
+
"@rbxts/react": "*"
|
|
59
|
+
}
|
|
60
|
+
}
|