@quenty/datastore 13.35.0 → 13.36.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
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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
|
+
# [13.36.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/datastore@13.35.0...@quenty/datastore@13.36.0) (2026-04-15)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* wait for data cleanup before attempting load ([#678](https://github.com/Quenty/NevermoreEngine/issues/678)) ([80adc48](https://github.com/Quenty/NevermoreEngine/commit/80adc48669603d9a30f1bb4aa8c45d09e995ada6))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [13.35.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/datastore@13.34.0...@quenty/datastore@13.35.0) (2026-04-14)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/datastore
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/datastore",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.36.0",
|
|
4
4
|
"description": "Quenty's Datastore implementation for Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "da500f4af908cef350ee386cf472a102e8e53437"
|
|
54
54
|
}
|
|
@@ -78,6 +78,7 @@ export type PlayerDataStoreManager =
|
|
|
78
78
|
_keyGenerator: KeyGenerator,
|
|
79
79
|
_datastores: { [PlayerUserId]: DataStore.DataStore },
|
|
80
80
|
_removing: { [PlayerUserId]: boolean },
|
|
81
|
+
_removingPromises: { [PlayerUserId]: Promise.Promise<any> },
|
|
81
82
|
_pendingSaves: PendingPromiseTracker.PendingPromiseTracker<any>,
|
|
82
83
|
_removingCallbacks: { RemovingCallback },
|
|
83
84
|
_disableSavingInStudio: boolean?,
|
|
@@ -112,6 +113,7 @@ function PlayerDataStoreManager.new(
|
|
|
112
113
|
|
|
113
114
|
self._datastores = {} -- [userId] = datastore
|
|
114
115
|
self._removing = {} -- [player] = true
|
|
116
|
+
self._removingPromises = {} -- [player] = removal promise
|
|
115
117
|
self._pendingSaves = PendingPromiseTracker.new()
|
|
116
118
|
self._removingCallbacks = {} -- [func, ...]
|
|
117
119
|
|
|
@@ -194,6 +196,67 @@ function PlayerDataStoreManager.GetDataStore(
|
|
|
194
196
|
return self:_createDataStore(userId)
|
|
195
197
|
end
|
|
196
198
|
|
|
199
|
+
--[=[
|
|
200
|
+
Gets the datastore for a player, waiting for any in-progress removal/save first.
|
|
201
|
+
Use this in async flows to safely support fast leave/rejoin behavior.
|
|
202
|
+
|
|
203
|
+
@return Promise<DataStore>
|
|
204
|
+
]=]
|
|
205
|
+
function PlayerDataStoreManager.PromiseDataStore(
|
|
206
|
+
self: PlayerDataStoreManager,
|
|
207
|
+
playerOrUserId: Player | PlayerUserId
|
|
208
|
+
): Promise.Promise<DataStore.DataStore>
|
|
209
|
+
local userId = self:_toPlayerUserIdOrError(playerOrUserId)
|
|
210
|
+
|
|
211
|
+
return self:_promiseDataStoreByUserId(userId)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
function PlayerDataStoreManager._promiseDataStoreByUserId(
|
|
215
|
+
self: PlayerDataStoreManager,
|
|
216
|
+
userId: PlayerUserId
|
|
217
|
+
): Promise.Promise<DataStore.DataStore>
|
|
218
|
+
local dataStore = self:GetDataStore(userId)
|
|
219
|
+
if dataStore then
|
|
220
|
+
return Promise.resolved(dataStore)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
return self:_promiseWaitForRemoving(userId):Then(function()
|
|
224
|
+
return self:_promiseDataStoreByUserId(userId)
|
|
225
|
+
end)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
function PlayerDataStoreManager._promiseWaitForRemoving(
|
|
229
|
+
self: PlayerDataStoreManager,
|
|
230
|
+
userId: PlayerUserId
|
|
231
|
+
): Promise.Promise<()>
|
|
232
|
+
local removingPromise = self._removingPromises[userId]
|
|
233
|
+
if removingPromise then
|
|
234
|
+
return removingPromise:Then(function()
|
|
235
|
+
return nil
|
|
236
|
+
end)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
if self._removing[userId] then
|
|
240
|
+
return Promise.defer(function(resolve, reject)
|
|
241
|
+
local elapsed = 0
|
|
242
|
+
while self._removing[userId] do
|
|
243
|
+
elapsed += task.wait()
|
|
244
|
+
|
|
245
|
+
if elapsed >= 15 then
|
|
246
|
+
warn(
|
|
247
|
+
`[PlayerDataStoreManager] - Last session cleanup for {userId} taking longer than 15 seconds. Rejecting.`
|
|
248
|
+
)
|
|
249
|
+
reject()
|
|
250
|
+
break
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
resolve()
|
|
254
|
+
end)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
return Promise.resolved()
|
|
258
|
+
end
|
|
259
|
+
|
|
197
260
|
function PlayerDataStoreManager:_toPlayerUserIdOrError(playerOrUserId: Player | PlayerUserId): PlayerUserId
|
|
198
261
|
if typeof(playerOrUserId) == "Instance" and playerOrUserId:IsA("Player") then
|
|
199
262
|
return playerOrUserId.UserId
|
|
@@ -286,7 +349,7 @@ function PlayerDataStoreManager._removePlayerDataStore(self: PlayerDataStoreMana
|
|
|
286
349
|
end
|
|
287
350
|
end
|
|
288
351
|
|
|
289
|
-
PromiseUtils.all(removingPromises)
|
|
352
|
+
local removalPromise = PromiseUtils.all(removingPromises)
|
|
290
353
|
:Then(function()
|
|
291
354
|
return datastore:SaveAndCloseSession()
|
|
292
355
|
end)
|
|
@@ -295,6 +358,13 @@ function PlayerDataStoreManager._removePlayerDataStore(self: PlayerDataStoreMana
|
|
|
295
358
|
self._removing[userId] = nil
|
|
296
359
|
end)
|
|
297
360
|
|
|
361
|
+
self._removingPromises[userId] = removalPromise
|
|
362
|
+
removalPromise:Finally(function()
|
|
363
|
+
if self._removingPromises[userId] == removalPromise then
|
|
364
|
+
self._removingPromises[userId] = nil
|
|
365
|
+
end
|
|
366
|
+
end)
|
|
367
|
+
|
|
298
368
|
-- Prevent double removal or additional issues
|
|
299
369
|
self._datastores[userId] = nil
|
|
300
370
|
self._maid._savingConns[userId] = nil
|
|
@@ -107,7 +107,7 @@ function PlayerDataStoreService.PromiseDataStore(
|
|
|
107
107
|
player: Player | number
|
|
108
108
|
): Promise.Promise<DataStore.DataStore>
|
|
109
109
|
return self:PromiseManager():Then(function(manager)
|
|
110
|
-
return manager:
|
|
110
|
+
return manager:PromiseDataStore(player)
|
|
111
111
|
end)
|
|
112
112
|
end
|
|
113
113
|
|