@quenty/datastore 13.20.0 → 13.20.1

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.20.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/datastore@13.20.0...@quenty/datastore@13.20.1) (2025-04-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
12
+
13
+
14
+
15
+
16
+
6
17
  # [13.20.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/datastore@13.19.3...@quenty/datastore@13.20.0) (2025-04-02)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/datastore
package/README.md CHANGED
@@ -26,9 +26,9 @@ This datastore prevents data loss by being explicit about what we're writing to,
26
26
  * Native Rx and Promise implementation
27
27
 
28
28
  ## How syncing works
29
- Sometimes datastores (like a global game data store) need to be synced live instead of upon server or player start. This is if we expect multiple servers to write to the same datastore at once we can use thie sync method to
29
+ Sometimes datastores (like a global game data store) need to be synced live instead of upon server or player start. This is if we expect multiple servers to write to the same datastore at once we can use thie sync method to
30
30
 
31
- Syncing is like saving. However, instead of treating the current datastore as a session lock, we load in additional data from our "source-of-truth". From here, we merge that data into the datastore, which means both clearing any matching write tokens that our sync says is done.
31
+ Syncing is like saving. However, instead of treating the current datastore as a session lock, we load in additional data from our "source-of-truth". From here, we merge that data into the datastore, which means both clearing any matching write tokens that our sync says is done.
32
32
 
33
33
  This is best for a "shared" memory that can be temporarily not correct. Deleting with a sync is less effective.
34
34
 
@@ -394,7 +394,7 @@ end
394
394
  -- Do actual load
395
395
 
396
396
  Players.PlayerAdded:Connect(handlePlayerAdded)
397
- for _, player in pairs(Players:GetPlayers()) do
397
+ for _, player in Players:GetPlayers() do
398
398
  handlePlayerAdded(player)
399
399
  end
400
400
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/datastore",
3
- "version": "13.20.0",
3
+ "version": "13.20.1",
4
4
  "description": "Quenty's Datastore implementation for Roblox",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -26,22 +26,22 @@
26
26
  "Quenty"
27
27
  ],
28
28
  "dependencies": {
29
- "@quenty/baseobject": "^10.8.0",
30
- "@quenty/bindtocloseservice": "^8.17.0",
31
- "@quenty/loader": "^10.8.0",
32
- "@quenty/maid": "^3.4.0",
33
- "@quenty/math": "^2.7.1",
34
- "@quenty/pagesutils": "^5.11.1",
35
- "@quenty/promise": "^10.10.1",
36
- "@quenty/rx": "^13.17.0",
37
- "@quenty/servicebag": "^11.11.1",
38
- "@quenty/signal": "^7.10.0",
39
- "@quenty/symbol": "^3.4.0",
40
- "@quenty/table": "^3.7.1",
41
- "@quenty/valueobject": "^13.17.0"
29
+ "@quenty/baseobject": "^10.8.1",
30
+ "@quenty/bindtocloseservice": "^8.17.1",
31
+ "@quenty/loader": "^10.8.1",
32
+ "@quenty/maid": "^3.4.1",
33
+ "@quenty/math": "^2.7.2",
34
+ "@quenty/pagesutils": "^5.11.2",
35
+ "@quenty/promise": "^10.10.2",
36
+ "@quenty/rx": "^13.17.1",
37
+ "@quenty/servicebag": "^11.11.2",
38
+ "@quenty/signal": "^7.10.1",
39
+ "@quenty/symbol": "^3.4.1",
40
+ "@quenty/table": "^3.7.2",
41
+ "@quenty/valueobject": "^13.17.1"
42
42
  },
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
- "gitHead": "e8ea56930e65322fcffc05a1556d5df988068f0b"
46
+ "gitHead": "78c3ac0ab08dd18085b6e6e6e4f745e76ed99f68"
47
47
  }
@@ -32,7 +32,7 @@
32
32
 
33
33
  local topMaid = Maid.new()
34
34
 
35
- local function handlePlayer(player)
35
+ local function handlePlayer(player: Player)
36
36
  local maid = Maid.new()
37
37
 
38
38
  local playerMoneyValue = Instance.new("IntValue")
@@ -54,7 +54,7 @@
54
54
  Players.PlayerRemoving:Connect(function(player)
55
55
  topMaid[player] = nil
56
56
  end)
57
- for _, player in pairs(Players:GetPlayers()) do
57
+ for _, player in Players:GetPlayers() do
58
58
  task.spawn(handlePlayer, player)
59
59
  end
