@quenty/loader 10.2.0 → 10.3.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 +13 -0
- package/default.project.json +1 -0
- package/package.json +2 -2
- package/src/Dependencies/PackageTracker.lua +1 -1
- package/src/LoaderLink/LoaderLink.lua +6 -1
- package/src/LoaderLink/LoaderLinkCreator.lua +64 -38
- package/src/Replication/ReplicatorReferences.lua +4 -0
- package/src/init.lua +20 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
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.3.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@10.2.0...@quenty/loader@10.3.0) (2024-05-09)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Fix .package-lock.json replicating in packages ([75d0efe](https://github.com/Quenty/NevermoreEngine/commit/75d0efeef239f221d93352af71a5b3e930ec23c5))
|
|
12
|
+
* Fix hoarcekat asset addition logic ([89e2c18](https://github.com/Quenty/NevermoreEngine/commit/89e2c181f83f9bca4d659477702d695af6e7b0cd))
|
|
13
|
+
* Immediate replication mode for loader and ability to bootstrap stories faster ([43967ec](https://github.com/Quenty/NevermoreEngine/commit/43967ecf3947241138dd3a44ba23ffe05de6d2b0))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
6
19
|
# [10.2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/loader@10.1.0...@quenty/loader@10.2.0) (2024-04-27)
|
|
7
20
|
|
|
8
21
|
**Note:** Version bump only for package @quenty/loader
|
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.3.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": "3fd5cdca3128bf34c8d9dfae1e92d62533b6e6f5"
|
|
30
30
|
}
|
|
@@ -427,7 +427,7 @@ function PackageTracker:_tryStorePackage(fullPackageName, packageInst)
|
|
|
427
427
|
return function()
|
|
428
428
|
local index = table.find(self._subpackagesTrackerList, packageTracker)
|
|
429
429
|
if index then
|
|
430
|
-
table.remove(self._subpackagesTrackerList,
|
|
430
|
+
table.remove(self._subpackagesTrackerList, index)
|
|
431
431
|
end
|
|
432
432
|
|
|
433
433
|
if self._subpackagesMap[fullPackageName] == packageInst then
|
|
@@ -22,4 +22,9 @@ local function waitForValue(objectValue)
|
|
|
22
22
|
return objectValue.Changed:Wait()
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
local loader = waitForValue(script:WaitForChild("LoaderLink"))
|
|
26
|
+
if not loader:IsDescendantOf(game) then
|
|
27
|
+
error("Cannot load loader that is unparented from game")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
return require(loader)
|
|
@@ -29,9 +29,29 @@ function LoaderLinkCreator.new(root, references, isRoot)
|
|
|
29
29
|
self._hasLoaderCount = self._maid:Add(Instance.new("IntValue"))
|
|
30
30
|
self._hasLoaderCount.Value = 0
|
|
31
31
|
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
32
|
+
self._provideLoader = self._maid:Add(Instance.new("BoolValue"))
|
|
33
|
+
self._provideLoader.Value = false
|
|
34
34
|
|
|
35
|
+
-- prevent frame delay
|
|
36
|
+
self:_setupEventTracking()
|
|
37
|
+
self:_setupRendering()
|
|
38
|
+
|
|
39
|
+
return self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
function LoaderLinkCreator:_setupEventTracking()
|
|
43
|
+
self._maid:GiveTask(self._root.ChildAdded:Connect(function(child)
|
|
44
|
+
self:_handleChildAdded(child)
|
|
45
|
+
end))
|
|
46
|
+
self._maid:GiveTask(self._root.ChildRemoved:Connect(function(child)
|
|
47
|
+
self:_handleChildRemoved(child)
|
|
48
|
+
end))
|
|
49
|
+
|
|
50
|
+
for _, child in pairs(self._root:GetChildren()) do
|
|
51
|
+
self:_handleChildAdded(child)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
-- Need to do this AFTER child added loop
|
|
35
55
|
if self._references then
|
|
36
56
|
self._maid:GiveTask(self._references:ObserveReferenceChanged(loader, function(replicatedLoader)
|
|
37
57
|
if replicatedLoader and replicatedLoader ~= loader then
|
|
@@ -40,52 +60,49 @@ function LoaderLinkCreator.new(root, references, isRoot)
|
|
|
40
60
|
self._maid._trackFakeLoader = nil
|
|
41
61
|
end
|
|
42
62
|
end))
|
|
63
|
+
else
|
|
64
|
+
self._maid:GiveTask(self:_countLoaderReferences(loader))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
-- Update state
|
|
68
|
+
self._maid:GiveTask(self._childRequiresLoaderCount.Changed:Connect(function()
|
|
69
|
+
self:_updateProviderLoader()
|
|
70
|
+
end))
|
|
71
|
+
self._maid:GiveTask(self._hasLoaderCount.Changed:Connect(function()
|
|
72
|
+
self:_updateProviderLoader()
|
|
73
|
+
end))
|
|
74
|
+
self:_updateProviderLoader()
|
|
75
|
+
end
|
|
43
76
|
|
|
44
|
-
|
|
45
|
-
|
|
77
|
+
function LoaderLinkCreator:_setupRendering()
|
|
78
|
+
if self._references then
|
|
79
|
+
local function renderLoader()
|
|
80
|
+
if self._provideLoader.Value then
|
|
46
81
|
self._maid._loader = self:_renderLoaderWithReferences()
|
|
47
82
|
else
|
|
48
83
|
self._maid._loader = nil
|
|
49
84
|
end
|
|
50
|
-
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
self._maid:GiveTask(self._provideLoader.Changed:Connect(renderLoader))
|
|
88
|
+
renderLoader()
|
|
51
89
|
else
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if self._needsLoader.Value then
|
|
90
|
+
local function renderLoader()
|
|
91
|
+
if self._provideLoader.Value then
|
|
55
92
|
self._maid._loader = self:_doLoaderRender(loader)
|
|
56
93
|
else
|
|
57
94
|
self._maid._loader = nil
|
|
58
95
|
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
self._maid:GiveTask(self:_countLoaderReferences(loader))
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
-- Update state
|
|
65
|
-
self._maid:GiveTask(self._childRequiresLoaderCount.Changed:Connect(function()
|
|
66
|
-
self:_updateNeedsLoader()
|
|
67
|
-
end))
|
|
68
|
-
self._maid:GiveTask(self._hasLoaderCount.Changed:Connect(function()
|
|
69
|
-
self:_updateNeedsLoader()
|
|
70
|
-
end))
|
|
71
|
-
self:_updateNeedsLoader()
|
|
96
|
+
end
|
|
72
97
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
end))
|
|
77
|
-
self._maid:GiveTask(self._root.ChildRemoved:Connect(function(child)
|
|
78
|
-
self:_handleChildRemoved(child)
|
|
79
|
-
end))
|
|
80
|
-
for _, child in pairs(self._root:GetChildren()) do
|
|
81
|
-
self:_handleChildAdded(child)
|
|
98
|
+
-- No references, just render as needed
|
|
99
|
+
self._maid:GiveTask(self._provideLoader.Changed:Connect(renderLoader))
|
|
100
|
+
renderLoader()
|
|
82
101
|
end
|
|
83
|
-
|
|
84
|
-
return self
|
|
85
102
|
end
|
|
86
103
|
|
|
87
|
-
function LoaderLinkCreator:
|
|
88
|
-
self.
|
|
104
|
+
function LoaderLinkCreator:_updateProviderLoader()
|
|
105
|
+
self._provideLoader.Value = (self._childRequiresLoaderCount.Value > 0) and self._hasLoaderCount.Value <= 0
|
|
89
106
|
end
|
|
90
107
|
|
|
91
108
|
function LoaderLinkCreator:_handleChildRemoved(child)
|
|
@@ -96,7 +113,13 @@ function LoaderLinkCreator:_handleChildAdded(child)
|
|
|
96
113
|
assert(typeof(child) == "Instance", "Bad child")
|
|
97
114
|
|
|
98
115
|
if child:IsA("ModuleScript") then
|
|
99
|
-
|
|
116
|
+
if child.Name ~= "loader" then
|
|
117
|
+
self._maid[child] = self:_incrementNeededLoader(1)
|
|
118
|
+
else
|
|
119
|
+
if child ~= self._lastProvidedLoader then
|
|
120
|
+
self._maid[child] = self:_addToHasLoaderCount(1)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
100
123
|
elseif child:IsA("Folder") then
|
|
101
124
|
-- TODO: Maybe add to children with node_modules explicitly in its list.
|
|
102
125
|
self._maid[child] = LoaderLinkCreator.new(child, self._references)
|
|
@@ -119,8 +142,11 @@ end
|
|
|
119
142
|
|
|
120
143
|
function LoaderLinkCreator:_doLoaderRender(value)
|
|
121
144
|
local loaderLink = LoaderLinkUtils.create(value, loader.Name)
|
|
145
|
+
self._lastProvidedLoader = loaderLink
|
|
146
|
+
|
|
122
147
|
loaderLink.Parent = self._root
|
|
123
148
|
|
|
149
|
+
|
|
124
150
|
return loaderLink
|
|
125
151
|
end
|
|
126
152
|
|
|
@@ -133,7 +159,7 @@ function LoaderLinkCreator:_incrementNeededLoader(amount)
|
|
|
133
159
|
end
|
|
134
160
|
end
|
|
135
161
|
|
|
136
|
-
function LoaderLinkCreator:
|
|
162
|
+
function LoaderLinkCreator:_addToHasLoaderCount(amount)
|
|
137
163
|
assert(type(amount) == "number", "Bad amount")
|
|
138
164
|
|
|
139
165
|
self._hasLoaderCount.Value = self._hasLoaderCount.Value + amount
|
|
@@ -149,12 +175,12 @@ function LoaderLinkCreator:_countLoaderReferences(robloxInst)
|
|
|
149
175
|
|
|
150
176
|
-- TODO: Maybe handle loader reparenting more elegantly? this seems deeply unlikely.
|
|
151
177
|
if robloxInst.Parent == self._root then
|
|
152
|
-
maid._current = self:
|
|
178
|
+
maid._current = self:_addToHasLoaderCount(1)
|
|
153
179
|
end
|
|
154
180
|
|
|
155
181
|
maid:GiveTask(robloxInst:GetPropertyChangedSignal("Parent"):Connect(function()
|
|
156
182
|
if robloxInst.Parent == self._root then
|
|
157
|
-
maid._current = self:
|
|
183
|
+
maid._current = self:_addToHasLoaderCount(1)
|
|
158
184
|
else
|
|
159
185
|
maid._current = nil
|
|
160
186
|
end
|
|
@@ -48,6 +48,10 @@ function ReplicatorReferences:UnsetReference(orig, replicated)
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
function ReplicatorReferences:GetReference(orig)
|
|
52
|
+
return self._lookup[orig]
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
function ReplicatorReferences:_fireSubs(orig, newValue)
|
|
52
56
|
assert(typeof(orig) == "Instance", "Bad orig")
|
|
53
57
|
|
package/src/init.lua
CHANGED
|
@@ -55,10 +55,6 @@ function Loader.bootstrapGame(packages)
|
|
|
55
55
|
|
|
56
56
|
GLOBAL_PACKAGE_TRACKER:AddPackageRoot(packages)
|
|
57
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
58
|
return self
|
|
63
59
|
end
|
|
64
60
|
|
|
@@ -71,9 +67,25 @@ function Loader.bootstrapPlugin(packages)
|
|
|
71
67
|
|
|
72
68
|
GLOBAL_PACKAGE_TRACKER:AddPackageRoot(packages)
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
return self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
function Loader.bootstrapStory(storyScript)
|
|
74
|
+
assert(typeof(storyScript) == "Instance", "Bad storyScript")
|
|
75
|
+
|
|
76
|
+
-- Prepopulate global package roots
|
|
77
|
+
local topNodeModule = storyScript
|
|
78
|
+
for node_modules in DependencyUtils.iterNodeModules(storyScript) do
|
|
79
|
+
if not node_modules:IsDescendantOf(topNodeModule) then
|
|
80
|
+
topNodeModule = node_modules
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
local self = Loader.new(topNodeModule.Parent, ReplicationType.PLUGIN)
|
|
85
|
+
|
|
86
|
+
self:_setupLoaderPopulation()
|
|
87
|
+
|
|
88
|
+
GLOBAL_PACKAGE_TRACKER:AddPackageRoot(topNodeModule.Parent)
|
|
77
89
|
|
|
78
90
|
return self
|
|
79
91
|
end
|
|
@@ -103,15 +115,6 @@ function Loader:__call(request)
|
|
|
103
115
|
end
|
|
104
116
|
end
|
|
105
117
|
|
|
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
118
|
function Loader:_findDependency(request)
|
|
116
119
|
assert(type(request) == "string", "Bad request")
|
|
117
120
|
|
|
@@ -141,9 +144,7 @@ function Loader:_findDependency(request)
|
|
|
141
144
|
-- Just standard dependency search
|
|
142
145
|
local foundBackup = DependencyUtils.findDependency(self._packages, request, self._replicationType)
|
|
143
146
|
if foundBackup then
|
|
144
|
-
|
|
145
|
-
warn(string.format("[Loader] - Failed to find package %q in package tracker\n%s", request, debug.traceback()))
|
|
146
|
-
end
|
|
147
|
+
warn(string.format("[Loader] - Failed to find package %q in package tracker\n%s", request, debug.traceback()))
|
|
147
148
|
|
|
148
149
|
-- Ensure hoarcekat story has a link to use
|
|
149
150
|
-- TODO: Maybe add to global package cache instead...
|