@quenty/loader 10.0.0 → 10.1.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 +8 -0
- package/default.project.json +1 -1
- package/package.json +2 -2
- package/src/LoaderUtils.lua +2 -235
- package/src/Utils.lua +1 -1
- package/src/init.lua +154 -103
- package/src/BounceTemplate.lua +0 -17
- package/src/BounceTemplateUtils.lua +0 -66
- package/src/GroupInfoUtils.lua +0 -167
- package/src/LegacyLoader.lua +0 -131
- package/src/Loader.lua +0 -52
- package/src/LoaderConstants.lua +0 -12
- package/src/PackageInfoUtils.lua +0 -232
- package/src/Queue.lua +0 -109
- package/src/ScriptInfoUtils.lua +0 -153
- package/src/StaticLegacyLoader.lua +0 -211
- package/src2/LoaderUtils.lua +0 -3
- package/src2/Utils.lua +0 -106
- package/src2/init.lua +0 -171
- /package/{src2 → src}/Dependencies/DependencyUtils.lua +0 -0
- /package/{src2 → src}/Dependencies/PackageTracker.lua +0 -0
- /package/{src2 → src}/Dependencies/PackageTrackerProvider.lua +0 -0
- /package/{src2 → src}/LoaderLink/LoaderLink.lua +0 -0
- /package/{src2 → src}/LoaderLink/LoaderLinkCreator.lua +0 -0
- /package/{src2 → src}/LoaderLink/LoaderLinkUtils.lua +0 -0
- /package/{src2 → src}/Maid.lua +0 -0
- /package/{src2 → src}/Replication/ReplicationType.lua +0 -0
- /package/{src2 → src}/Replication/ReplicationTypeUtils.lua +0 -0
- /package/{src2 → src}/Replication/Replicator.lua +0 -0
- /package/{src2 → src}/Replication/ReplicatorReferences.lua +0 -0
- /package/{src2 → src}/Replication/ReplicatorUtils.lua +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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
|
+
# [10.1.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@10.0.0...@quenty/loader@10.1.0) (2024-03-09)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/loader
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# [10.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@9.0.0...@quenty/loader@10.0.0) (2024-02-14)
|
|
7
15
|
|
|
8
16
|
|
package/default.project.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/loader",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.1.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": "e0148dde5ca3864389a0faa2da66153a776acc1e"
|
|
30
30
|
}
|
package/src/LoaderUtils.lua
CHANGED
|
@@ -1,236 +1,3 @@
|
|
|
1
|
-
--
|
|
2
|
-
@private
|
|
3
|
-
@class LoaderUtils
|
|
4
|
-
]=]
|
|
1
|
+
-- Literally here just so old loading code works
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
local BounceTemplateUtils = require(script.Parent.BounceTemplateUtils)
|
|
8
|
-
local GroupInfoUtils = require(script.Parent.GroupInfoUtils)
|
|
9
|
-
local PackageInfoUtils = require(script.Parent.PackageInfoUtils)
|
|
10
|
-
local ScriptInfoUtils = require(script.Parent.ScriptInfoUtils)
|
|
11
|
-
local Utils = require(script.Parent.Utils)
|
|
12
|
-
|
|
13
|
-
local LoaderUtils = {}
|
|
14
|
-
LoaderUtils.Utils = Utils -- TODO: Remove this
|
|
15
|
-
|
|
16
|
-
LoaderUtils.ContextTypes = Utils.readonly({
|
|
17
|
-
CLIENT = "client";
|
|
18
|
-
SERVER = "server";
|
|
19
|
-
})
|
|
20
|
-
LoaderUtils.IncludeBehavior = Utils.readonly({
|
|
21
|
-
NO_INCLUDE = "noInclude";
|
|
22
|
-
INCLUDE_ONLY = "includeOnly";
|
|
23
|
-
INCLUDE_SHARED = "includeShared";
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
function LoaderUtils.toWallyFormat(instance, isPlugin)
|
|
27
|
-
assert(typeof(instance) == "Instance", "Bad instance")
|
|
28
|
-
assert(type(isPlugin) == "boolean", "Bad isPlugin")
|
|
29
|
-
|
|
30
|
-
local topLevelPackages = {}
|
|
31
|
-
LoaderUtils.discoverTopLevelPackages(topLevelPackages, instance)
|
|
32
|
-
LoaderUtils.injectLoader(topLevelPackages)
|
|
33
|
-
|
|
34
|
-
local packageInfoList = {}
|
|
35
|
-
local packageInfoMap = {}
|
|
36
|
-
local defaultReplicationType = isPlugin
|
|
37
|
-
and ScriptInfoUtils.ModuleReplicationTypes.PLUGIN
|
|
38
|
-
or ScriptInfoUtils.ModuleReplicationTypes.SHARED
|
|
39
|
-
|
|
40
|
-
for _, folder in pairs(topLevelPackages) do
|
|
41
|
-
local packageInfo = PackageInfoUtils.getOrCreatePackageInfo(folder, packageInfoMap, "", defaultReplicationType)
|
|
42
|
-
table.insert(packageInfoList, packageInfo)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
PackageInfoUtils.fillDependencySet(packageInfoList)
|
|
46
|
-
|
|
47
|
-
if isPlugin then
|
|
48
|
-
local pluginGroup = GroupInfoUtils.groupPackageInfos(packageInfoList, ScriptInfoUtils.ModuleReplicationTypes.PLUGIN)
|
|
49
|
-
local publishSet = LoaderUtils.getPublishPackageInfoSet(packageInfoList)
|
|
50
|
-
|
|
51
|
-
local pluginFolder = Instance.new("Folder")
|
|
52
|
-
pluginFolder.Name = "PluginPackages"
|
|
53
|
-
|
|
54
|
-
LoaderUtils.reifyGroupList(pluginGroup, publishSet, pluginFolder, ScriptInfoUtils.ModuleReplicationTypes.PLUGIN)
|
|
55
|
-
|
|
56
|
-
return pluginFolder
|
|
57
|
-
else
|
|
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)
|
|
61
|
-
local publishSet = LoaderUtils.getPublishPackageInfoSet(packageInfoList)
|
|
62
|
-
|
|
63
|
-
local clientFolder = Instance.new("Folder")
|
|
64
|
-
clientFolder.Name = "Packages"
|
|
65
|
-
|
|
66
|
-
local sharedFolder = Instance.new("Folder")
|
|
67
|
-
sharedFolder.Name = "SharedPackages"
|
|
68
|
-
|
|
69
|
-
local serverFolder = Instance.new("Folder")
|
|
70
|
-
serverFolder.Name = "Packages"
|
|
71
|
-
|
|
72
|
-
LoaderUtils.reifyGroupList(clientGroupList, publishSet, clientFolder, ScriptInfoUtils.ModuleReplicationTypes.CLIENT)
|
|
73
|
-
LoaderUtils.reifyGroupList(serverGroupList, publishSet, serverFolder, ScriptInfoUtils.ModuleReplicationTypes.SERVER)
|
|
74
|
-
LoaderUtils.reifyGroupList(sharedGroupList, publishSet, sharedFolder, ScriptInfoUtils.ModuleReplicationTypes.SHARED)
|
|
75
|
-
|
|
76
|
-
return clientFolder, serverFolder, sharedFolder
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
function LoaderUtils.isPackage(folder)
|
|
81
|
-
assert(typeof(folder) == "Instance", "Bad instance")
|
|
82
|
-
|
|
83
|
-
for _, item in pairs(folder:GetChildren()) do
|
|
84
|
-
if item:IsA("Folder") or item:IsA("Camera") then
|
|
85
|
-
if item.Name == "Server"
|
|
86
|
-
or item.Name == "Client"
|
|
87
|
-
or item.Name == "Shared"
|
|
88
|
-
or item.Name == ScriptInfoUtils.DEPENDENCY_FOLDER_NAME then
|
|
89
|
-
return true
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
return false
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
function LoaderUtils.injectLoader(topLevelPackages)
|
|
98
|
-
for _, item in pairs(topLevelPackages) do
|
|
99
|
-
-- If we're underneath the hierachy or if we're in the actual item...
|
|
100
|
-
if item == loader or loader:IsDescendantOf(item) then
|
|
101
|
-
return
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
-- We need the loader injected!
|
|
106
|
-
table.insert(topLevelPackages, loader)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
function LoaderUtils.discoverTopLevelPackages(packages, instance)
|
|
110
|
-
assert(type(packages) == "table", "Bad packages")
|
|
111
|
-
assert(typeof(instance) == "Instance", "Bad instance")
|
|
112
|
-
|
|
113
|
-
if LoaderUtils.isPackage(instance) then
|
|
114
|
-
table.insert(packages, instance)
|
|
115
|
-
elseif instance:IsA("ObjectValue") then
|
|
116
|
-
local linkedValue = instance.Value
|
|
117
|
-
if linkedValue and LoaderUtils.isPackage(linkedValue) then
|
|
118
|
-
table.insert(packages, linkedValue)
|
|
119
|
-
end
|
|
120
|
-
else
|
|
121
|
-
-- Loop through all folders
|
|
122
|
-
for _, item in pairs(instance:GetChildren()) do
|
|
123
|
-
if item:IsA("Folder") or item:IsA("Camera") then
|
|
124
|
-
LoaderUtils.discoverTopLevelPackages(packages, item)
|
|
125
|
-
elseif item:IsA("ObjectValue") then
|
|
126
|
-
local linkedValue = item.Value
|
|
127
|
-
if linkedValue and LoaderUtils.isPackage(linkedValue) then
|
|
128
|
-
table.insert(packages, linkedValue)
|
|
129
|
-
end
|
|
130
|
-
elseif item:IsA("ModuleScript") then
|
|
131
|
-
table.insert(packages, item)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
function LoaderUtils.reifyGroupList(groupInfoList, publishSet, parent, replicationMode)
|
|
138
|
-
assert(type(groupInfoList) == "table", "Bad groupInfoList")
|
|
139
|
-
assert(type(publishSet) == "table", "Bad publishSet")
|
|
140
|
-
assert(typeof(parent) == "Instance", "Bad parent")
|
|
141
|
-
assert(type(replicationMode) == "string", "Bad replicationMode")
|
|
142
|
-
|
|
143
|
-
local folder = Instance.new("Folder")
|
|
144
|
-
folder.Name = "_Index"
|
|
145
|
-
|
|
146
|
-
for _, groupInfo in pairs(groupInfoList) do
|
|
147
|
-
if LoaderUtils.needToReify(groupInfo, replicationMode) then
|
|
148
|
-
LoaderUtils.reifyGroup(groupInfo, folder, replicationMode)
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
-- Publish
|
|
153
|
-
for packageInfo, _ in pairs(publishSet) do
|
|
154
|
-
for scriptName, scriptInfo in pairs(packageInfo.scriptInfoLookup[replicationMode]) do
|
|
155
|
-
local link = BounceTemplateUtils.create(scriptInfo.instance, scriptName)
|
|
156
|
-
link.Parent = parent
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
folder.Parent = parent
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
function LoaderUtils.getPublishPackageInfoSet(packageInfoList)
|
|
164
|
-
local packageInfoSet = {}
|
|
165
|
-
for _, packageInfo in pairs(packageInfoList) do
|
|
166
|
-
packageInfoSet[packageInfo] = true
|
|
167
|
-
-- First level declared dependencies too (assuming we're importing just one item)
|
|
168
|
-
for dependentPackageInfo, _ in pairs(packageInfo.explicitDependencySet) do
|
|
169
|
-
packageInfoSet[dependentPackageInfo] = true
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
return packageInfoSet
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
function LoaderUtils.needToReify(groupInfo, replicationMode)
|
|
176
|
-
for _, scriptInfo in pairs(groupInfo.packageScriptInfoMap) do
|
|
177
|
-
if scriptInfo.replicationMode == replicationMode then
|
|
178
|
-
return true
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
return false
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
function LoaderUtils.reifyGroup(groupInfo, parent, replicationMode)
|
|
186
|
-
assert(type(groupInfo) == "table", "Bad groupInfo")
|
|
187
|
-
assert(typeof(parent) == "Instance", "Bad parent")
|
|
188
|
-
assert(type(replicationMode) == "string", "Bad replicationMode")
|
|
189
|
-
|
|
190
|
-
local folder = Instance.new("Folder")
|
|
191
|
-
folder.Name = assert(next(groupInfo.packageSet).fullName, "Bad package fullName")
|
|
192
|
-
|
|
193
|
-
for scriptName, scriptInfo in pairs(groupInfo.packageScriptInfoMap) do
|
|
194
|
-
assert(scriptInfo.name == scriptName, "Bad scriptInfo.name")
|
|
195
|
-
|
|
196
|
-
if scriptInfo.replicationMode == replicationMode then
|
|
197
|
-
if scriptInfo.instance == loader and loader.Parent == game:GetService("ReplicatedStorage") then
|
|
198
|
-
-- Hack to prevent reparenting of loader in legacy mode
|
|
199
|
-
local link = BounceTemplateUtils.create(scriptInfo.instance, scriptName)
|
|
200
|
-
link.Parent = folder
|
|
201
|
-
else
|
|
202
|
-
scriptInfo.instance.Name = scriptName
|
|
203
|
-
scriptInfo.instance.Parent = folder
|
|
204
|
-
end
|
|
205
|
-
else
|
|
206
|
-
if scriptInfo.instance == loader then
|
|
207
|
-
local link = BounceTemplateUtils.create(scriptInfo.instance, scriptName)
|
|
208
|
-
link.Parent = folder
|
|
209
|
-
else
|
|
210
|
-
-- Turns out creating these links are a LOT faster than cloning a module script
|
|
211
|
-
local link = BounceTemplateUtils.createLink(scriptInfo.instance, scriptName)
|
|
212
|
-
link.Parent = folder
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
-- Link all of the other dependencies
|
|
218
|
-
for scriptName, scriptInfo in pairs(groupInfo.scriptInfoMap) do
|
|
219
|
-
assert(scriptInfo.name == scriptName, "Bad scriptInfo.name")
|
|
220
|
-
|
|
221
|
-
if not groupInfo.packageScriptInfoMap[scriptName] then
|
|
222
|
-
if scriptInfo.instance == loader then
|
|
223
|
-
local link = BounceTemplateUtils.create(scriptInfo.instance, scriptName)
|
|
224
|
-
link.Parent = folder
|
|
225
|
-
else
|
|
226
|
-
-- Turns out creating these links are a LOT faster than cloning a module script
|
|
227
|
-
local link = BounceTemplateUtils.createLink(scriptInfo.instance, scriptName)
|
|
228
|
-
link.Parent = folder
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
folder.Parent = parent
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
return LoaderUtils
|
|
3
|
+
error("Not implemented! Please require LoaderUtils.Parent. This file acts as a marker for old loader versions.")
|
package/src/Utils.lua
CHANGED
package/src/init.lua
CHANGED
|
@@ -1,137 +1,188 @@
|
|
|
1
1
|
--[=[
|
|
2
|
-
|
|
2
|
+
Primary loader which handles bootstrapping different scenarios quickly
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Specific layouts for npm node_modules
|
|
7
|
-
* Layouts for node_modules being symlinked
|
|
8
|
-
* Multiple versions of modules being used in conjunction with each other
|
|
9
|
-
* Relative path requires
|
|
10
|
-
* Require by name
|
|
11
|
-
* Replication to client and server
|
|
12
|
-
|
|
13
|
-
@class Loader
|
|
4
|
+
@class loader
|
|
14
5
|
]=]
|
|
15
6
|
|
|
16
7
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
17
|
-
local ServerScriptService = game:GetService("ServerScriptService")
|
|
18
8
|
local RunService = game:GetService("RunService")
|
|
19
9
|
|
|
20
|
-
local
|
|
21
|
-
local
|
|
22
|
-
local
|
|
23
|
-
|
|
24
|
-
local
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
10
|
+
local DependencyUtils = require(script.Dependencies.DependencyUtils)
|
|
11
|
+
local LoaderLinkCreator = require(script.LoaderLink.LoaderLinkCreator)
|
|
12
|
+
local LoaderLinkUtils = require(script.LoaderLink.LoaderLinkUtils)
|
|
13
|
+
local Maid = require(script.Maid)
|
|
14
|
+
local PackageTrackerProvider = require(script.Dependencies.PackageTrackerProvider)
|
|
15
|
+
local ReplicationType = require(script.Replication.ReplicationType)
|
|
16
|
+
local ReplicationTypeUtils = require(script.Replication.ReplicationTypeUtils)
|
|
17
|
+
local Replicator = require(script.Replication.Replicator)
|
|
18
|
+
local ReplicatorReferences = require(script.Replication.ReplicatorReferences)
|
|
19
|
+
|
|
20
|
+
local GLOBAL_PACKAGE_TRACKER = PackageTrackerProvider.new()
|
|
21
|
+
|
|
22
|
+
local Loader = {}
|
|
23
|
+
Loader.__index = Loader
|
|
24
|
+
Loader.ClassName = "Loader"
|
|
25
|
+
|
|
26
|
+
function Loader.new(packages, replicationType)
|
|
27
|
+
assert(typeof(packages) == "Instance", "Bad packages")
|
|
28
|
+
assert(ReplicationTypeUtils.isReplicationType(replicationType), "Bad replicationType")
|
|
29
|
+
|
|
30
|
+
local self = setmetatable({}, Loader)
|
|
31
|
+
|
|
32
|
+
self._maid = Maid.new()
|
|
33
|
+
|
|
34
|
+
self._replicationType = assert(replicationType, "No replicationType")
|
|
35
|
+
self._packages = assert(packages, "No packages")
|
|
36
|
+
|
|
37
|
+
return self
|
|
47
38
|
end
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
shared.
|
|
40
|
+
function Loader.bootstrapGame(packages)
|
|
41
|
+
assert(typeof(packages) == "Instance", "Bad packages")
|
|
52
42
|
|
|
53
|
-
|
|
54
|
-
local ServerScriptService = game:GetService("ServerScriptService")
|
|
43
|
+
local self = Loader.new(packages, ReplicationTypeUtils.inferReplicationType())
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
45
|
+
if self._replicationType == ReplicationType.SERVER then
|
|
46
|
+
self:_setupLoaderPopulation()
|
|
59
47
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
-- Trade off security for performance
|
|
49
|
+
if RunService:IsStudio() then
|
|
50
|
+
packages.Parent = ReplicatedStorage
|
|
51
|
+
else
|
|
52
|
+
self:_setupClientReplication()
|
|
53
|
+
end
|
|
54
|
+
end
|
|
63
55
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
56
|
+
GLOBAL_PACKAGE_TRACKER:AddPackageRoot(packages)
|
|
57
|
+
|
|
58
|
+
-- We need to wait here once we "populate" the loader so the Ancestry/query events can
|
|
59
|
+
-- fire in Signal deferred mode.
|
|
60
|
+
self:_waitForNextDeferFrame()
|
|
61
|
+
|
|
62
|
+
return self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
function Loader.bootstrapPlugin(packages)
|
|
66
|
+
assert(typeof(packages) == "Instance", "Bad packages")
|
|
67
|
+
|
|
68
|
+
local self = Loader.new(packages, ReplicationType.PLUGIN)
|
|
69
|
+
|
|
70
|
+
self:_setupLoaderPopulation()
|
|
71
|
+
|
|
72
|
+
GLOBAL_PACKAGE_TRACKER:AddPackageRoot(packages)
|
|
73
|
+
|
|
74
|
+
-- We need to wait here once we "populate" the loader so the Ancestry/query events can
|
|
75
|
+
-- fire in Signal deferred mode.
|
|
76
|
+
self:_waitForNextDeferFrame()
|
|
77
|
+
|
|
78
|
+
return self
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
function Loader.load(packagesOrModuleScript)
|
|
82
|
+
assert(typeof(packagesOrModuleScript) == "Instance", "Bad packagesOrModuleScript")
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
local self = Loader.new(packagesOrModuleScript, ReplicationTypeUtils.inferReplicationType())
|
|
75
85
|
|
|
76
|
-
|
|
86
|
+
return self
|
|
87
|
+
end
|
|
77
88
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
function Loader:__index(request)
|
|
90
|
+
if Loader[request] then
|
|
91
|
+
return Loader[request]
|
|
92
|
+
end
|
|
81
93
|
|
|
82
|
-
return
|
|
94
|
+
return self:_findDependency(request)
|
|
83
95
|
end
|
|
84
96
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
function Loader:__call(request)
|
|
98
|
+
if type(request) == "string" then
|
|
99
|
+
local module = self:_findDependency(request)
|
|
100
|
+
return require(module)
|
|
101
|
+
else
|
|
102
|
+
return require(request)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
89
105
|
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
function Loader:_waitForNextDeferFrame()
|
|
107
|
+
local signal = Instance.new("BindableEvent")
|
|
108
|
+
task.defer(function()
|
|
109
|
+
signal:Fire()
|
|
110
|
+
end)
|
|
111
|
+
signal.Event:Wait()
|
|
112
|
+
signal:Destroy()
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
function Loader:_findDependency(request)
|
|
116
|
+
assert(type(request) == "string", "Bad request")
|
|
92
117
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
118
|
+
local packageTracker = GLOBAL_PACKAGE_TRACKER:FindPackageTracker(self._packages)
|
|
119
|
+
if packageTracker then
|
|
120
|
+
local foundDependency = packageTracker:ResolveDependency(request, self._replicationType)
|
|
121
|
+
if foundDependency then
|
|
122
|
+
return foundDependency
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
-- Otherwise let's fail with an error acknowledging that the module exists
|
|
126
|
+
if self._replicationType == ReplicationType.SERVER or self._replicationType == ReplicationType.SHARED then
|
|
127
|
+
local foundClientDependency = packageTracker:ResolveDependency(request, ReplicationType.CLIENT)
|
|
128
|
+
if foundClientDependency then
|
|
129
|
+
error(string.format("[Loader] - %q is only available on the client", foundClientDependency.Name))
|
|
97
130
|
end
|
|
131
|
+
end
|
|
98
132
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
133
|
+
if self._replicationType == ReplicationType.CLIENT or self._replicationType == ReplicationType.SHARED then
|
|
134
|
+
local foundServerDependency = packageTracker:ResolveDependency(request, ReplicationType.SERVER)
|
|
135
|
+
if foundServerDependency then
|
|
136
|
+
error(string.format("[Loader] - %q is only available on the server", foundServerDependency.Name))
|
|
137
|
+
end
|
|
102
138
|
end
|
|
103
139
|
end
|
|
140
|
+
|
|
141
|
+
-- Just standard dependency search
|
|
142
|
+
local foundBackup = DependencyUtils.findDependency(self._packages, request, self._replicationType)
|
|
143
|
+
if foundBackup then
|
|
144
|
+
if RunService:IsRunning() then
|
|
145
|
+
warn(string.format("[Loader] - Failed to find package %q in package tracker\n%s", request, debug.traceback()))
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
-- Ensure hoarcekat story has a link to use
|
|
149
|
+
-- TODO: Maybe add to global package cache instead...
|
|
150
|
+
local parent = foundBackup.Parent
|
|
151
|
+
if parent and not parent:FindFirstChild("loader") then
|
|
152
|
+
local link = LoaderLinkUtils.create(script, "loader")
|
|
153
|
+
link.Parent = parent
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
return foundBackup
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
-- TODO: Track location and provider install command
|
|
160
|
+
error(string.format("[Loader] - %q is not available. Please make this module or install it to the package requiring it.", request))
|
|
161
|
+
return nil
|
|
104
162
|
end
|
|
105
163
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
@within Loader
|
|
110
|
-
]=]
|
|
164
|
+
function Loader:_setupClientReplication()
|
|
165
|
+
local copy = self._maid:Add(Instance.new("Folder"))
|
|
166
|
+
copy.Name = self._packages.Name
|
|
111
167
|
|
|
112
|
-
|
|
113
|
-
Returns a function that can be used to load modules relative
|
|
114
|
-
to the script specified.
|
|
168
|
+
local references = ReplicatorReferences.new()
|
|
115
169
|
|
|
116
|
-
|
|
117
|
-
|
|
170
|
+
local replicator = self._maid:Add(Replicator.new(references))
|
|
171
|
+
replicator:SetTarget(copy)
|
|
172
|
+
replicator:ReplicateFrom(self._packages)
|
|
118
173
|
|
|
119
|
-
|
|
120
|
-
```
|
|
174
|
+
self._maid:Add(LoaderLinkCreator.new(copy, references, true))
|
|
121
175
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
assert(typeof(moduleScript) == "Instance", "Bad moduleScript")
|
|
176
|
+
copy.Parent = ReplicatedStorage
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
function Loader:_setupLoaderPopulation()
|
|
180
|
+
self._maid:Add(LoaderLinkCreator.new(self._packages, nil, true))
|
|
181
|
+
end
|
|
129
182
|
|
|
130
|
-
|
|
183
|
+
function Loader:Destroy()
|
|
184
|
+
self._maid:DoCleaning()
|
|
185
|
+
setmetatable(self, nil)
|
|
131
186
|
end
|
|
132
187
|
|
|
133
|
-
return
|
|
134
|
-
load = handleLoad;
|
|
135
|
-
bootstrapGame = bootstrapGame;
|
|
136
|
-
bootstrapPlugin = bootstrapPlugin;
|
|
137
|
-
}, metatable)
|
|
188
|
+
return Loader
|
package/src/BounceTemplate.lua
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
Bounces the current named script to the expected version of this module
|
|
3
|
-
|
|
4
|
-
@private
|
|
5
|
-
@class BounceTemplate
|
|
6
|
-
]=]
|
|
7
|
-
|
|
8
|
-
local function waitForValue(objectValue)
|
|
9
|
-
local value = objectValue.Value
|
|
10
|
-
if value then
|
|
11
|
-
return value
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
return objectValue.Changed:Wait()
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
return require(waitForValue(script:WaitForChild("BounceTarget")))
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
@class BounceTemplateUtils
|
|
3
|
-
@private
|
|
4
|
-
]=]
|
|
5
|
-
|
|
6
|
-
local BounceTemplate = script.Parent.BounceTemplate
|
|
7
|
-
|
|
8
|
-
local CREATE_ONLY_LINK = false
|
|
9
|
-
|
|
10
|
-
local BounceTemplateUtils = {}
|
|
11
|
-
|
|
12
|
-
function BounceTemplateUtils.isBounceTemplate(instance)
|
|
13
|
-
return instance:GetAttribute("IsBounceTemplate", true) == true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
function BounceTemplateUtils.getTarget(instance)
|
|
17
|
-
if not BounceTemplateUtils.isBounceTemplate(instance) then
|
|
18
|
-
return nil
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
if instance:IsA("ObjectValue") then
|
|
22
|
-
return instance.Value
|
|
23
|
-
else
|
|
24
|
-
local found = instance:FindFirstChild("BounceTarget")
|
|
25
|
-
if found then
|
|
26
|
-
return found.Value
|
|
27
|
-
else
|
|
28
|
-
warn("[BounceTemplateUtils.getTarget] - Bounce template without BounceTarget")
|
|
29
|
-
return nil
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
function BounceTemplateUtils.create(target, linkName)
|
|
35
|
-
assert(typeof(target) == "Instance", "Bad target")
|
|
36
|
-
assert(type(linkName) == "string", "Bad linkName")
|
|
37
|
-
|
|
38
|
-
if CREATE_ONLY_LINK then
|
|
39
|
-
return BounceTemplateUtils.createLink(target, linkName)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
local copy = BounceTemplate:Clone()
|
|
43
|
-
copy:SetAttribute("IsBounceTemplate", true)
|
|
44
|
-
copy.Name = linkName
|
|
45
|
-
|
|
46
|
-
local objectValue = Instance.new("ObjectValue")
|
|
47
|
-
objectValue.Name = "BounceTarget"
|
|
48
|
-
objectValue.Value = target
|
|
49
|
-
objectValue.Parent = copy
|
|
50
|
-
|
|
51
|
-
return copy
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
function BounceTemplateUtils.createLink(target, linkName)
|
|
55
|
-
assert(typeof(target) == "Instance", "Bad target")
|
|
56
|
-
assert(type(linkName) == "string", "Bad linkName")
|
|
57
|
-
|
|
58
|
-
local objectValue = Instance.new("ObjectValue")
|
|
59
|
-
objectValue.Name = linkName
|
|
60
|
-
objectValue.Value = target
|
|
61
|
-
objectValue:SetAttribute("IsBounceTemplate", true)
|
|
62
|
-
|
|
63
|
-
return objectValue
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
return BounceTemplateUtils
|