60
60
  ```
@@ -85,6 +85,8 @@ local DataStore = setmetatable({}, DataStoreStage)
85
85
  DataStore.ClassName = "DataStore"
86
86
  DataStore.__index = DataStore
87
87
 
88
+ export type DataStore = typeof(setmetatable({}, { __index = DataStore }))
89
+
88
90
  --[=[
89
91
  Constructs a new DataStore. See [DataStoreStage] for more API.
90
92
 
@@ -96,7 +98,7 @@ DataStore.__index = DataStore
96
98
  @param key string
97
99
  @return DataStore
98
100
  ]=]
99
- function DataStore.new(robloxDataStore, key)
101
+ function DataStore.new(robloxDataStore, key: string)
100
102
  local self = setmetatable(DataStoreStage.new(key), DataStore)
101
103
 
102
104
  self._key = key or error("No key")
@@ -114,7 +116,7 @@ function DataStore.new(robloxDataStore, key)
114
116
  error("[DataStore] - Key cannot be an empty string")
115
117
  end
116
118
 
117
- --[=[
119
+ --[=[
118
120
  Prop that fires when saving. Promise will resolve once saving is complete.
119
121
  @prop Saving Signal<Promise>
120
122
  @within DataStore
@@ -131,7 +133,7 @@ end
131
133
 
132
134
  @param debugWriting boolean
133
135
  ]=]
134
- function DataStore:SetDoDebugWriting(debugWriting)
136
+ function DataStore:SetDoDebugWriting(debugWriting: boolean)
135
137
  assert(type(debugWriting) == "boolean", "Bad debugWriting")
136
138
 
137
139
  self._debugWriting = debugWriting
@@ -141,7 +143,7 @@ end
141
143
  Returns the full path for the datastore
142
144
  @return string
143
145
  ]=]
144
- function DataStore:GetFullPath()
146
+ function DataStore:GetFullPath(): string
145
147
  return string.format("RobloxDataStore@%s", self._key)
146
148
  end
147
149
 
@@ -149,9 +151,9 @@ end
149
151
  How frequent the data store will autosave (or sync) to the cloud. If set to nil then the datastore
150
152
  will not do any syncing.
151
153
 
152
- @param autoSaveTimeSeconds number | nil
154
+ @param autoSaveTimeSeconds number?
153
155
  ]=]
154
- function DataStore:SetAutoSaveTimeSeconds(autoSaveTimeSeconds)
156
+ function DataStore:SetAutoSaveTimeSeconds(autoSaveTimeSeconds: number?)
155
157
  assert(type(autoSaveTimeSeconds) == "number" or autoSaveTimeSeconds == nil, "Bad autoSaveTimeSeconds")
156
158
 
157
159
  self._autoSaveTimeSeconds.Value = autoSaveTimeSeconds
@@ -162,7 +164,7 @@ end
162
164
 
163
165
  @param syncEnabled boolean
164
166
  ]=]
165
- function DataStore:SetSyncOnSave(syncEnabled)
167
+ function DataStore:SetSyncOnSave(syncEnabled: boolean)
166
168
  assert(type(syncEnabled) == "boolean", "Bad syncEnabled")
167
169
 
168
170
  self._syncOnSave.Value = syncEnabled
@@ -172,7 +174,7 @@ end
172
174
  Returns whether the datastore failed.
173
175
  @return boolean
174
176
  ]=]
175
- function DataStore:DidLoadFail()
177
+ function DataStore:DidLoadFail(): boolean
176
178
  if not self._firstLoadPromise then
177
179
  return false
178
180
  end
@@ -189,7 +191,7 @@ end
189
191
 
190
192
  @return Promise<boolean>
191
193
  ]=]
192
- function DataStore:PromiseLoadSuccessful()
194
+ function DataStore:PromiseLoadSuccessful(): Promise.Promise<boolean>
193
195
  return self._maid:GivePromise(self:PromiseViewUpToDate()):Then(function()
194
196
  return true
195
197
  end, function()
@@ -201,7 +203,7 @@ end
201
203
  Saves all stored data.
202
204
  @return Promise
203
205
  ]=]
204
- function DataStore:Save()
206
+ function DataStore:Save(): Promise.Promise<()>
205
207
  return self:_syncData(false)
206
208
  end
207
209
 
@@ -211,16 +213,16 @@ end
211
213
 
212
214
  @return Promise
213
215
  ]=]
214
- function DataStore:Sync()
216
+ function DataStore:Sync(): Promise.Promise<()>
215
217
  return self:_syncData(true)
216
218
  end
217
219
 
218
220
  --[=[
219
221
  Sets the user id list associated with this datastore. Can be useful for GDPR compliance.
220
222
 
221
- @param userIdList { number } | nil
223
+ @param userIdList { number }?
222
224
  ]=]
223
- function DataStore:SetUserIdList(userIdList)
225
+ function DataStore:SetUserIdList(userIdList: { number }?)
224
226
  assert(type(userIdList) == "table" or userIdList == nil, "Bad userIdList")
225
227
  assert(not Symbol.isSymbol(userIdList), "Should not be symbol")
226
228
 
@@ -230,9 +232,9 @@ end
230
232
  --[=[
231
233
  Returns a list of user ids or nil
232
234
 
233
- @return { number } | nil
235
+ @return { number }?
234
236
  ]=]
235
- function DataStore:GetUserIdList()
237
+ function DataStore:GetUserIdList(): { number }?
236
238
  return self._userIdList
237
239
  end
238
240
 
@@ -241,7 +243,7 @@ end
241
243
 
242
244
  @return Promise
243
245
  ]=]
244
- function DataStore:PromiseViewUpToDate()
246
+ function DataStore:PromiseViewUpToDate(): Promise.Promise<()>
245
247
  if self._firstLoadPromise then
246
248
  return self._firstLoadPromise
247
249
  end
@@ -259,10 +261,10 @@ function DataStore:_setupAutoSaving()
259
261
  local startTime = os.clock()
260
262
 
261
263
  self._maid:GiveTask(Rx.combineLatest({
262
- autoSaveTimeSeconds = self._autoSaveTimeSeconds:Observe();
263
- jitterProportion = self._jitterProportion:Observe();
264
- syncOnSave = self._syncOnSave:Observe();
265
- loadedOk = self._loadedOk:Observe();
264
+ autoSaveTimeSeconds = self._autoSaveTimeSeconds:Observe(),
265
+ jitterProportion = self._jitterProportion:Observe(),
266
+ syncOnSave = self._syncOnSave:Observe(),
267
+ loadedOk = self._loadedOk:Observe(),
266
268
  }):Subscribe(function(state)
267
269
  if state.autoSaveTimeSeconds and state.loadedOk then
268
270
  local maid = Maid.new()
@@ -275,7 +277,11 @@ function DataStore:_setupAutoSaving()
275
277
  while true do
276
278
  local jitterBase = math.random()
277
279
  local timeElapsed = os.clock() - startTime
278
- local totalWaitTime = Math.jitter(state.autoSaveTimeSeconds, state.jitterProportion*state.autoSaveTimeSeconds, jitterBase)
280
+ local totalWaitTime = Math.jitter(
281
+ state.autoSaveTimeSeconds,
282
+ state.jitterProportion * state.autoSaveTimeSeconds,
283
+ jitterBase
284
+ )
279
285
  local timeRemaining = totalWaitTime - timeElapsed
280
286
 
281
287
  if timeRemaining > 0 then
@@ -301,7 +307,7 @@ function DataStore:_setupAutoSaving()
301
307
  end))
302
308
  end
303
309
 
304
- function DataStore:_syncData(doMergeNewData)
310
+ function DataStore:_syncData(doMergeNewData: boolean)
305
311
  if self:DidLoadFail() then
306
312
  warn("[DataStore] - Not syncing, failed to load")
307
313
  return Promise.rejected("Load not successful, not syncing")
@@ -354,6 +360,8 @@ function DataStore:_doDataSync(writer, doMergeNewData)
354
360
  -- Do syncing after
355
361
  return self:_promiseGetAsyncNoCache()
356
362
  end
363
+
364
+ return nil
357
365
  end))
358
366
  else
359
367
  if self._debugWriting then
@@ -12,11 +12,12 @@ local DataStore = require("DataStore")
12
12
  local DataStorePromises = require("DataStorePromises")
13
13
  local Maid = require("Maid")
14
14
  local Promise = require("Promise")
15
+ local _ServiceBag = require("ServiceBag")
15
16
 
16
17
  local GameDataStoreService = {}
17
18
  GameDataStoreService.ServiceName = "GameDataStoreService"
18
19
 
19
- function GameDataStoreService:Init(serviceBag)
20
+ function GameDataStoreService:Init(serviceBag: _ServiceBag.ServiceBag)
20
21
  assert(not self._serviceBag, "Already initialized")
21
22
  self._serviceBag = assert(serviceBag, "No serviceBag")
22
23
 
@@ -8,7 +8,7 @@ local Symbol = require("Symbol")
8
8
 
9
9
  local DataStoreSnapshotUtils = {}
10
10
 
11
- function DataStoreSnapshotUtils.isEmptySnapshot(snapshot)
11
+ function DataStoreSnapshotUtils.isEmptySnapshot(snapshot: any): boolean
12
12
  return not Symbol.isSymbol(snapshot) and type(snapshot) == "table" and next(snapshot) == nil
13
13
  end
14
14
 
@@ -20,7 +20,7 @@ local BaseObject = require("BaseObject")
20
20
  local DataStoreDeleteToken = require("DataStoreDeleteToken")
21
21
  local DataStoreSnapshotUtils = require("DataStoreSnapshotUtils")
22
22
  local DataStoreWriter = require("DataStoreWriter")
23
- local GoodSignal = require("GoodSignal")
23
+ local Signal = require("Signal")
24
24
  local Maid = require("Maid")
25
25
  local Observable = require("Observable")
26
26
  local ObservableSubscriptionTable = require("ObservableSubscriptionTable")
@@ -36,6 +36,14 @@ local DataStoreStage = setmetatable({}, BaseObject)
36
36
  DataStoreStage.ClassName = "DataStoreStage"
37
37
  DataStoreStage.__index = DataStoreStage
38
38
 
39
+ export type DataStoreStage = typeof(setmetatable(
40
+ {} :: {
41
+ Changed: Signal.Signal<any>,
42
+ DataStored: Signal.Signal<any>,
43
+ },
44
+ DataStoreStage
45
+ ))
46
+
39
47
  --[=[
40
48
  Constructs a new DataStoreStage to load from. Prefer to use DataStore because this doesn't
41
49
  have any way to retrieve this.
@@ -51,15 +59,15 @@ DataStoreStage.__index = DataStoreStage
51
59
  @param loadParent DataStoreStage?
52
60
  @return DataStoreStage
53
61
  ]=]
54
- function DataStoreStage.new(loadName, loadParent)
62
+ function DataStoreStage.new(loadName: string, loadParent: DataStoreStage?)
55
63
  local self = setmetatable(BaseObject.new(), DataStoreStage)
56
64
 
57
65
  -- LoadParent is optional, used for loading
58
66
  self._loadName = loadName
59
67
  self._loadParent = loadParent
60
68
 
61
- self.Changed = self._maid:Add(GoodSignal.new()) -- :Fire(viewSnapshot)
62
- self.DataStored = self._maid:Add(GoodSignal.new())
69
+ self.Changed = self._maid:Add(Signal.new()) -- :Fire(viewSnapshot)
70
+ self.DataStored = self._maid:Add(Signal.new())
63
71
 
64
72
  -- Stores the actual data loaded and synced (but not pending written data)
65
73
  self._saveDataSnapshot = nil
@@ -83,10 +91,10 @@ end
83
91
  dataStore:Store("money", 25)
84
92
  ```
