@quenty/settings 11.60.0 → 11.62.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 +10 -0
- package/package.json +29 -28
- package/src/Client/SettingsServiceClient.lua +9 -8
- package/src/Shared/Player/PlayerSettingsBase.lua +4 -1
- package/src/Shared/Setting/SettingDefinition.lua +8 -3
- package/src/Shared/Setting/SettingProperty.lua +31 -10
- package/src/Shared/SettingsDataService.lua +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
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
|
+
# [11.62.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.61.0...@quenty/settings@11.62.0) (2026-07-23)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- Add baseline player-mock and support across Nevermore for mocked players. ([567d121](https://github.com/Quenty/NevermoreEngine/commit/567d121ffc014b42391554088189a1a6296dda83))
|
|
11
|
+
|
|
12
|
+
# [11.61.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.60.0...@quenty/settings@11.61.0) (2026-07-22)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @quenty/settings
|
|
15
|
+
|
|
6
16
|
# [11.60.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/settings@11.59.0...@quenty/settings@11.60.0) (2026-07-21)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @quenty/settings
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/settings",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.62.0",
|
|
4
4
|
"description": "Centralized player settings service",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,42 +28,43 @@
|
|
|
28
28
|
"Quenty"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@quenty/attributeutils": "14.
|
|
32
|
-
"@quenty/baseobject": "10.
|
|
33
|
-
"@quenty/binder": "14.
|
|
34
|
-
"@quenty/brio": "14.
|
|
35
|
-
"@quenty/canceltoken": "11.
|
|
36
|
-
"@quenty/cmdrservice": "13.
|
|
37
|
-
"@quenty/datastore": "13.
|
|
31
|
+
"@quenty/attributeutils": "14.33.0",
|
|
32
|
+
"@quenty/baseobject": "10.15.0",
|
|
33
|
+
"@quenty/binder": "14.41.0",
|
|
34
|
+
"@quenty/brio": "14.33.0",
|
|
35
|
+
"@quenty/canceltoken": "11.22.0",
|
|
36
|
+
"@quenty/cmdrservice": "13.51.0",
|
|
37
|
+
"@quenty/datastore": "13.46.0",
|
|
38
38
|
"@quenty/ducktype": "5.11.0",
|
|
39
39
|
"@quenty/enumutils": "3.4.6",
|
|
40
|
-
"@quenty/instanceutils": "13.
|
|
41
|
-
"@quenty/jsonutils": "10.
|
|
40
|
+
"@quenty/instanceutils": "13.33.0",
|
|
41
|
+
"@quenty/jsonutils": "10.21.0",
|
|
42
42
|
"@quenty/loader": "10.11.0",
|
|
43
|
-
"@quenty/maid": "3.
|
|
44
|
-
"@quenty/nevermore-test-runner": "1.
|
|
45
|
-
"@quenty/observablecollection": "12.
|
|
46
|
-
"@quenty/playerbinder": "14.
|
|
47
|
-
"@quenty/
|
|
48
|
-
"@quenty/
|
|
49
|
-
"@quenty/
|
|
50
|
-
"@quenty/
|
|
51
|
-
"@quenty/
|
|
52
|
-
"@quenty/
|
|
53
|
-
"@quenty/
|
|
54
|
-
"@quenty/
|
|
43
|
+
"@quenty/maid": "3.11.0",
|
|
44
|
+
"@quenty/nevermore-test-runner": "1.5.0",
|
|
45
|
+
"@quenty/observablecollection": "12.42.0",
|
|
46
|
+
"@quenty/playerbinder": "14.41.0",
|
|
47
|
+
"@quenty/playermock": "1.1.0",
|
|
48
|
+
"@quenty/playerutils": "8.36.0",
|
|
49
|
+
"@quenty/promise": "10.21.0",
|
|
50
|
+
"@quenty/remotefunctionutils": "10.21.0",
|
|
51
|
+
"@quenty/remoting": "12.36.0",
|
|
52
|
+
"@quenty/rx": "13.31.0",
|
|
53
|
+
"@quenty/rxbinderutils": "14.41.0",
|
|
54
|
+
"@quenty/rxsignal": "7.31.0",
|
|
55
|
+
"@quenty/servicebag": "11.20.0",
|
|
55
56
|
"@quenty/signal": "7.13.1",
|
|
56
|
-
"@quenty/statestack": "14.
|
|
57
|
-
"@quenty/string": "3.
|
|
57
|
+
"@quenty/statestack": "14.35.0",
|
|
58
|
+
"@quenty/string": "3.4.0",
|
|
58
59
|
"@quenty/symbol": "3.5.2",
|
|
59
60
|
"@quenty/table": "3.9.2",
|
|
60
|
-
"@quenty/throttle": "10.
|
|
61
|
-
"@quenty/tie": "10.
|
|
62
|
-
"@quenty/valueobject": "13.
|
|
61
|
+
"@quenty/throttle": "10.14.0",
|
|
62
|
+
"@quenty/tie": "10.44.0",
|
|
63
|
+
"@quenty/valueobject": "13.34.0",
|
|
63
64
|
"@quentystudios/jest-lua": "3.10.0-quenty.2"
|
|
64
65
|
},
|
|
65
66
|
"publishConfig": {
|
|
66
67
|
"access": "public"
|
|
67
68
|
},
|
|
68
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "1de37218a2bedb8e3f8614a2e09bba9eddc812da"
|
|
69
70
|
}
|
|
@@ -15,6 +15,7 @@ local Brio = require("Brio")
|
|
|
15
15
|
local CancelToken = require("CancelToken")
|
|
16
16
|
local Maid = require("Maid")
|
|
17
17
|
local Observable = require("Observable")
|
|
18
|
+
local PlayerMock = require("PlayerMock")
|
|
18
19
|
local PlayerSettingsClient = require("PlayerSettingsClient")
|
|
19
20
|
local Promise = require("Promise")
|
|
20
21
|
local ServiceBag = require("ServiceBag")
|
|
@@ -62,7 +63,7 @@ end
|
|
|
62
63
|
function SettingsServiceClient.GetLocalPlayerSettings(
|
|
63
64
|
self: SettingsServiceClient
|
|
64
65
|
): PlayerSettingsClient.PlayerSettingsClient?
|
|
65
|
-
return self:GetPlayerSettings(Players.LocalPlayer)
|
|
66
|
+
return self:GetPlayerSettings(Players.LocalPlayer or PlayerMock.getMockedLocalPlayer())
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
--[=[
|
|
@@ -73,7 +74,7 @@ end
|
|
|
73
74
|
function SettingsServiceClient.ObserveLocalPlayerSettingsBrio(self: SettingsServiceClient): Observable.Observable<
|
|
74
75
|
Brio.Brio<PlayerSettingsClient.PlayerSettingsClient>
|
|
75
76
|
>
|
|
76
|
-
return self:ObservePlayerSettingsBrio(Players.LocalPlayer)
|
|
77
|
+
return self:ObservePlayerSettingsBrio(Players.LocalPlayer or PlayerMock.getMockedLocalPlayer())
|
|
77
78
|
end
|
|
78
79
|
|
|
79
80
|
--[=[
|
|
@@ -84,7 +85,7 @@ end
|
|
|
84
85
|
function SettingsServiceClient.ObserveLocalPlayerSettings(self: SettingsServiceClient): Observable.Observable<
|
|
85
86
|
PlayerSettingsClient.PlayerSettingsClient
|
|
86
87
|
>
|
|
87
|
-
return self:ObservePlayerSettings(Players.LocalPlayer)
|
|
88
|
+
return self:ObservePlayerSettings(Players.LocalPlayer or PlayerMock.getMockedLocalPlayer())
|
|
88
89
|
end
|
|
89
90
|
|
|
90
91
|
--[=[
|
|
@@ -97,7 +98,7 @@ function SettingsServiceClient.PromiseLocalPlayerSettings(
|
|
|
97
98
|
self: SettingsServiceClient,
|
|
98
99
|
cancelToken: CancelToken.CancelToken
|
|
99
100
|
): Promise.Promise<PlayerSettingsClient.PlayerSettingsClient>
|
|
100
|
-
return self:PromisePlayerSettings(Players.LocalPlayer, cancelToken)
|
|
101
|
+
return self:PromisePlayerSettings(Players.LocalPlayer or PlayerMock.getMockedLocalPlayer(), cancelToken)
|
|
101
102
|
end
|
|
102
103
|
|
|
103
104
|
--[=[
|
|
@@ -110,7 +111,7 @@ function SettingsServiceClient.ObservePlayerSettings(
|
|
|
110
111
|
self: SettingsServiceClient,
|
|
111
112
|
player: Player
|
|
112
113
|
): Observable.Observable<PlayerSettingsClient.PlayerSettingsClient>
|
|
113
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
114
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
114
115
|
|
|
115
116
|
return self._settingsDataService:ObservePlayerSettings(player)
|
|
116
117
|
end
|
|
@@ -127,7 +128,7 @@ function SettingsServiceClient.ObservePlayerSettingsBrio(
|
|
|
127
128
|
): Observable.Observable<
|
|
128
129
|
Brio.Brio<PlayerSettingsClient.PlayerSettingsClient>
|
|
129
130
|
>
|
|
130
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
131
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
131
132
|
|
|
132
133
|
return self._settingsDataService:ObservePlayerSettingsBrio(player)
|
|
133
134
|
end
|
|
@@ -142,7 +143,7 @@ function SettingsServiceClient.GetPlayerSettings(
|
|
|
142
143
|
self: SettingsServiceClient,
|
|
143
144
|
player: Player
|
|
144
145
|
): PlayerSettingsClient.PlayerSettingsClient?
|
|
145
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
146
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
146
147
|
|
|
147
148
|
return self._settingsDataService:GetPlayerSettings(player)
|
|
148
149
|
end
|
|
@@ -159,7 +160,7 @@ function SettingsServiceClient.PromisePlayerSettings(
|
|
|
159
160
|
player: Player,
|
|
160
161
|
cancelToken: CancelToken.CancelToken
|
|
161
162
|
): Promise.Promise<PlayerSettingsClient.PlayerSettingsClient>
|
|
162
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
163
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
163
164
|
|
|
164
165
|
return self._settingsDataService:PromisePlayerSettings(player, cancelToken)
|
|
165
166
|
end
|
|
@@ -10,6 +10,7 @@ local require = require(script.Parent.loader).load(script)
|
|
|
10
10
|
local BaseObject = require("BaseObject")
|
|
11
11
|
local DataStoreStringUtils = require("DataStoreStringUtils")
|
|
12
12
|
local Observable = require("Observable")
|
|
13
|
+
local PlayerMock = require("PlayerMock")
|
|
13
14
|
local PlayerSettingsUtils = require("PlayerSettingsUtils")
|
|
14
15
|
local Rx = require("Rx")
|
|
15
16
|
local RxAttributeUtils = require("RxAttributeUtils")
|
|
@@ -51,7 +52,9 @@ end
|
|
|
51
52
|
@return Player
|
|
52
53
|
]=]
|
|
53
54
|
function PlayerSettingsBase.GetPlayer(self: PlayerSettingsBase): Player?
|
|
54
|
-
|
|
55
|
+
-- The real Player ancestor, or the PlayerMock a test parented the settings folder under
|
|
56
|
+
-- (a mock's backing Folder is invisible to the IsA walk).
|
|
57
|
+
return self._obj:FindFirstAncestorWhichIsA("Player") or PlayerMock.findFirstAncestorMock(self._obj)
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
--[=[
|
|
@@ -26,6 +26,7 @@ local Players = game:GetService("Players")
|
|
|
26
26
|
local DuckTypeUtils = require("DuckTypeUtils")
|
|
27
27
|
local Maid = require("Maid")
|
|
28
28
|
local Observable = require("Observable")
|
|
29
|
+
local PlayerMock = require("PlayerMock")
|
|
29
30
|
local Promise = require("Promise")
|
|
30
31
|
local ServiceBag = require("ServiceBag")
|
|
31
32
|
local SettingProperty = require("SettingProperty")
|
|
@@ -175,9 +176,13 @@ function SettingDefinition.GetSettingProperty<T>(
|
|
|
175
176
|
player: Player
|
|
176
177
|
): SettingProperty.SettingProperty<T>
|
|
177
178
|
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
178
|
-
assert(
|
|
179
|
+
assert(
|
|
180
|
+
typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)) or player == nil,
|
|
181
|
+
"Bad player"
|
|
182
|
+
)
|
|
179
183
|
|
|
180
|
-
|
|
184
|
+
-- May still be nil in a non-running DataModel; SettingProperty resolves the local player lazily.
|
|
185
|
+
player = player or Players.LocalPlayer or PlayerMock.getMockedLocalPlayer()
|
|
181
186
|
|
|
182
187
|
return SettingProperty.new(serviceBag, player, self)
|
|
183
188
|
end
|
|
@@ -194,7 +199,7 @@ function SettingDefinition.GetLocalPlayerSettingProperty<T>(
|
|
|
194
199
|
): SettingProperty.SettingProperty<T>
|
|
195
200
|
assert(ServiceBag.isServiceBag(serviceBag), "Bad serviceBag")
|
|
196
201
|
|
|
197
|
-
return self:GetSettingProperty(serviceBag, Players.LocalPlayer)
|
|
202
|
+
return self:GetSettingProperty(serviceBag, Players.LocalPlayer or PlayerMock.getMockedLocalPlayer())
|
|
198
203
|
end
|
|
199
204
|
|
|
200
205
|
--[=[
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
+
local Players = game:GetService("Players")
|
|
9
|
+
|
|
8
10
|
local Observable = require("Observable")
|
|
11
|
+
local PlayerMock = require("PlayerMock")
|
|
9
12
|
local Promise = require("Promise")
|
|
10
13
|
local Rx = require("Rx")
|
|
11
14
|
local RxSignal = require("RxSignal")
|
|
@@ -24,7 +27,7 @@ export type SettingProperty<T> = typeof(setmetatable(
|
|
|
24
27
|
|
|
25
28
|
_serviceBag: ServiceBag.ServiceBag,
|
|
26
29
|
_bridge: SettingsDataService.SettingsDataService,
|
|
27
|
-
_player: Player
|
|
30
|
+
_player: Player?,
|
|
28
31
|
_definition: any,
|
|
29
32
|
},
|
|
30
33
|
{} :: typeof({ __index = SettingProperty })
|
|
@@ -33,23 +36,33 @@ export type SettingProperty<T> = typeof(setmetatable(
|
|
|
33
36
|
--[=[
|
|
34
37
|
Constructs a new SettingProperty.
|
|
35
38
|
|
|
39
|
+
A nil player means the local player: the real `Players.LocalPlayer`, or the mock a test has
|
|
40
|
+
already designated through [PlayerMock.setMockedLocalPlayer]. Designation may happen before
|
|
41
|
+
bags boot -- matching production, where `Players.LocalPlayer` exists before any service runs --
|
|
42
|
+
so construction requires a resolvable local player up front.
|
|
43
|
+
|
|
36
44
|
@param serviceBag ServiceBag
|
|
37
|
-
@param player Player
|
|
45
|
+
@param player Player?
|
|
38
46
|
@param definition SettingDefinition
|
|
39
47
|
@return SettingProperty<T>
|
|
40
48
|
]=]
|
|
41
|
-
function SettingProperty.new<T>(serviceBag: ServiceBag.ServiceBag, player: Player
|
|
49
|
+
function SettingProperty.new<T>(serviceBag: ServiceBag.ServiceBag, player: Player?, definition): SettingProperty<T>
|
|
42
50
|
local self: SettingProperty<T> = setmetatable({} :: any, SettingProperty)
|
|
43
51
|
|
|
44
52
|
self._serviceBag = assert(serviceBag, "No serviceBag")
|
|
45
53
|
self._bridge = self._serviceBag:GetService(SettingsDataService) :: any
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
assert(player ~= nil or Players.LocalPlayer ~= nil or PlayerMock.getMockedLocalPlayer() ~= nil, "No player")
|
|
56
|
+
if player ~= nil then
|
|
57
|
+
self._player = player
|
|
58
|
+
end
|
|
48
59
|
self._definition = assert(definition, "No definition")
|
|
49
60
|
|
|
50
|
-
self:
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
if self:_findPlayer() ~= nil then
|
|
62
|
+
self:_promisePlayerSettings():Then(function(playerSettings)
|
|
63
|
+
playerSettings:EnsureInitialized(self._definition:GetSettingName(), self._definition:GetDefaultValue())
|
|
64
|
+
end)
|
|
65
|
+
end
|
|
53
66
|
|
|
54
67
|
return self
|
|
55
68
|
end
|
|
@@ -191,16 +204,24 @@ function SettingProperty.PromiseRestoreDefault<T>(self: SettingProperty<T>): Pro
|
|
|
191
204
|
end)
|
|
192
205
|
end
|
|
193
206
|
|
|
207
|
+
function SettingProperty._findPlayer<T>(self: SettingProperty<T>): Player?
|
|
208
|
+
return rawget(self :: any, "_player") or Players.LocalPlayer or PlayerMock.getMockedLocalPlayer()
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
function SettingProperty._resolvePlayer<T>(self: SettingProperty<T>): Player
|
|
212
|
+
return assert(self:_findPlayer(), "No player") :: Player
|
|
213
|
+
end
|
|
214
|
+
|
|
194
215
|
function SettingProperty._observePlayerSettings<T>(self: SettingProperty<T>)
|
|
195
|
-
return self._bridge:ObservePlayerSettings(self
|
|
216
|
+
return self._bridge:ObservePlayerSettings(self:_resolvePlayer())
|
|
196
217
|
end
|
|
197
218
|
|
|
198
219
|
function SettingProperty._getPlayerSettings<T>(self: SettingProperty<T>)
|
|
199
|
-
return self._bridge:GetPlayerSettings(self
|
|
220
|
+
return self._bridge:GetPlayerSettings(self:_resolvePlayer())
|
|
200
221
|
end
|
|
201
222
|
|
|
202
223
|
function SettingProperty._promisePlayerSettings<T>(self: SettingProperty<T>)
|
|
203
|
-
return self._bridge:PromisePlayerSettings(self
|
|
224
|
+
return self._bridge:PromisePlayerSettings(self:_resolvePlayer())
|
|
204
225
|
end
|
|
205
226
|
|
|
206
227
|
return SettingProperty
|
|
@@ -14,6 +14,7 @@ local Maid = require("Maid")
|
|
|
14
14
|
local Observable = require("Observable")
|
|
15
15
|
local ObservableMap = require("ObservableMap")
|
|
16
16
|
local ObservableSet = require("ObservableSet")
|
|
17
|
+
local PlayerMock = require("PlayerMock")
|
|
17
18
|
local PlayerSettingsInterface = require("PlayerSettingsInterface")
|
|
18
19
|
local Promise = require("Promise")
|
|
19
20
|
local Rx = require("Rx")
|
|
@@ -154,7 +155,7 @@ function SettingsDataService.ObservePlayerSettings(
|
|
|
154
155
|
self: SettingsDataService,
|
|
155
156
|
player: Player
|
|
156
157
|
): Observable.Observable<any>
|
|
157
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
158
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
158
159
|
|
|
159
160
|
return (self:_getPlayerSettingsMapForPlayer(player) :: any):ObserveAtKey(
|
|
160
161
|
player,
|
|
@@ -190,7 +191,7 @@ function SettingsDataService.PromisePlayerSettings(
|
|
|
190
191
|
player: Player,
|
|
191
192
|
cancelToken: any
|
|
192
193
|
): Promise.Promise<any>
|
|
193
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
194
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
194
195
|
|
|
195
196
|
return Rx.toPromise(
|
|
196
197
|
(self:ObservePlayerSettings(player) :: any):Pipe({
|
|
@@ -209,7 +210,7 @@ end
|
|
|
209
210
|
@return Promise<PlayerSettingsBase>
|
|
210
211
|
]=]
|
|
211
212
|
function SettingsDataService.GetPlayerSettings(self: SettingsDataService, player: Player): any
|
|
212
|
-
assert(typeof(player) == "Instance" and player:IsA("Player"), "Bad player")
|
|
213
|
+
assert(typeof(player) == "Instance" and (player:IsA("Player") or PlayerMock.isMock(player)), "Bad player")
|
|
213
214
|
|
|
214
215
|
return self:_getPlayerSettingsMapForPlayer(player):Get(player)
|
|
215
216
|
end
|