@quenty/loader 8.0.0-canary.ee17b33.0 → 8.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/CHANGELOG.md +53 -1
- package/README.md +0 -2
- package/default.project.json +1 -1
- package/package.json +2 -2
- package/src/LoaderConstants.lua +1 -1
- package/src/LoaderUtils.lua +4 -10
- package/src/init.lua +1 -1
- package/src2/Dependencies/DependencyUtils.lua +26 -12
- package/src2/Dependencies/PackageTracker.lua +441 -0
- package/src2/Dependencies/PackageTrackerProvider.lua +66 -0
- package/src2/LoaderLink/LoaderLink.lua +25 -0
- package/src2/LoaderLink/LoaderLinkCreator.lua +175 -0
- package/src2/LoaderLink/LoaderLinkUtils.lua +27 -0
- package/src2/LoaderUtils.lua +3 -0
- package/src2/Maid.lua +1 -1
- package/src2/Replication/ReplicationType.lua +1 -0
- package/src2/Replication/ReplicationTypeUtils.lua +41 -0
- package/src2/Replication/Replicator.lua +19 -23
- package/src2/Replication/ReplicatorUtils.lua +1 -0
- package/src2/Utils.lua +1 -1
- package/src2/init.lua +146 -43
- package/src2/Bounce/BounceTemplate.lua +0 -17
- package/src2/Bounce/BounceTemplateUtils.lua +0 -51
- package/src2/Loader/LoaderAdder.lua +0 -181
- package/src2/PathUtils.lua +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,59 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
# [8.0.0
|
|
6
|
+
# [8.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@7.3.0...@quenty/loader@8.0.0) (2024-02-13)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* New loader (breaking changes), fixing loader issues ([#439](https://github.com/Quenty/NevermoreEngine/issues/439)) ([3534345](https://github.com/Quenty/NevermoreEngine/commit/353434522918812953bd9f13fece73e27a4d034d))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### BREAKING CHANGES
|
|
15
|
+
|
|
16
|
+
* Standard loader
|
|
17
|
+
|
|
18
|
+
Adds new loader version which replicates full structure instead of some partial structure. This allows us to have hot-reloading (in the future), as well as generally do less computation, handle dependencies more carefully, and other changes.
|
|
19
|
+
|
|
20
|
+
This means you'll need to change you how require client-side modules, as we export a simple `loader` module instead of all modules available.
|
|
21
|
+
|
|
22
|
+
Signed-off-by: James Onnen <jonnen0@gmail.com>
|
|
23
|
+
|
|
24
|
+
* fix: Fix missing dependency in ResetService
|
|
25
|
+
|
|
26
|
+
* feat: Add RxPhysicsUtils.observePartMass
|
|
27
|
+
|
|
28
|
+
* fix: Fix package discovery for games
|
|
29
|
+
|
|
30
|
+
* feat: Add UIAlignmentUtils.verticalToHorizontalAlignment(verticalAlignment) and UIAlignmentUtils.horizontalToVerticalAlignment(horizontalAlignment)
|
|
31
|
+
|
|
32
|
+
* feat: AdorneeData:InitAttributes() does not require data as a secondparameter
|
|
33
|
+
|
|
34
|
+
* ci: Upgrade to new rojo 7.4.0
|
|
35
|
+
|
|
36
|
+
* fix: Update loader to handle hoarcekat properly
|
|
37
|
+
|
|
38
|
+
* docs: Fix spacing in Maid
|
|
39
|
+
|
|
40
|
+
* fix: Add new ragdoll constants
|
|
41
|
+
|
|
42
|
+
* fix: Compress influxDB sends
|
|
43
|
+
|
|
44
|
+
* style: Errors use string.format
|
|
45
|
+
|
|
46
|
+
* fix: Handle motor animations
|
|
47
|
+
|
|
48
|
+
* ci: Upgrade rojo version
|
|
49
|
+
|
|
50
|
+
* feat!: Maid no longer is includd in ValueObject.Changed event
|
|
51
|
+
|
|
52
|
+
* docs: Fix docs
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# [7.3.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@7.1.0...@quenty/loader@7.3.0) (2024-01-08)
|
|
7
59
|
|
|
8
60
|
|
|
9
61
|
### Features
|
package/README.md
CHANGED
|
@@ -56,8 +56,6 @@ For a given package folder, all packages underneath it shall have...
|
|
|
56
56
|
3. Access to every package in the dependency folder at each ancestor level at the 1st level of recursion
|
|
57
57
|
4. Access to every sibling package (this is because we expect to be installed at a uniform level)
|
|
58
58
|
|
|
59
|
-
We will
|
|
60
|
-
|
|
61
59
|
|
|
62
60
|
|
|
63
61
|
-------
|
package/default.project.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/loader",
|
|
3
|
-
"version": "8.0.0
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "A simple module loader for Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "5736b108e4d23cd4c9e761bbe4cc9fed6fb32dfa"
|
|
30
30
|
}
|
package/src/LoaderConstants.lua
CHANGED
package/src/LoaderUtils.lua
CHANGED
|
@@ -45,9 +45,7 @@ function LoaderUtils.toWallyFormat(instance, isPlugin)
|
|
|
45
45
|
PackageInfoUtils.fillDependencySet(packageInfoList)
|
|
46
46
|
|
|
47
47
|
if isPlugin then
|
|
48
|
-
local pluginGroup = GroupInfoUtils.groupPackageInfos(packageInfoList,
|
|
49
|
-
ScriptInfoUtils.ModuleReplicationTypes.PLUGIN)
|
|
50
|
-
|
|
48
|
+
local pluginGroup = GroupInfoUtils.groupPackageInfos(packageInfoList, ScriptInfoUtils.ModuleReplicationTypes.PLUGIN)
|
|
51
49
|
local publishSet = LoaderUtils.getPublishPackageInfoSet(packageInfoList)
|
|
52
50
|
|
|
53
51
|
local pluginFolder = Instance.new("Folder")
|
|
@@ -57,13 +55,9 @@ function LoaderUtils.toWallyFormat(instance, isPlugin)
|
|
|
57
55
|
|
|
58
56
|
return pluginFolder
|
|
59
57
|
else
|
|
60
|
-
local clientGroupList = GroupInfoUtils.groupPackageInfos(packageInfoList,
|
|
61
|
-
|
|
62
|
-
local
|
|
63
|
-
ScriptInfoUtils.ModuleReplicationTypes.SERVER)
|
|
64
|
-
local sharedGroupList = GroupInfoUtils.groupPackageInfos(packageInfoList,
|
|
65
|
-
ScriptInfoUtils.ModuleReplicationTypes.SHARED)
|
|
66
|
-
|
|
58
|
+
local clientGroupList = GroupInfoUtils.groupPackageInfos(packageInfoList, ScriptInfoUtils.ModuleReplicationTypes.CLIENT)
|
|
59
|
+
local serverGroupList = GroupInfoUtils.groupPackageInfos(packageInfoList, ScriptInfoUtils.ModuleReplicationTypes.SERVER)
|
|
60
|
+
local sharedGroupList = GroupInfoUtils.groupPackageInfos(packageInfoList, ScriptInfoUtils.ModuleReplicationTypes.SHARED)
|
|
67
61
|
local publishSet = LoaderUtils.getPublishPackageInfoSet(packageInfoList)
|
|
68
62
|
|
|
69
63
|
local clientFolder = Instance.new("Folder")
|
package/src/init.lua
CHANGED
|
@@ -96,7 +96,7 @@ local function bootstrapPlugin(packageFolder)
|
|
|
96
96
|
return require(pluginFolder:FindFirstChild(value))
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
error(("Unknown module %q"
|
|
99
|
+
error(string.format("Unknown module %q", tostring(value)))
|
|
100
100
|
else
|
|
101
101
|
return require(value)
|
|
102
102
|
end
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
@class DependencyUtils
|
|
6
6
|
]=]
|
|
7
7
|
|
|
8
|
+
local loader = script.Parent.Parent
|
|
9
|
+
local ReplicationType = require(loader.Replication.ReplicationType)
|
|
10
|
+
local ReplicationTypeUtils = require(loader.Replication.ReplicationTypeUtils)
|
|
11
|
+
|
|
8
12
|
local DependencyUtils = {}
|
|
9
13
|
|
|
10
14
|
--[=[
|
|
@@ -13,16 +17,22 @@ local DependencyUtils = {}
|
|
|
13
17
|
|
|
14
18
|
@param requester Instance
|
|
15
19
|
@param moduleName string
|
|
20
|
+
@param requestedReplicationType ReplicationType
|
|
16
21
|
@return ModuleScript?
|
|
17
22
|
]=]
|
|
18
|
-
function DependencyUtils.findDependency(requester, moduleName)
|
|
23
|
+
function DependencyUtils.findDependency(requester, moduleName, requestedReplicationType)
|
|
19
24
|
assert(typeof(requester) == "Instance", "Bad requester")
|
|
20
25
|
assert(type(moduleName) == "string", "Bad moduleName")
|
|
26
|
+
assert(ReplicationTypeUtils.isReplicationType(requestedReplicationType), "Bad requestedReplicationType")
|
|
21
27
|
|
|
22
28
|
for packageInst in DependencyUtils.iterPackages(requester) do
|
|
23
|
-
for module in DependencyUtils.iterModules(packageInst) do
|
|
29
|
+
for module, replicationType in DependencyUtils.iterModules(packageInst, ReplicationType.SHARED) do
|
|
24
30
|
if module.Name == moduleName then
|
|
25
|
-
|
|
31
|
+
if ReplicationTypeUtils.isAllowed(replicationType, requestedReplicationType) then
|
|
32
|
+
return module
|
|
33
|
+
else
|
|
34
|
+
error(string.format("[DependencyUtils] - %q is not allowed in %q", moduleName, requestedReplicationType))
|
|
35
|
+
end
|
|
26
36
|
end
|
|
27
37
|
end
|
|
28
38
|
end
|
|
@@ -30,20 +40,24 @@ function DependencyUtils.findDependency(requester, moduleName)
|
|
|
30
40
|
return nil
|
|
31
41
|
end
|
|
32
42
|
|
|
33
|
-
function DependencyUtils.iterModules(packageInst)
|
|
43
|
+
function DependencyUtils.iterModules(packageInst, ancestorReplicationType)
|
|
34
44
|
assert(typeof(packageInst) == "Instance", "Bad packageInst")
|
|
45
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
35
46
|
|
|
36
47
|
return coroutine.wrap(function()
|
|
37
48
|
if packageInst:IsA("ModuleScript") then
|
|
38
|
-
coroutine.yield(packageInst)
|
|
49
|
+
coroutine.yield(packageInst, ancestorReplicationType)
|
|
39
50
|
return
|
|
40
51
|
end
|
|
41
52
|
|
|
42
53
|
-- Iterate over the package contents
|
|
43
54
|
for _, item in pairs(packageInst:GetChildren()) do
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
local itemName = item.Name
|
|
56
|
+
local itemReplicationType = ReplicationTypeUtils.getFolderReplicationType(itemName, ancestorReplicationType)
|
|
57
|
+
|
|
58
|
+
if itemName ~= "node_modules" then
|
|
59
|
+
for result, resultReplicationType in DependencyUtils.iterModules(item, itemReplicationType) do
|
|
60
|
+
coroutine.yield(result, resultReplicationType)
|
|
47
61
|
end
|
|
48
62
|
end
|
|
49
63
|
end
|
|
@@ -98,10 +112,10 @@ function DependencyUtils.iterPackagesInModuleModules(nodeModules)
|
|
|
98
112
|
if linked:IsA("ModuleScript") or linked:IsA("Folder") then
|
|
99
113
|
coroutine.yield(linked)
|
|
100
114
|
else
|
|
101
|
-
warn("Bad link value type")
|
|
115
|
+
warn("[DependencyUtils] - Bad link value type")
|
|
102
116
|
end
|
|
103
117
|
else
|
|
104
|
-
warn("Nothing linked")
|
|
118
|
+
warn("[DependencyUtils] - Nothing linked")
|
|
105
119
|
end
|
|
106
120
|
end
|
|
107
121
|
end
|
|
@@ -116,10 +130,10 @@ function DependencyUtils.iterPackagesInModuleModules(nodeModules)
|
|
|
116
130
|
if linked:IsA("ModuleScript") or linked:IsA("Folder") then
|
|
117
131
|
coroutine.yield(linked)
|
|
118
132
|
else
|
|
119
|
-
warn("Bad link value type")
|
|
133
|
+
warn("[DependencyUtils] - Bad link value type")
|
|
120
134
|
end
|
|
121
135
|
else
|
|
122
|
-
warn("Nothing linked")
|
|
136
|
+
warn("[DependencyUtils] - Nothing linked")
|
|
123
137
|
end
|
|
124
138
|
end
|
|
125
139
|
end
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
For each package, track subdependent packages and packages
|
|
3
|
+
|
|
4
|
+
@class PackageTracker
|
|
5
|
+
]=]
|
|
6
|
+
|
|
7
|
+
local loader = script.Parent.Parent
|
|
8
|
+
local Maid = require(loader.Maid)
|
|
9
|
+
local DependencyUtils = require(loader.Dependencies.DependencyUtils)
|
|
10
|
+
local ReplicationType = require(loader.Replication.ReplicationType)
|
|
11
|
+
local ReplicationTypeUtils = require(loader.Replication.ReplicationTypeUtils)
|
|
12
|
+
|
|
13
|
+
local PackageTracker = {}
|
|
14
|
+
PackageTracker.ClassName = "PackageTracker"
|
|
15
|
+
PackageTracker.__index = PackageTracker
|
|
16
|
+
|
|
17
|
+
function PackageTracker.new(packageTrackerProvider, packageRoot)
|
|
18
|
+
assert(packageTrackerProvider, "No packageTrackerProvider")
|
|
19
|
+
assert(typeof(packageRoot) == "Instance", "Bad packageRoot")
|
|
20
|
+
|
|
21
|
+
local self = setmetatable({}, PackageTracker)
|
|
22
|
+
self._maid = Maid.new()
|
|
23
|
+
|
|
24
|
+
self._packageTrackerProvider = assert(packageTrackerProvider, "No packageTrackerProvider")
|
|
25
|
+
self._packageRoot = assert(packageRoot, "No packageRoot")
|
|
26
|
+
|
|
27
|
+
self._subpackagesMap = {}
|
|
28
|
+
self._subpackagesTrackerList = {}
|
|
29
|
+
self._packageModuleScriptMap = {}
|
|
30
|
+
|
|
31
|
+
if self._packageRoot:IsA("ModuleScript") then
|
|
32
|
+
-- Module script children don't get to be observed
|
|
33
|
+
self._maid:GiveTask(self:_trackModuleScript(self._packageRoot, ReplicationType.SHARED))
|
|
34
|
+
else
|
|
35
|
+
self._maid:GiveTask(self:_trackChildren(self._packageRoot, ReplicationType.SHARED))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
return self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
function PackageTracker:ResolveDependency(request, replicationType)
|
|
42
|
+
local packageModuleScript = self:FindPackageModuleScript(request, replicationType)
|
|
43
|
+
if packageModuleScript then
|
|
44
|
+
return packageModuleScript
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
local subpackageModuleScript = self:FindSubpackageModuleScript(request, replicationType)
|
|
48
|
+
if subpackageModuleScript then
|
|
49
|
+
return subpackageModuleScript
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
local parentModuleScript = self:FindImplicitParentModuleScript(request, replicationType)
|
|
53
|
+
if parentModuleScript then
|
|
54
|
+
return parentModuleScript
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
return nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
function PackageTracker:FindImplicitParentModuleScript(request, replicationType)
|
|
61
|
+
assert(type(request) == "string", "Bad request")
|
|
62
|
+
assert(ReplicationTypeUtils.isReplicationType(replicationType), "Bad replicationType")
|
|
63
|
+
|
|
64
|
+
-- Implicit dependencies
|
|
65
|
+
local packageRootParent = self._packageRoot.Parent
|
|
66
|
+
if not packageRootParent then
|
|
67
|
+
return nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
local parentProvider = self._packageTrackerProvider:FindPackageTracker(packageRootParent)
|
|
71
|
+
if not parentProvider then
|
|
72
|
+
return nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
-- Check parent provider for implicit dependency
|
|
76
|
+
local subpackageModuleScript = parentProvider:FindSubpackageModuleScript(request, replicationType)
|
|
77
|
+
if subpackageModuleScript then
|
|
78
|
+
return subpackageModuleScript
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return parentProvider:FindImplicitParentModuleScript(request, replicationType)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
function PackageTracker:FindPackageModuleScript(moduleScriptName, replicationType)
|
|
85
|
+
assert(type(moduleScriptName) == "string", "Bad moduleScriptName")
|
|
86
|
+
assert(ReplicationTypeUtils.isReplicationType(replicationType), "Bad replicationType")
|
|
87
|
+
|
|
88
|
+
local found = self._packageModuleScriptMap[moduleScriptName]
|
|
89
|
+
|
|
90
|
+
if found then
|
|
91
|
+
if ReplicationTypeUtils.isAllowed(found.replicationType, replicationType) then
|
|
92
|
+
return found.moduleScript
|
|
93
|
+
else
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
return nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
function PackageTracker:FindSubpackageModuleScript(moduleScriptName, replicationType)
|
|
102
|
+
assert(type(moduleScriptName) == "string", "Bad moduleScriptName")
|
|
103
|
+
assert(ReplicationTypeUtils.isReplicationType(replicationType), "Bad replicationType")
|
|
104
|
+
|
|
105
|
+
for _, packageTracker in pairs(self._subpackagesTrackerList) do
|
|
106
|
+
local found = packageTracker._packageModuleScriptMap[moduleScriptName]
|
|
107
|
+
if found then
|
|
108
|
+
if ReplicationTypeUtils.isAllowed(found.replicationType, replicationType) then
|
|
109
|
+
return found.moduleScript
|
|
110
|
+
else
|
|
111
|
+
return nil
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
return nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
function PackageTracker:_trackChildrenAndReplicationType(parent, ancestorReplicationType)
|
|
120
|
+
assert(typeof(parent) == "Instance", "Bad parent")
|
|
121
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
122
|
+
|
|
123
|
+
local maid = Maid.new()
|
|
124
|
+
|
|
125
|
+
local lastReplicationType = ReplicationTypeUtils.getFolderReplicationType(parent.Name, ancestorReplicationType)
|
|
126
|
+
|
|
127
|
+
maid:GiveTask(parent:GetPropertyChangedSignal("Name"):Connect(function()
|
|
128
|
+
local newReplicationType = ReplicationTypeUtils.getFolderReplicationType(parent.Name, ancestorReplicationType)
|
|
129
|
+
if newReplicationType ~= lastReplicationType then
|
|
130
|
+
maid._current = self:_trackChildren(parent, newReplicationType)
|
|
131
|
+
lastReplicationType = newReplicationType
|
|
132
|
+
end
|
|
133
|
+
end))
|
|
134
|
+
|
|
135
|
+
maid._current = self:_trackChildren(parent, lastReplicationType)
|
|
136
|
+
|
|
137
|
+
return maid
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
function PackageTracker:_trackChildren(parent, ancestorReplicationType)
|
|
141
|
+
assert(typeof(parent) == "Instance", "Bad parent")
|
|
142
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
143
|
+
|
|
144
|
+
local maid = Maid.new()
|
|
145
|
+
|
|
146
|
+
maid:GiveTask(parent.ChildAdded:Connect(function(child)
|
|
147
|
+
self:_handleChildAdded(maid, child, ancestorReplicationType)
|
|
148
|
+
end))
|
|
149
|
+
maid:GiveTask(parent.ChildRemoved:Connect(function(child)
|
|
150
|
+
self:_handleChildRemoved(maid, child, ancestorReplicationType)
|
|
151
|
+
end))
|
|
152
|
+
for _, child in pairs(parent:GetChildren()) do
|
|
153
|
+
self:_handleChildAdded(maid, child, ancestorReplicationType)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
return maid
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
function PackageTracker:_handleChildAdded(parentMaid, child, ancestorReplicationType)
|
|
160
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
161
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
162
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
163
|
+
|
|
164
|
+
if child:IsA("ModuleScript") then
|
|
165
|
+
parentMaid[child] = self:_trackModuleScript(child, ancestorReplicationType)
|
|
166
|
+
elseif child:IsA("Folder") then
|
|
167
|
+
parentMaid[child] = self:_trackFolder(child, ancestorReplicationType)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
function PackageTracker:_handleChildRemoved(parentMaid, child)
|
|
172
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
173
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
174
|
+
|
|
175
|
+
parentMaid[child] = nil
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
function PackageTracker:_trackFolder(child, ancestorReplicationType)
|
|
180
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
181
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
182
|
+
|
|
183
|
+
local maid = Maid.new()
|
|
184
|
+
|
|
185
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Name"):Connect(function()
|
|
186
|
+
if child.Name == "node_modules" then
|
|
187
|
+
maid._current = self:_trackMainNodeModuleFolder(child)
|
|
188
|
+
else
|
|
189
|
+
maid._current = self:_trackChildrenAndReplicationType(child, ancestorReplicationType)
|
|
190
|
+
end
|
|
191
|
+
end))
|
|
192
|
+
|
|
193
|
+
if child.Name == "node_modules" then
|
|
194
|
+
maid._current = self:_trackMainNodeModuleFolder(child)
|
|
195
|
+
else
|
|
196
|
+
maid._current = self:_trackChildrenAndReplicationType(child, ancestorReplicationType)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
return maid
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
function PackageTracker:_trackModuleScript(child, ancestorReplicationType)
|
|
204
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
205
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
local maid = Maid.new()
|
|
209
|
+
|
|
210
|
+
local function update()
|
|
211
|
+
if child.Archivable then
|
|
212
|
+
maid._current = self:_storeModuleScript(child.Name, child, ancestorReplicationType)
|
|
213
|
+
else
|
|
214
|
+
maid._current = nil
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Name"):Connect(update))
|
|
219
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Archivable"):Connect(update))
|
|
220
|
+
|
|
221
|
+
update()
|
|
222
|
+
|
|
223
|
+
return maid
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
function PackageTracker:_storeModuleScript(moduleScriptName, child, ancestorReplicationType)
|
|
227
|
+
assert(type(moduleScriptName) == "string", "Bad moduleScriptName")
|
|
228
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
229
|
+
assert(ReplicationTypeUtils.isReplicationType(ancestorReplicationType), "Bad ancestorReplicationType")
|
|
230
|
+
|
|
231
|
+
if self._packageModuleScriptMap[moduleScriptName] then
|
|
232
|
+
warn(string.format("[PackageTracker] - Overwriting moduleScript with name %q", moduleScriptName))
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
local data = {
|
|
236
|
+
moduleScript = child;
|
|
237
|
+
replicationType = ancestorReplicationType;
|
|
238
|
+
}
|
|
239
|
+
self._packageModuleScriptMap[moduleScriptName] = data
|
|
240
|
+
|
|
241
|
+
return function()
|
|
242
|
+
if self._packageModuleScriptMap[moduleScriptName] == data then
|
|
243
|
+
self._packageModuleScriptMap[moduleScriptName] = nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
function PackageTracker:_trackMainNodeModuleFolder(parent)
|
|
249
|
+
local maid = Maid.new()
|
|
250
|
+
|
|
251
|
+
maid:GiveTask(parent.ChildAdded:Connect(function(child)
|
|
252
|
+
self:_handleNodeModulesChildAdded(maid, child)
|
|
253
|
+
end))
|
|
254
|
+
maid:GiveTask(parent.ChildRemoved:Connect(function(child)
|
|
255
|
+
self:_handleNodeModulesChildRemoved(maid, child)
|
|
256
|
+
end))
|
|
257
|
+
for _, child in pairs(parent:GetChildren()) do
|
|
258
|
+
self:_handleNodeModulesChildAdded(maid, child)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
return maid
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
function PackageTracker:_handleNodeModulesChildAdded(parentMaid, child)
|
|
266
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
267
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
268
|
+
|
|
269
|
+
if child:IsA("ObjectValue") then
|
|
270
|
+
-- Assume symlinked package
|
|
271
|
+
parentMaid[child] = self:_trackNodeModulesObjectValue(child)
|
|
272
|
+
elseif child:IsA("Folder") then
|
|
273
|
+
parentMaid[child] = self:_trackNodeModulesChildFolder(child)
|
|
274
|
+
elseif child:IsA("ModuleScript") then
|
|
275
|
+
parentMaid[child] = self:_trackAddPackage(child)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
function PackageTracker:_handleNodeModulesChildRemoved(parentMaid, child)
|
|
280
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
281
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
282
|
+
|
|
283
|
+
parentMaid[child] = nil
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
function PackageTracker:_trackNodeModulesChildFolder(child)
|
|
287
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
288
|
+
|
|
289
|
+
local maid = Maid.new()
|
|
290
|
+
|
|
291
|
+
local function update()
|
|
292
|
+
local childName = child.Name
|
|
293
|
+
|
|
294
|
+
-- like @quenty
|
|
295
|
+
if DependencyUtils.isPackageGroup(childName) then
|
|
296
|
+
return self:_trackScopedChildFolder(childName, child)
|
|
297
|
+
else
|
|
298
|
+
return self:_tryStorePackage(childName, child)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Name"):Connect(function()
|
|
303
|
+
maid._current = update()
|
|
304
|
+
end))
|
|
305
|
+
|
|
306
|
+
maid._current = update()
|
|
307
|
+
|
|
308
|
+
return maid
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
function PackageTracker:_trackNodeModulesObjectValue(objectValue)
|
|
312
|
+
assert(typeof(objectValue) == "Instance", "Bad objectValue")
|
|
313
|
+
|
|
314
|
+
local maid = Maid.new()
|
|
315
|
+
|
|
316
|
+
maid:GiveTask(objectValue:GetPropertyChangedSignal("Name"):Connect(function()
|
|
317
|
+
maid._current = self:_tryStorePackage(objectValue.Name, objectValue.Value)
|
|
318
|
+
end))
|
|
319
|
+
maid:GiveTask(objectValue:GetPropertyChangedSignal("Value"):Connect(function()
|
|
320
|
+
maid._current = self:_tryStorePackage(objectValue.Name, objectValue.Value)
|
|
321
|
+
end))
|
|
322
|
+
|
|
323
|
+
maid._current = self:_tryStorePackage(objectValue.Name, objectValue.Value)
|
|
324
|
+
|
|
325
|
+
return maid
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
function PackageTracker:_trackScopedChildFolder(scopeName, parent)
|
|
329
|
+
assert(type(scopeName) == "string", "Bad scopeName")
|
|
330
|
+
assert(typeof(parent) == "Instance", "Bad parent")
|
|
331
|
+
|
|
332
|
+
local maid = Maid.new()
|
|
333
|
+
|
|
334
|
+
maid:GiveTask(parent.ChildAdded:Connect(function(child)
|
|
335
|
+
self:_handleScopedModulesChildAdded(scopeName, maid, child)
|
|
336
|
+
end))
|
|
337
|
+
maid:GiveTask(parent.ChildRemoved:Connect(function(child)
|
|
338
|
+
self:_handleScopedModulesChildRemoved(maid, child)
|
|
339
|
+
end))
|
|
340
|
+
for _, child in pairs(parent:GetChildren()) do
|
|
341
|
+
self:_handleScopedModulesChildAdded(scopeName, maid, child)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
return maid
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
function PackageTracker:_handleScopedModulesChildAdded(scopeName, parentMaid, child)
|
|
348
|
+
assert(type(scopeName) == "string", "Bad scopeName")
|
|
349
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
350
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
351
|
+
|
|
352
|
+
if child:IsA("ObjectValue") then
|
|
353
|
+
parentMaid[child] = self:_trackScopedNodeModulesObjectValue(scopeName, child)
|
|
354
|
+
elseif child:IsA("Folder") or child:IsA("ModuleScript") then
|
|
355
|
+
parentMaid[child] = self:_trackAddScopedPackage(scopeName, child)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
function PackageTracker:_trackScopedNodeModulesObjectValue(scopeName, objectValue)
|
|
360
|
+
assert(type(scopeName) == "string", "Bad scopeName")
|
|
361
|
+
assert(typeof(objectValue) == "Instance", "Bad objectValue")
|
|
362
|
+
|
|
363
|
+
local maid = Maid.new()
|
|
364
|
+
|
|
365
|
+
maid:GiveTask(objectValue:GetPropertyChangedSignal("Name"):Connect(function()
|
|
366
|
+
maid._current = self:_tryStorePackage(scopeName .. "/" .. objectValue.Name, objectValue.Value)
|
|
367
|
+
end))
|
|
368
|
+
maid:GiveTask(objectValue:GetPropertyChangedSignal("Value"):Connect(function()
|
|
369
|
+
maid._current = self:_tryStorePackage(scopeName .. "/" .. objectValue.Name, objectValue.Value)
|
|
370
|
+
end))
|
|
371
|
+
|
|
372
|
+
maid._current = self:_tryStorePackage(scopeName .. "/" .. objectValue.Name, objectValue.Value)
|
|
373
|
+
|
|
374
|
+
return maid
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
function PackageTracker:_handleScopedModulesChildRemoved(parentMaid, child)
|
|
378
|
+
assert(Maid.isMaid(parentMaid), "Bad maid")
|
|
379
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
380
|
+
|
|
381
|
+
parentMaid[child] = nil
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
function PackageTracker:_trackAddScopedPackage(scopeName, child)
|
|
385
|
+
assert(type(scopeName) == "string", "Bad scopeName")
|
|
386
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
387
|
+
|
|
388
|
+
local maid = Maid.new()
|
|
389
|
+
|
|
390
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Name"):Connect(function()
|
|
391
|
+
maid._current = self:_tryStorePackage(scopeName .. "/" .. child.Name, child)
|
|
392
|
+
end))
|
|
393
|
+
|
|
394
|
+
maid._current = self:_tryStorePackage(scopeName .. "/" .. child.Name, child)
|
|
395
|
+
|
|
396
|
+
return maid
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
function PackageTracker:_trackAddPackage(child)
|
|
400
|
+
assert(typeof(child) == "Instance", "Bad child")
|
|
401
|
+
|
|
402
|
+
local maid = Maid.new()
|
|
403
|
+
|
|
404
|
+
maid:GiveTask(child:GetPropertyChangedSignal("Name"):Connect(function()
|
|
405
|
+
maid._current = self:_tryStorePackage(child.Name, child)
|
|
406
|
+
end))
|
|
407
|
+
|
|
408
|
+
maid._current = self:_tryStorePackage(child.Name, child)
|
|
409
|
+
|
|
410
|
+
return maid
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
function PackageTracker:_tryStorePackage(fullPackageName, packageInst)
|
|
414
|
+
assert(type(fullPackageName) == "string", "Bad fullPackageName")
|
|
415
|
+
|
|
416
|
+
if not packageInst then
|
|
417
|
+
return nil
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
self._subpackagesMap[fullPackageName] = packageInst
|
|
421
|
+
|
|
422
|
+
local packageTracker = self._packageTrackerProvider:AddPackageRoot(packageInst)
|
|
423
|
+
table.insert(self._subpackagesTrackerList, packageTracker)
|
|
424
|
+
|
|
425
|
+
return function()
|
|
426
|
+
local index = table.find(self._subpackagesTrackerList, packageTracker)
|
|
427
|
+
if index then
|
|
428
|
+
table.remove(self._subpackagesTrackerList, packageTracker)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
if self._subpackagesMap[fullPackageName] == packageInst then
|
|
432
|
+
self._subpackagesMap[fullPackageName] = nil
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
function PackageTracker:Destroy()
|
|
438
|
+
self._maid:DoCleaning()
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
return PackageTracker
|