85
93
 
86
- @param key string | number
94
+ @param key string
87
95
  @param value any
88
96
  ]=]
89
- function DataStoreStage:Store(key, value)
97
+ function DataStoreStage:Store(key: string, value: any)
90
98
  assert(type(key) == "string", "Bad key")
91
99
 
92
100
  if value == nil then
@@ -112,7 +120,7 @@ end
112
120
  @param defaultValue T?
113
121
  @return Promise<T>
114
122
  ]=]
115
- function DataStoreStage:Load(key, defaultValue)
123
+ function DataStoreStage:Load<T>(key: string | number, defaultValue: T?): Promise.Promise<T>
116
124
  assert(type(key) == "string" or type(key) == "number", "Bad key")
117
125
 
118
126
  return self:PromiseViewUpToDate():Then(function()
@@ -165,7 +173,7 @@ end
165
173
  @param key string | number
166
174
  @return DataStoreStage
167
175
  ]=]
168
- function DataStoreStage:GetSubStore(key)
176
+ function DataStoreStage:GetSubStore(key: string | number)
169
177
  assert(type(key) == "string" or type(key) == "number", "Bad key")
170
178
 
171
179
  if self._stores[key] then
@@ -220,7 +228,7 @@ end
220
228
 
221
229
  @param key string | number
222
230
  ]=]
223
- function DataStoreStage:Delete(key)
231
+ function DataStoreStage:Delete(key: string)
224
232
  assert(type(key) == "string", "Bad key")
225
233
 
226
234
  self:_storeAtKey(key, DataStoreDeleteToken)
@@ -238,7 +246,7 @@ end
238
246
 
239
247
  If no key is passed than it will observe the whole view snapshot
240
248
 
241
- @param key string | number | nil
249
+ @param key string | number?
242
250
  @param defaultValue T?
243
251
  @return Observable<T>
244
252
  ]=]
@@ -248,25 +256,24 @@ function DataStoreStage:Observe(key, defaultValue)
248
256
  if key == nil then
249
257
  return Observable.new(function(sub)
250
258
  local maid = Maid.new()
251
- maid:GivePromise(self:LoadAll())
252
- :Then(function()
253
- -- Only connect once loaded
254
- maid:GiveTask(self.Changed:Connect(function(viewSnapshot)
255
- if viewSnapshot == nil then
256
- sub:Fire(defaultValue)
257
- else
258
- sub:Fire(viewSnapshot)
259
- end
260
- end))
261
-
262
- if self._viewSnapshot == nil then
259
+ maid:GivePromise(self:LoadAll()):Then(function()
260
+ -- Only connect once loaded
261
+ maid:GiveTask(self.Changed:Connect(function(viewSnapshot)
262
+ if viewSnapshot == nil then
263
263
  sub:Fire(defaultValue)
264
264
  else
265
- sub:Fire(self._viewSnapshot)
265
+ sub:Fire(viewSnapshot)
266
266
  end
267
- end, function(...)
268
- sub:Fail(...)
269
- end)
267
+ end))
268
+
269
+ if self._viewSnapshot == nil then
270
+ sub:Fire(defaultValue)
271
+ else
272
+ sub:Fire(self._viewSnapshot)
273
+ end
274
+ end, function(...)
275
+ sub:Fail(...)
276
+ end)
270
277
 
271
278
  return maid
272
279
  end)
@@ -275,21 +282,23 @@ function DataStoreStage:Observe(key, defaultValue)
275
282
  return Observable.new(function(sub)
276
283
  local maid = Maid.new()
277
284
 
278
- maid:GiveTask(self._keySubscriptions:Observe(key):Subscribe(function(value)
279
- if value == nil then
280
- sub:Fire(defaultValue)
281
- else
282
- sub:Fire(value)
283
- end
284
- end), sub:GetFailComplete())
285
+ maid:GiveTask(
286
+ self._keySubscriptions:Observe(key):Subscribe(function(value)
287
+ if value == nil then
288
+ sub:Fire(defaultValue)
289
+ else
290
+ sub:Fire(value)
291
+ end
292
+ end),
293
+ sub:GetFailComplete()
294
+ )
285
295
 
286
296
  -- Load initially
287
- maid:GivePromise(self:Load(key, defaultValue))
288
- :Then(function(value)
289
- sub:Fire(value)
290
- end, function(...)
291
- sub:Fail(...)
292
- end)
297
+ maid:GivePromise(self:Load(key, defaultValue)):Then(function(value)
298
+ sub:Fire(value)
299
+ end, function(...)
300
+ sub:Fail(...)
301
+ end)
293
302
 
294
303
  return maid
295
304
  end)
@@ -301,7 +310,7 @@ end
301
310
  @param callback function -- May return a promise
302
311
  @return function -- Call to remove
303
312
  ]=]
304
- function DataStoreStage:AddSavingCallback(callback)
313
+ function DataStoreStage:AddSavingCallback(callback: () -> ())
305
314
  assert(type(callback) == "function", "Bad callback")
306
315
 
307
316
  table.insert(self._savingCallbacks, callback)
@@ -317,7 +326,7 @@ end
317
326
  Removes a saving callback from the data store stage
318
327
  @param callback function
319
328
  ]=]
320
- function DataStoreStage:RemoveSavingCallback(callback)
329
+ function DataStoreStage:RemoveSavingCallback(callback: () -> ())
321
330
  assert(type(callback) == "function", "Bad callback")
322
331
 
323
332
  local index = table.find(self._savingCallbacks, callback)
@@ -361,10 +370,10 @@ function DataStoreStage:PromiseKeyList()
361
370
  return self:PromiseKeySet()
362
371
  :Then(function(keys)
363
372
  local list = {}
364
- for key, _ in pairs(keys) do
365
- table.insert(list, key)
366
- end
367
- return list
373
+ for key, _ in keys do
374
+ table.insert(list, key)
375
+ end
376
+ return list
368
377
  end)
369
378
  end
370
379
 
@@ -437,11 +446,12 @@ function DataStoreStage:MarkDataAsSaved(parentWriter)
437
446
  newBaseDataSnapshot = {}
438
447
  end
439
448
 
440
- for key, value in pairs(dataToSave) do
449
+ for key, value in dataToSave do
441
450
  local ourSnapshotValue = self._saveDataSnapshot[key]
442
451
  if Table.deepEquivalent(ourSnapshotValue, value) or ourSnapshotValue == nil then
443
452
  -- This shouldn't fire any event because our save data is matching
444
- newBaseDataSnapshot[key] = self:_updateStoresAndComputeBaseDataSnapshotValueFromDiffSnapshot(key, value)
453
+ newBaseDataSnapshot[key] =
454
+ self:_updateStoresAndComputeBaseDataSnapshotValueFromDiffSnapshot(key, value)
445
455
  newSaveSnapshot[key] = nil
446
456
  end
447
457
  end
@@ -512,12 +522,12 @@ function DataStoreStage:Overwrite(data)
512
522
  local newSaveSnapshot = {}
513
523
 
514
524
  local remaining = Set.fromKeys(self._stores)
515
- for key, store in pairs(self._stores) do
525
+ for key, store in self._stores do
516
526
  -- Update each store
517
527
  store:Overwrite(data[key])
518
528
  end
519
529
 
520
- for key, value in pairs(data) do
530
+ for key, value in data do
521
531
  remaining[key] = nil
522
532
  if self._stores[key] then
523
533
  self._stores[key]:Overwrite(value)
@@ -526,13 +536,13 @@ function DataStoreStage:Overwrite(data)
526
536
  end
527
537
  end
528
538
 
529
- for key, _ in pairs(remaining) do
539
+ for key, _ in remaining do
530
540
  self._stores[key]:Overwrite(DataStoreDeleteToken)
531
541
  end
532
542
 
533
543
  self._saveDataSnapshot = table.freeze(newSaveSnapshot)
534
544
  else
535
- for _, store in pairs(self._stores) do
545
+ for _, store in self._stores do
536
546
  store:Overwrite(DataStoreDeleteToken)
537
547
  end
538
548
 
@@ -559,7 +569,7 @@ function DataStoreStage:OverwriteMerge(data)
559
569
 
560
570
  if type(data) == "table" and data ~= DataStoreDeleteToken then
561
571
  -- Note we explicitly don't wipe values here! Need delete token if we want to delete!
562
- for key, value in pairs(data) do
572
+ for key, value in data do
563
573
  self:_storeAtKey(key, value)
564
574
  end
565
575
  else
@@ -605,7 +615,7 @@ function DataStoreStage:HasWritableData()
605
615
  return true
606
616
  end
607
617
 
608
- for name, store in pairs(self._stores) do
618
+ for name, store in self._stores do
609
619
  if not store.Destroy then
610
620
  warn(string.format("[DataStoreStage] - Substore %q destroyed", name))
611
621
  continue
@@ -639,7 +649,7 @@ function DataStoreStage:GetNewWriter()
639
649
  writer:SetSaveDataSnapshot(self._saveDataSnapshot)
640
650
  end
641
651
 
642
- for key, store in pairs(self._stores) do
652
+ for key, store in self._stores do
643
653
  if not store.Destroy then
644
654
  warn(string.format("[DataStoreStage] - Substore %q destroyed", key))
645
655
  continue
@@ -667,14 +677,14 @@ end
667
677
  function DataStoreStage:PromiseInvokeSavingCallbacks()
668
678
  local removingPromises = {}
669
679
 
670
- for _, func in pairs(self._savingCallbacks) do
680
+ for _, func in self._savingCallbacks do
671
681
  local result = func()
672
682
  if Promise.isPromise(result) then
673
683
  table.insert(removingPromises, result)
674
684
  end
675
685
  end
676
686
 
677
- for _, substore in pairs(self._stores) do
687
+ for _, substore in self._stores do
678
688
  local promise = substore:PromiseInvokeSavingCallbacks()
679
689
  if promise then
680
690
  table.insert(removingPromises, promise)
@@ -695,7 +705,7 @@ function DataStoreStage:_createFullBaseDataSnapshot()
695
705
  newSnapshot = {}
696
706
  end
697
707
 
698
- for key, store in pairs(self._stores) do
708
+ for key, store in self._stores do
699
709
  if not store.Destroy then
700
710
  warn(string.format("[DataStoreStage] - Substore %q destroyed", key))
701
711
  continue
@@ -730,7 +740,7 @@ function DataStoreStage:_updateStoresAndComputeBaseDataSnapshotFromDiffSnapshot(
730
740
  end
731
741
 
732
742
  -- Merge all of our newly downloaded data here into our base layer.
733
- for key, value in pairs(diffSnapshot) do
743
+ for key, value in diffSnapshot do
734
744
  newBaseDataSnapshot[key] = self:_updateStoresAndComputeBaseDataSnapshotValueFromDiffSnapshot(key, value)
735
745
  end
736
746
 
@@ -750,7 +760,11 @@ function DataStoreStage:_updateStoresAndComputeBaseDataSnapshotValueFromDiffSnap
750
760
  return nil
751
761
  elseif value == DataStoreDeleteToken then
752
762
  return nil
753
- elseif type(value) == "table" and type(self._baseDataSnapshot) == "table" and type(self._baseDataSnapshot[key]) == "table" then
763
+ elseif
764
+ type(value) == "table"
765
+ and type(self._baseDataSnapshot) == "table"
766
+ and type(self._baseDataSnapshot[key]) == "table"
767
+ then
754
768
  return self:_recurseMergeTable(self._baseDataSnapshot[key], value)
755
769
  else
756
770
  return value
@@ -765,7 +779,7 @@ function DataStoreStage:_recurseMergeTable(original, incoming)
765
779
  local newSnapshot = table.clone(original)
766
780
 
767
781
  -- Overwerite with merged values...
768
- for key, value in pairs(incoming) do
782
+ for key, value in incoming do
769
783
  newSnapshot[key] = self:_recurseMergeTable(original[key], value)
770
784
  end
771
785
 
@@ -788,11 +802,11 @@ function DataStoreStage:_updateViewSnapshot()
788
802
  local changedKeys = self:_computeChangedKeys(previousViewSnapshot, newViewSnapshot)
789
803
  if next(changedKeys) ~= nil then
790
804
  if type(newViewSnapshot) == "table" then
791
- for key, _ in pairs(changedKeys) do
805
+ for key, _ in changedKeys do
792
806
  self._keySubscriptions:Fire(key, newViewSnapshot[key])
793
807
  end
794
808
  else
795
- for key, _ in pairs(changedKeys) do
809
+ for key, _ in changedKeys do
796
810
  self._keySubscriptions:Fire(key, nil)
797
811
  end
798
812
  end
@@ -810,7 +824,7 @@ function DataStoreStage:_computeChangedKeys(previousViewSnapshot, newViewSnapsho
810
824
  local changedKeys = {}
811
825
 
812
826
  local keys = Set.union(Set.fromKeys(previousViewSnapshot), Set.fromKeys(newViewSnapshot))
813
- for key, _ in pairs(keys) do
827
+ for key, _ in keys do
814
828
  if not Table.deepEquivalent(previousViewSnapshot[key], newViewSnapshot[key]) then
815
829
  changedKeys[key] = true
816
830
  end
@@ -869,13 +883,13 @@ function DataStoreStage:_computeNewViewSnapshot()
869
883
  end
870
884
 
871
885
  -- Add in stores
872
- for key, store in pairs(self._stores) do
886
+ for key, store in self._stores do
873
887
  newView[key] = store._viewSnapshot
874
888
  end
875
889
 
876
890
  -- Then finally save data
877
891
  if type(self._saveDataSnapshot) == "table" then
878
- for key, value in pairs(self._saveDataSnapshot) do
892
+ for key, value in self._saveDataSnapshot do
879
893
  if value == DataStoreDeleteToken then
880
894
  newView[key] = nil
881
895
  else
@@ -884,7 +898,10 @@ function DataStoreStage:_computeNewViewSnapshot()
884
898
  end
885
899
  end
886
900
 
887
- if next(newView) == nil and not (type(self._baseDataSnapshot) == "table" or type(self._saveDataSnapshot) == "table") then
901
+ if
902
+ next(newView) == nil
903
+ and not (type(self._baseDataSnapshot) == "table" or type(self._saveDataSnapshot) == "table")
904
+ then
888
905
  -- We have no reason to be a table, make sure we return nil
889
906
  return nil
890
907
  end
@@ -995,11 +1012,11 @@ function DataStoreStage:_checkSnapshotIntegrity(label, result)
995
1012
  return
996
1013
  end
997
1014
 
998
- for key, item in pairs(value) do
1015
+ for key, item in value do
999
1016
  local keyLabel = innerLabel .. "." .. tostring(key)
1000
1017
 
1001
1018
  if not (type(key) == "string" or type(key) == "number") then
1002
- error(string.format("%s should be a number or string", keyLabel))
1019
+ error(string.format("%s should be a number or string", keyLabel))
1003
1020
  end
1004
1021
 
1005
1022
  if item == DataStoreDeleteToken then
@@ -1037,7 +1054,7 @@ function DataStoreStage:_checkIntegrity()
1037
1054
  self:_checkSnapshotIntegrity("self._viewSnapshot", self._viewSnapshot)
1038
1055
  end
1039
1056
 
1040
- for key, _ in pairs(self._stores) do
1057
+ for key, _ in self._stores do
1041
1058
  if type(self._baseDataSnapshot) == "table" and self._baseDataSnapshot[key] ~= nil then
1042
1059
  error(string.format("[DataStoreStage] - Duplicate baseData at key %q", key))
1043
1060
  end
@@ -24,7 +24,7 @@ DataStoreWriter.__index = DataStoreWriter
24
24
  @param debugName string
25
25
  @return DataStoreWriter
26
26
  ]=]
27
- function DataStoreWriter.new(debugName)
27
+ function DataStoreWriter.new(debugName: string)
28
28
  local self = setmetatable({}, DataStoreWriter)
29
29
 
30
30
  self._debugName = assert(debugName, "No debugName")
@@ -66,7 +66,10 @@ function DataStoreWriter:GetSubWritersMap()
66
66
  end
67
67
 
68
68
  function DataStoreWriter:SetFullBaseDataSnapshot(fullBaseDataSnapshot)
69
- assert(type(fullBaseDataSnapshot) ~= "table" or table.isfrozen(fullBaseDataSnapshot), "fullBaseDataSnapshot should be frozen")
69
+ assert(
70
+ type(fullBaseDataSnapshot) ~= "table" or table.isfrozen(fullBaseDataSnapshot),
71
+ "fullBaseDataSnapshot should be frozen"
72
+ )
70
73
  assert(not Symbol.isSymbol(fullBaseDataSnapshot), "fullBaseDataSnapshot should not be symbol")
71
74
 
72
75
  if fullBaseDataSnapshot == DataStoreDeleteToken then
@@ -81,7 +84,7 @@ end
81
84
  @param name string
82
85
  @param writer DataStoreWriter
83
86
  ]=]
84
- function DataStoreWriter:AddSubWriter(name, writer)
87
+ function DataStoreWriter:AddSubWriter(name: string, writer)
85
88
  assert(type(name) == "string", "Bad name")
86
89
  assert(not self._writers[name], "Writer already exists for name")
87
90
  assert(writer, "Bad writer")
@@ -95,7 +98,7 @@ end
95
98
  @param name string
96
99
  @return DataStoreWriter
97
100
  ]=]
98
- function DataStoreWriter:GetWriter(name)
101
+ function DataStoreWriter:GetWriter(name: string)
99
102
  assert(type(name) == "string", "Bad name")
100
103
 
101
104
  return self._writers[name]
@@ -124,7 +127,7 @@ function DataStoreWriter:ComputeDiffSnapshot(incoming)
124
127
  end
125
128
 
126
129
  local diffSnapshot = {}
127
- for key, _ in pairs(keys) do
130
+ for key, _ in keys do
128
131
  if self._writers[key] then
129
132
  diffSnapshot[key] = self._writers[key]:ComputeDiffSnapshot(incoming[key])
130
133
  else
@@ -172,7 +175,7 @@ function DataStoreWriter:_computeTableDiff(original, incoming)
172
175
  local keys = Set.union(Set.fromKeys(original), Set.fromKeys(incoming))
173
176
 
174
177
  local diffSnapshot = {}
175
- for key, _ in pairs(keys) do
178
+ for key, _ in keys do
176
179
  diffSnapshot[key] = self:_computeValueDiff(original[key], incoming[key])
177
180
  end
178
181
 
@@ -224,7 +227,7 @@ function DataStoreWriter:_writeMergeWriters(original)
224
227
  end
225
228
 
226
229
  -- Write our writers first...
227
- for key, writer in pairs(self._writers) do
230
+ for key, writer in self._writers do
228
231
  local result = writer:WriteMerge(copy[key])
229
232
  if result == DataStoreDeleteToken then
230
233
  copy[key] = nil
@@ -235,15 +238,26 @@ function DataStoreWriter:_writeMergeWriters(original)
235
238
  end
236
239
 
237
240
  -- Write our save data next
238
- if not Symbol.isSymbol(self._saveDataSnapshot) and type(self._saveDataSnapshot) == "table" and next(self._saveDataSnapshot) ~= nil then
241
+ if
242
+ not Symbol.isSymbol(self._saveDataSnapshot)
243
+ and type(self._saveDataSnapshot) == "table"
244
+ and next(self._saveDataSnapshot) ~= nil
245
+ then
239
246
  -- Original was not a table. We need to swap to one.
240
247
  if type(copy) ~= "table" then
241
248
  copy = {}
242
249
  end
243
250
 
244
- for key, value in pairs(self._saveDataSnapshot) do
251
+ for key, value in self._saveDataSnapshot do
245
252
  if self._writers[key] then
246
- warn(string.format("[DataStoreWriter._writeMergeWriters] - Overwriting key %q already saved as rawData with a writer with %q (was %q)", key, tostring(value), tostring(copy[key])))
253
+ warn(
254
+ string.format(
255
+ "[DataStoreWriter._writeMergeWriters] - Overwriting key %q already saved as rawData with a writer with %q (was %q)",
256
+ key,
257
+ tostring(value),
258
+ tostring(copy[key])
259
+ )
260
+ )
247
261
  end
248
262
 
249
263
  if value == DataStoreDeleteToken then
@@ -276,7 +290,11 @@ function DataStoreWriter:WriteMerge(original)
276
290
 
277
291
  if self._saveDataSnapshot == DataStoreDeleteToken then
278
292
  return DataStoreDeleteToken
279
- elseif self._saveDataSnapshot == UNSET_TOKEN or self._saveDataSnapshot == nil or type(self._saveDataSnapshot) == "table" then
293
+ elseif
294
+ self._saveDataSnapshot == UNSET_TOKEN
295
+ or self._saveDataSnapshot == nil
296
+ or type(self._saveDataSnapshot) == "table"
297
+ then
280
298
  return self:_writeMergeWriters(original)
281
299
  else
282
300
  -- Save data must be a boolean or something
@@ -284,7 +302,7 @@ function DataStoreWriter:WriteMerge(original)
284
302
  end
285
303
  end
286
304
 
287
- function DataStoreWriter:IsCompleteWipe()
305
+ function DataStoreWriter:IsCompleteWipe(): boolean
288
306
  if self._saveDataSnapshot == UNSET_TOKEN then
289
307
  return false
290
308
  end
@@ -17,7 +17,7 @@
17
17
 
18
18
  local topMaid = Maid.new()
19
19
 
20
- local function handlePlayer(player)
20
+ local function handlePlayer(player: Player)
21
21
  local maid = Maid.new()
22
22
 
23
23
  local playerMoneyValue = Instance.new("IntValue")
@@ -39,7 +39,7 @@
39
39
  Players.PlayerRemoving:Connect(function(player)
40
40
  topMaid[player] = nil
41
41
  end)
42
- for _, player in pairs(Players:GetPlayers()) do
42
+ for _, player in Players:GetPlayers() do
43
43
  task.spawn(handlePlayer, player)
44
44
  end
45
45
  ```
@@ -72,7 +72,7 @@ PlayerDataStoreManager.__index = PlayerDataStoreManager
72
72
  @param skipBindingToClose boolean?
73
73
  @return PlayerDataStoreManager
74
74
  ]=]
75
- function PlayerDataStoreManager.new(robloxDataStore, keyGenerator, skipBindingToClose)
75
+ function PlayerDataStoreManager.new(robloxDataStore: DataStore, keyGenerator, skipBindingToClose)
76
76
  local self = setmetatable(BaseObject.new(), PlayerDataStoreManager)
77
77
 
78
78
  assert(type(skipBindingToClose) == "boolean" or skipBindingToClose == nil, "Bad skipBindingToClose")
@@ -131,7 +131,7 @@ end
131
131
 
132
132
  @param player Player
133
133
  ]=]
134
- function PlayerDataStoreManager:RemovePlayerDataStore(player)
134
+ function PlayerDataStoreManager:RemovePlayerDataStore(player: Player)
135
135
  self:_removePlayerDataStore(player)
136
136
  end
137
137
 
@@ -139,7 +139,7 @@ end
139
139
  @param player Player
140
140
  @return DataStore
141
141
  ]=]
142
- function PlayerDataStoreManager:GetDataStore(player)
142
+ function PlayerDataStoreManager:GetDataStore(player: Player)
143
143
  assert(typeof(player) == "Instance", "Bad player")
144
144
  assert(player:IsA("Player"), "Bad player")
145
145
 
@@ -161,13 +161,13 @@ end
161
161
  @return Promise
162
162
  ]=]
163
163
  function PlayerDataStoreManager:PromiseAllSaves()
164
- for player, _ in pairs(self._datastores) do
164
+ for player, _ in self._datastores do
165
165
  self:_removePlayerDataStore(player)
166
166
  end
167
167
  return self._maid:GivePromise(PromiseUtils.all(self._pendingSaves:GetAll()))
168
168
  end
169
169
 
170
- function PlayerDataStoreManager:_createDataStore(player)
170
+ function PlayerDataStoreManager:_createDataStore(player: Player)
171
171
  assert(not self._datastores[player], "Bad player")
172
172
 
173
173
  local datastore = DataStore.new(self._robloxDataStore, self:_getKey(player))
@@ -182,7 +182,7 @@ function PlayerDataStoreManager:_createDataStore(player)
182
182
  return datastore
183
183
  end
184
184
 
185
- function PlayerDataStoreManager:_removePlayerDataStore(player)
185
+ function PlayerDataStoreManager:_removePlayerDataStore(player: Player)
186
186
  assert(typeof(player) == "Instance", "Bad player")
187
187
  assert(player:IsA("Player"), "Bad player")
188
188
 
@@ -194,7 +194,7 @@ function PlayerDataStoreManager:_removePlayerDataStore(player)
194
194
  self._removing[player] = true
195
195
 
196
196
  local removingPromises = {}
197
- for _, func in pairs(self._removingCallbacks) do
197
+ for _, func in self._removingCallbacks do
198
198
  local result = func(player)
199
199
  if Promise.isPromise(result) then
200
200
  table.insert(removingPromises, result)
@@ -215,7 +215,7 @@ function PlayerDataStoreManager:_removePlayerDataStore(player)
215
215
  self._maid._savingConns[player] = nil
216
216
  end
217
217
 
218
- function PlayerDataStoreManager:_getKey(player)
218
+ function PlayerDataStoreManager:_getKey(player: Player)
219
219
  return self._keyGenerator(player)
220
220
  end
221
221
 
@@ -11,6 +11,7 @@ local PlayerDataStoreManager = require("PlayerDataStoreManager")
11
11
  local DataStorePromises = require("DataStorePromises")
12
12
  local Promise = require("Promise")
13
13
  local Maid = require("Maid")
14
+ local _ServiceBag = require("ServiceBag")
14
15
 
15
16
  local PlayerDataStoreService = {}
16
17
  PlayerDataStoreService.ServiceName = "PlayerDataStoreService"
@@ -19,7 +20,7 @@ PlayerDataStoreService.ServiceName = "PlayerDataStoreService"
19
20
  Initializes the PlayerDataStoreService. Should be done via [ServiceBag.Init].
20
21
  @param serviceBag ServiceBag
21
22
  ]=]
22
- function PlayerDataStoreService:Init(serviceBag)
23
+ function PlayerDataStoreService:Init(serviceBag: _ServiceBag.ServiceBag)
23
24
  self._serviceBag = assert(serviceBag, "No serviceBag")
24
25
  self._maid = Maid.new()
25
26
 
@@ -49,7 +50,7 @@ end
49
50
 
50
51
  @param dataStoreName string
51
52
  ]=]
52
- function PlayerDataStoreService:SetDataStoreName(dataStoreName)
53
+ function PlayerDataStoreService:SetDataStoreName(dataStoreName: string)
53
54
  assert(type(dataStoreName) == "string", "Bad dataStoreName")
54
55
  assert(self._promiseStarted, "Not initialized")
55
56
  assert(self._promiseStarted:IsPending(), "Already started, cannot configure")
@@ -66,7 +67,7 @@ end
66
67
 
67
68
  @param dataStoreScope string
68
69
  ]=]
69
- function PlayerDataStoreService:SetDataStoreScope(dataStoreScope)
70
+ function PlayerDataStoreService:SetDataStoreScope(dataStoreScope: string)
70
71
  assert(type(dataStoreScope) == "string", "Bad dataStoreScope")
71
72
  assert(self._promiseStarted, "Not initialized")
72
73
  assert(self._promiseStarted:IsPending(), "Already started, cannot configure")
@@ -10,11 +10,12 @@ local require = require(script.Parent.loader).load(script)
10
10
  local DataStore = require("DataStore")
11
11
  local DataStorePromises = require("DataStorePromises")
12
12
  local Maid = require("Maid")
13
+ local _ServiceBag = require("ServiceBag")
13
14
 
14
15
  local PrivateServerDataStoreService = {}
15
16
  PrivateServerDataStoreService.ServiceName = "PrivateServerDataStoreService"
16
17
 
17
- function PrivateServerDataStoreService:Init(serviceBag)
18
+ function PrivateServerDataStoreService:Init(serviceBag: _ServiceBag.ServiceBag)
18
19
  assert(not self._serviceBag, "Already initialized")
19
20
  self._serviceBag = assert(serviceBag, "No serviceBag")
20
21
 
@@ -1,3 +1,4 @@
1
+ --!strict
1
2
  --[=[
2
3
  Utility methods to interactive with Roblox datastores.
3
4
  @server
@@ -21,7 +22,7 @@ local DataStorePromises = {}
21
22
  @param scope string
22
23
  @return Promise<DataStore>
23
24
  ]=]
24
- function DataStorePromises.promiseDataStore(name, scope)
25
+ function DataStorePromises.promiseDataStore(name: string, scope: string): Promise.Promise<DataStore>
25
26
  assert(type(name) == "string", "Bad name")
26
27
  assert(type(scope) == "string", "Bad scope")
27
28
 
@@ -44,7 +45,7 @@ end
44
45
  @param scope string
45
46
  @return Promise<OrderedDataStore>
46
47
  ]=]
47
- function DataStorePromises.promiseOrderedDataStore(name, scope)
48
+ function DataStorePromises.promiseOrderedDataStore(name: string, scope: string): Promise.Promise<OrderedDataStore>
48
49
  assert(type(name) == "string", "Bad name")
49
50
  assert(type(scope) == "string", "Bad scope")
50
51
 
@@ -66,7 +67,7 @@ end
66
67
  @param key string
67
68
  @return Promise<T>
68
69
  ]=]
69
- function DataStorePromises.getAsync(robloxDataStore, key)
70
+ function DataStorePromises.getAsync<T>(robloxDataStore: DataStore, key: string): Promise.Promise<T>
70
71
  assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
71
72
  assert(type(key) == "string", "Bad key")
72
73
 
@@ -88,10 +89,14 @@ end
88
89
  @param robloxDataStore DataStore
89
90
  @param key string
90
91
  @param updateFunc (T) -> T?
91
- @return Promise<boolean>
92
+ @return Promise<T>
92
93
  ]=]
93
94
 
94
- function DataStorePromises.updateAsync(robloxDataStore, key, updateFunc)
95
+ function DataStorePromises.updateAsync<T>(
96
+ robloxDataStore: DataStore,
97
+ key: string,
98
+ updateFunc: (T) -> T?
99
+ ): Promise.Promise<(T, DataStoreKeyInfo)>
95
100
  assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
96
101
  assert(type(key) == "string", "Bad key")
97
102
  assert(type(updateFunc) == "function", "Bad updateFunc")
@@ -119,7 +124,12 @@ end
119
124
  @param userIds { number } -- Associated userIds
120
125
  @return Promise<boolean>
121
126
  ]=]
122
- function DataStorePromises.setAsync(robloxDataStore, key, value, userIds)
127
+ function DataStorePromises.setAsync(
128
+ robloxDataStore: DataStore,
129
+ key,
130
+ value: string,
131
+ userIds: { number }?
132
+ ): Promise.Promise<boolean>
123
133
  assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
124
134
  assert(type(key) == "string", "Bad key")
125
135
  assert(type(userIds) == "table" or userIds == nil, "Bad userIds")
@@ -142,7 +152,11 @@ end
142
152
  @param delta number
143
153
  @return Promise<boolean>
144
154
  ]=]
145
- function DataStorePromises.promiseIncrementAsync(robloxDataStore, key, delta)
155
+ function DataStorePromises.promiseIncrementAsync(
156
+ robloxDataStore: DataStore,
157
+ key: string,
158
+ delta: number
159
+ ): Promise.Promise<boolean>
146
160
  assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
147
161
  assert(type(key) == "string", "Bad key")
148
162
  assert(type(delta) == "number" or delta == nil, "Bad delta")
@@ -164,7 +178,7 @@ end
164
178
  @param key string
165
179
  @return Promise<boolean>
166
180
  ]=]
167
- function DataStorePromises.removeAsync(robloxDataStore, key)
181
+ function DataStorePromises.removeAsync(robloxDataStore: DataStore, key: string): Promise.Promise<boolean>
168
182
  assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
169
183
  assert(type(key) == "string", "Bad key")
170
184
 
@@ -191,7 +205,13 @@ end
191
205
  @param maxValue number?
192
206
  @return Promise<DataStorePages>
193
207
  ]=]
194
- function DataStorePromises.promiseSortedPagesAsync(orderedDataStore, ascending, pagesize, minValue, maxValue)
208
+ function DataStorePromises.promiseSortedPagesAsync(
209
+ orderedDataStore: OrderedDataStore,
210
+ ascending: boolean,
211
+ pagesize: number,
212
+ minValue: number?,
213
+ maxValue: number?
214
+ ): Promise.Promise<DataStorePages>
195
215
  assert(typeof(orderedDataStore) == "Instance" and orderedDataStore:IsA("OrderedDataStore"), "Bad orderedDataStore")
196
216
  assert(type(ascending) == "boolean", "Bad ascending")
197
217
  assert(type(pagesize) == "number", "Bad entries")
@@ -212,7 +232,6 @@ function DataStorePromises.promiseSortedPagesAsync(orderedDataStore, ascending,
212
232
  end)
213
233
  end
214
234
 
215
-
216
235
  --[=[
217
236
  @interface OrderedDataStoreEntry
218
237
  .key any
@@ -253,19 +272,20 @@ end
253
272
  @param maxValue number?
254
273
  @return Promise<OrderedDataStoreEntry>
255
274
  ]=]
256
- function DataStorePromises.promiseOrderedEntries(orderedDataStore, ascending, pagesize, entries, minValue, maxValue)
275
+ function DataStorePromises.promiseOrderedEntries(orderedDataStore: OrderedDataStore, ascending: boolean, pagesize: number, entries: number, minValue: number?, maxValue: number?): Promise.Promise<OrderedDataStoreEntry>
257
276
  assert(typeof(orderedDataStore) == "Instance" and orderedDataStore:IsA("OrderedDataStore"), "Bad orderedDataStore")
258
277
  assert(type(ascending) == "boolean", "Bad ascending")
259
278
  assert(type(entries) == "number", "Bad entries")
260
279
 
280
+ -- stylua: ignore
261
281
  return DataStorePromises.promiseSortedPagesAsync(orderedDataStore, ascending, pagesize, minValue, maxValue)
262
- :Then(function(dataStorePages)
282
+ :Then(function(dataStorePages: DataStorePages)
263
283
  return Promise.spawn(function(resolve, reject)
264
284
  local resultList = {}
265
285
 
266
- local pageData = dataStorePages:GetCurrentPage()
286
+ local pageData: any? = dataStorePages:GetCurrentPage()
267
287
  while pageData do
268
- for _, data in pairs(pageData) do
288
+ for _, data in pageData do
269
289
  if #resultList < entries then
270
290
  table.insert(resultList, data)
271
291
  else
@@ -13,7 +13,7 @@ local Promise = require("Promise")
13
13
 
14
14
  local TURN_TIME = 8
15
15
 
16
- local function spinUpGameCopy(prefix)
16
+ local function spinUpGameCopy(prefix: string)
17
17
  assert(type(prefix) == "string", "Bad prefix")
18
18
 
19
19
  local serviceBag = require("ServiceBag").new()