@quenty/observablecollection 12.20.0 → 12.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.
@@ -1,3 +1,4 @@
1
+ --strict
1
2
  --[=[
2
3
  A list that can be observed for blend and other components and maintains sorting order.
3
4
 
@@ -35,16 +36,38 @@ local ObservableSortedList = {}
35
36
  ObservableSortedList.ClassName = "ObservableSortedList"
36
37
  ObservableSortedList.__index = ObservableSortedList
37
38
 
39
+ export type CompareFunction<T> = (T, T) -> number
40
+
41
+ export type ObservableSortedList<T> = typeof(setmetatable(
42
+ {} :: {
43
+ _maid: Maid.Maid,
44
+ _root: SortedNode.SortedNode<T>?,
45
+ _nodesAdded: { [SortedNode.SortedNode<T>]: boolean },
46
+ _nodesRemoved: { [SortedNode.SortedNode<T>]: boolean },
47
+ _lowestIndexChanged: number?,
48
+ _compare: CompareFunction<T>,
49
+ _countValue: ValueObject.ValueObject<number>,
50
+ _indexObservers: any,
51
+ _nodeIndexObservables: any,
52
+ _mainObservables: any,
53
+ ItemAdded: Signal.Signal<T, number, SortedNode.SortedNode<T>>,
54
+ ItemRemoved: Signal.Signal<T, SortedNode.SortedNode<T>>,
55
+ OrderChanged: Signal.Signal<()>,
56
+ CountChanged: Signal.Signal<number>,
57
+ },
58
+ ObservableSortedList
59
+ ))
60
+
38
61
  --[=[
39
62
  Constructs a new ObservableSortedList
40
63
  @param isReversed boolean
41
64
  @param compare function
42
65
  @return ObservableSortedList<T>
43
66
  ]=]
44
- function ObservableSortedList.new(isReversed, compare)
67
+ function ObservableSortedList.new<T>(isReversed: boolean?, compare: CompareFunction<T>): ObservableSortedList<T>
45
68
  assert(type(isReversed) == "boolean" or isReversed == nil, "Bad isReversed")
46
69
 
47
- local self = setmetatable({}, ObservableSortedList)
70
+ local self = setmetatable({} :: any, ObservableSortedList)
48
71
 
49
72
  self._maid = Maid.new()
50
73
 
@@ -61,7 +84,7 @@ function ObservableSortedList.new(isReversed, compare)
61
84
 
62
85
  self._countValue = self._maid:Add(ValueObject.new(0, "number"))
63
86
 
64
- --[=[
87
+ --[=[
65
88
  Fires when an item is added
66
89
 
67
90
  @readonly
@@ -70,7 +93,7 @@ function ObservableSortedList.new(isReversed, compare)
70
93
  ]=]
71
94
  self.ItemAdded = self._maid:Add(Signal.new())
72
95
 
73
- --[=[
96
+ --[=[
74
97
  Fires when an item is removed.
75
98
 
76
99
  @readonly
@@ -79,7 +102,7 @@ function ObservableSortedList.new(isReversed, compare)
79
102
  ]=]
80
103
  self.ItemRemoved = self._maid:Add(Signal.new())
81
104
 
82
- --[=[
105
+ --[=[
83
106
  Fires when the order could have changed
84
107
 
85
108
  @readonly
@@ -88,8 +111,7 @@ function ObservableSortedList.new(isReversed, compare)
88
111
  ]=]
89
112
  self.OrderChanged = self._maid:Add(Signal.new())
90
113
 
91
-
92
- --[=[
114
+ --[=[
93
115
  Fires when the count changes
94
116
 
95
117
  @readonly
@@ -106,7 +128,7 @@ end
106
128
  @param value any
107
129
  @return boolean
108
130
  ]=]
109
- function ObservableSortedList.isObservableSortedList(value)
131
+ function ObservableSortedList.isObservableSortedList(value: any): boolean
110
132
  return DuckTypeUtils.isImplementation(ObservableSortedList, value)
111
133
  end
112
134
 
@@ -115,11 +137,11 @@ end
115
137
 
116
138
  @return Observable<{ T }>
117
139
  ]=]
118
- function ObservableSortedList:Observe()
140
+ function ObservableSortedList.Observe<T>(self: ObservableSortedList<T>): Observable.Observable<{ T }>
119
141
  return self._mainObservables:Observe("list"):Pipe({
120
142
  Rx.start(function()
121
143
  return self:GetList()
122
- end)
144
+ end),
123
145
  })
124
146
  end
125
147
 
@@ -128,7 +150,7 @@ end
128
150
 
129
151
  @return (T) -> ((T, nextIndex: any) -> ...any, T?)
130
152
  ]=]
131
- function ObservableSortedList:__iter()
153
+ function ObservableSortedList.__iter<T>(self: ObservableSortedList<T>): SortFunctionUtils.WrappedIterator<number, T>
132
154
  if self._root then
133
155
  return self._root:IterateData()
134
156
  else
@@ -143,15 +165,21 @@ end
143
165
  @param finish number
144
166
  @return (T) -> ((T, nextIndex: any) -> ...any, T?)
145
167
  ]=]
146
- function ObservableSortedList:IterateRange(start, finish)
168
+ function ObservableSortedList.IterateRange<T>(
169
+ self: ObservableSortedList<T>,
170
+ start: number,
171
+ finish: number
172
+ ): SortFunctionUtils.WrappedIterator<number, T>
147
173
  return coroutine.wrap(function()
148
- for index, node in self:_iterateNodesRange(start, finish) do
174
+ for index: number, node in self:_iterateNodesRange(start, finish) do
149
175
  coroutine.yield(index, node.data)
150
176
  end
151
- end)
177
+ end) :: any
152
178
  end
153
179
 
154
- function ObservableSortedList:_iterateNodes()
180
+ function ObservableSortedList._iterateNodes<T>(
181
+ self: ObservableSortedList<T>
182
+ ): SortFunctionUtils.WrappedIterator<number, SortedNode.SortedNode<T>>
155
183
  if self._root then
156
184
  return self._root:IterateNodes()
157
185
  else
@@ -159,7 +187,11 @@ function ObservableSortedList:_iterateNodes()
159
187
  end
160
188
  end
161
189
 
162
- function ObservableSortedList:_iterateNodesRange(start, finish)
190
+ function ObservableSortedList._iterateNodesRange<T>(
191
+ self: ObservableSortedList<T>,
192
+ start: number,
193
+ finish: number
194
+ ): SortFunctionUtils.WrappedIterator<number, SortedNode.SortedNode<T>>
163
195
  if self._root then
164
196
  return self._root:IterateNodesRange(start, finish)
165
197
  else
@@ -167,7 +199,7 @@ function ObservableSortedList:_iterateNodesRange(start, finish)
167
199
  end
168
200
  end
169
201
 
170
- function ObservableSortedList:_containsNode(node)
202
+ function ObservableSortedList._containsNode<T>(self: ObservableSortedList<T>, node: SortedNode.SortedNode<T>): boolean
171
203
  assert(SortedNode.isSortedNode(node), "Bad node")
172
204
 
173
205
  if self._root then
@@ -177,7 +209,10 @@ function ObservableSortedList:_containsNode(node)
177
209
  end
178
210
  end
179
211
 
180
- function ObservableSortedList:_findNodeForDataLinearSearchSlow(data)
212
+ function ObservableSortedList._findNodeForDataLinearSearchSlow<T>(
213
+ self: ObservableSortedList<T>,
214
+ data: T
215
+ ): SortedNode.SortedNode<T>?
181
216
  if self._root then
182
217
  return self._root:FindFirstNodeForData(data)
183
218
  else
@@ -185,7 +220,7 @@ function ObservableSortedList:_findNodeForDataLinearSearchSlow(data)
185
220
  end
186
221
  end
187
222
 
188
- function ObservableSortedList:_findNodeAtIndex(index)
223
+ function ObservableSortedList._findNodeAtIndex<T>(self: ObservableSortedList<T>, index: number): SortedNode.SortedNode<T>?
189
224
  assert(type(index) == "number", "Bad index")
190
225
 
191
226
  if self._root then
@@ -195,7 +230,7 @@ function ObservableSortedList:_findNodeAtIndex(index)
195
230
  end
196
231
  end
197
232
 
198
- function ObservableSortedList:_findNodeIndex(node)
233
+ function ObservableSortedList._findNodeIndex<T>(self: ObservableSortedList<T>, node: SortedNode.SortedNode<T>): number?
199
234
  assert(SortedNode.isSortedNode(node), "Bad node")
200
235
 
201
236
  if self._root then
@@ -211,11 +246,11 @@ end
211
246
  @param content T
212
247
  @return Symbol
213
248
  ]=]
214
- function ObservableSortedList:FindFirstKey(content)
249
+ function ObservableSortedList.FindFirstKey<T>(self: ObservableSortedList<T>, content: T): SortedNode.SortedNode<T>?
215
250
  return self:_findNodeForDataLinearSearchSlow(content)
216
251
  end
217
252
 
218
- function ObservableSortedList:PrintDebug()
253
+ function ObservableSortedList.PrintDebug<T>(self: ObservableSortedList<T>)
219
254
  print(self._root)
220
255
  end
221
256
 
@@ -225,7 +260,7 @@ end
225
260
  @param content T
226
261
  @return boolean
227
262
  ]=]
228
- function ObservableSortedList:Contains(content)
263
+ function ObservableSortedList.Contains<T>(self: ObservableSortedList<T>, content): boolean
229
264
  assert(content ~= nil, "Bad content")
230
265
 
231
266
  -- TODO: Speed up
@@ -236,14 +271,16 @@ end
236
271
  Observes all items in the list
237
272
  @return Observable<Brio<T, Symbol>>
238
273
  ]=]
239
- function ObservableSortedList:ObserveItemsBrio()
274
+ function ObservableSortedList.ObserveItemsBrio<T>(
275
+ self: ObservableSortedList<T>
276
+ ): Observable.Observable<Brio.Brio<T, SortedNode.SortedNode<T>>>
240
277
  return Observable.new(function(sub)
241
278
  local maid = Maid.new()
242
279
 
243
280
  -- TODO: Optimize this so we don't have to make so many brios and connect
244
281
  -- to so many events
245
282
 
246
- local function handleItem(data, _index, node)
283
+ local function handleItem(data: T, _index, node)
247
284
  local brio = Brio.new(data, node)
248
285
  maid[node] = brio
249
286
  sub:Fire(brio)
@@ -267,7 +304,7 @@ function ObservableSortedList:ObserveItemsBrio()
267
304
  end)
268
305
 
269
306
  return maid
270
- end)
307
+ end) :: any
271
308
  end
272
309
 
273
310
  --[=[
@@ -277,12 +314,20 @@ end
277
314
  @param indexToObserve number
278
315
  @return Observable<number>
279
316
  ]=]
280
- function ObservableSortedList:ObserveIndex(indexToObserve)
317
+ function ObservableSortedList.ObserveIndex<T>(
318
+ self: ObservableSortedList<T>,
319
+ indexToObserve: number
320
+ ): Observable.Observable<number>
281
321
  assert(type(indexToObserve) == "number", "Bad indexToObserve")
282
322
 
283
323
  local node = self:_findNodeAtIndex(indexToObserve)
284
324
  if not node then
285
- error(string.format("[ObservableSortedList.ObserveIndex] - No entry at index %q, cannot observe changes", indexToObserve))
325
+ error(
326
+ string.format(
327
+ "[ObservableSortedList.ObserveIndex] - No entry at index %d, cannot observe changes",
328
+ indexToObserve
329
+ )
330
+ )
286
331
  end
287
332
 
288
333
  return self:ObserveIndexByKey(node)
@@ -295,7 +340,10 @@ end
295
340
  @param indexToObserve number
296
341
  @return Observable<(T, Key)>
297
342
  ]=]
298
- function ObservableSortedList:ObserveAtIndex(indexToObserve)
343
+ function ObservableSortedList.ObserveAtIndex<T>(
344
+ self: ObservableSortedList<T>,
345
+ indexToObserve: number
346
+ ): Observable.Observable<T, SortedNode.SortedNode<T>>
299
347
  assert(type(indexToObserve) == "number", "Bad indexToObserve")
300
348
 
301
349
  return self._indexObservers:Observe(indexToObserve, function(sub)
@@ -305,7 +353,7 @@ function ObservableSortedList:ObserveAtIndex(indexToObserve)
305
353
  else
306
354
  sub:Fire(nil, nil)
307
355
  end
308
- end)
356
+ end) :: any
309
357
  end
310
358
 
311
359
  --[=[
@@ -315,7 +363,10 @@ end
315
363
  @param node SortedNode
316
364
  @return Observable<number>
317
365
  ]=]
318
- function ObservableSortedList:ObserveIndexByKey(node)
366
+ function ObservableSortedList.ObserveIndexByKey<T>(
367
+ self: ObservableSortedList<T>,
368
+ node: SortedNode.SortedNode<T>
369
+ ): Observable.Observable<number?>
319
370
  assert(SortedNode.isSortedNode(node), "Bad node")
320
371
 
321
372
  return self._nodeIndexObservables:Observe(node, function(sub)
@@ -323,7 +374,7 @@ function ObservableSortedList:ObserveIndexByKey(node)
323
374
  if currentIndex then
324
375
  sub:Fire(currentIndex)
325
376
  end
326
- end)
377
+ end) :: any
327
378
  end
328
379
 
329
380
  --[=[
@@ -332,7 +383,7 @@ end
332
383
  @param node SortedNode
333
384
  @return number
334
385
  ]=]
335
- function ObservableSortedList:GetIndexByKey(node)
386
+ function ObservableSortedList.GetIndexByKey<T>(self: ObservableSortedList<T>, node: SortedNode.SortedNode<T>): number?
336
387
  assert(SortedNode.isSortedNode(node), "Bad node")
337
388
 
338
389
  return self:_findNodeIndex(node)
@@ -342,7 +393,7 @@ end
342
393
  Gets the count of items in the list
343
394
  @return number
344
395
  ]=]
345
- function ObservableSortedList:GetCount()
396
+ function ObservableSortedList.GetCount<T>(self: ObservableSortedList<T>): number
346
397
  return self._countValue.Value or 0
347
398
  end
348
399
 
@@ -352,7 +403,7 @@ ObservableSortedList.__len = ObservableSortedList.GetCount
352
403
  Gets a list of all entries.
353
404
  @return { T }
354
405
  ]=]
355
- function ObservableSortedList:GetList()
406
+ function ObservableSortedList.GetList<T>(self: ObservableSortedList<T>): { T }
356
407
  local list = table.create(self._countValue.Value)
357
408
  for index, data in self:__iter() do
358
409
  list[index] = data
@@ -364,7 +415,7 @@ end
364
415
  Observes the count of the list
365
416
  @return Observable<number>
366
417
  ]=]
367
- function ObservableSortedList:ObserveCount()
418
+ function ObservableSortedList.ObserveCount<T>(self: ObservableSortedList<T>): Observable.Observable<number>
368
419
  return self._countValue:Observe()
369
420
  end
370
421
 
@@ -374,7 +425,11 @@ end
374
425
  @param observeValue Observable<Comparable> | Comparable
375
426
  @return callback -- Call to remove
376
427
  ]=]
377
- function ObservableSortedList:Add(data, observeValue)
428
+ function ObservableSortedList.Add<T>(
429
+ self: ObservableSortedList<T>,
430
+ data: T,
431
+ observeValue: Observable.Observable<number> | number
432
+ ): () -> ()
378
433
  assert(data ~= nil, "Bad data")
379
434
  assert(Observable.isObservable(observeValue) or observeValue ~= nil, "Bad observeValue")
380
435
 
@@ -384,7 +439,7 @@ function ObservableSortedList:Add(data, observeValue)
384
439
  local maid = Maid.new()
385
440
 
386
441
  if Observable.isObservable(observeValue) then
387
- maid:GiveTask(observeValue:Subscribe(function(sortValue)
442
+ maid:GiveTask((observeValue :: any):Subscribe(function(sortValue: number)
388
443
  self:_assignSortValue(node, sortValue)
389
444
  end))
390
445
  elseif observeValue ~= nil then
@@ -406,9 +461,13 @@ function ObservableSortedList:Add(data, observeValue)
406
461
  end
407
462
  end
408
463
 
409
- function ObservableSortedList:_assignSortValue(node, value)
464
+ function ObservableSortedList._assignSortValue<T>(
465
+ self: ObservableSortedList<T>,
466
+ node: SortedNode.SortedNode<T>,
467
+ value: number?
468
+ ): ()
410
469
  if SortedNodeValue.isSortedNodeValue(node.value) then
411
- if node.value:GetValue() == value then
470
+ if (node.value :: any):GetValue() == value then
412
471
  return
413
472
  end
414
473
  elseif node.value == value then
@@ -435,7 +494,7 @@ function ObservableSortedList:_assignSortValue(node, value)
435
494
  end
436
495
 
437
496
  if self._compare ~= nil then
438
- value = SortedNodeValue.new(value, self._compare)
497
+ value = SortedNodeValue.new(value, self._compare) :: any
439
498
  end
440
499
 
441
500
  -- our value changing didn't change anything
@@ -460,7 +519,7 @@ function ObservableSortedList:_assignSortValue(node, value)
460
519
  self:_queueFireEvents()
461
520
  end
462
521
 
463
- function ObservableSortedList:_applyLowestIndexChanged(index)
522
+ function ObservableSortedList._applyLowestIndexChanged<T>(self: ObservableSortedList<T>, index: number)
464
523
  if self._lowestIndexChanged == nil then
465
524
  self._lowestIndexChanged = index
466
525
  return
@@ -471,7 +530,7 @@ function ObservableSortedList:_applyLowestIndexChanged(index)
471
530
  end
472
531
  end
473
532
 
474
- function ObservableSortedList:_queueFireEvents()
533
+ function ObservableSortedList._queueFireEvents<T>(self: ObservableSortedList<T>)
475
534
  if self._maid._fireEvents then
476
535
  return
477
536
  end
@@ -482,7 +541,7 @@ function ObservableSortedList:_queueFireEvents()
482
541
  end)
483
542
  end
484
543
 
485
- function ObservableSortedList:_fireEvents()
544
+ function ObservableSortedList._fireEvents<T>(self: ObservableSortedList<T>)
486
545
  -- print(self._root)
487
546
 
488
547
  local lowestIndexChanged = self._lowestIndexChanged
@@ -500,7 +559,9 @@ function ObservableSortedList:_fireEvents()
500
559
  -- Fire count changed first
501
560
  self._countValue.Value = newCount
502
561
 
503
- if not self.Destroy then return end
562
+ if not self.Destroy then
563
+ return
564
+ end
504
565
 
505
566
  -- TODO: Prevent Rx.of(itemAdded) stuff in our UI
506
567
  for node in nodesAdded do
@@ -509,37 +570,46 @@ function ObservableSortedList:_fireEvents()
509
570
  self.ItemAdded:Fire(node.data, index, node)
510
571
  end
511
572
 
512
- if not self.Destroy then return end
573
+ if not self.Destroy then
574
+ return
575
+ end
513
576
 
514
577
  for node in nodesRemoved do
515
578
  self.ItemRemoved:Fire(node.data, node)
516
579
  end
517
580
 
518
- if not self.Destroy then return end
581
+ if not self.Destroy then
582
+ return
583
+ end
519
584
 
520
585
  self.OrderChanged:Fire()
521
586
 
522
- if not self.Destroy then return end
587
+ if not self.Destroy then
588
+ return
589
+ end
523
590
 
524
591
  do
592
+ local descendantCount = self._root and self._root.descendantCount or 0
525
593
  for index, node in self:_iterateNodesRange(lowestIndexChanged) do
526
594
  -- TODO: Handle negative observations to avoid refiring upon insertion
527
595
  -- TODO: Handle our state changing while we're firing
528
596
  -- TODO: Avoid looping over nodes if we don't need to (track observations in node itself?)
529
- local negative = ListIndexUtils.toNegativeIndex(self._root.descendantCount, index)
597
+ local negative = ListIndexUtils.toNegativeIndex(descendantCount, index)
530
598
  self._nodeIndexObservables:Fire(node, index)
531
599
  self._indexObservers:Fire(index, node.data, node)
532
600
  self._indexObservers:Fire(negative, node.data, node)
533
601
  end
534
602
 
535
- for index=newCount+1, lastCount do
603
+ for index = newCount + 1, lastCount do
536
604
  self._indexObservers:Fire(index, nil, nil)
537
605
  end
538
606
 
539
607
  -- TODO: Fire negatives beyond range
540
608
  end
541
609
 
542
- if not self.Destroy then return end
610
+ if not self.Destroy then
611
+ return
612
+ end
543
613
 
544
614
  if self._mainObservables:HasSubscriptions("list") then
545
615
  -- TODO: Reuse list
@@ -548,7 +618,7 @@ function ObservableSortedList:_fireEvents()
548
618
  end
549
619
  end
550
620
 
551
- function ObservableSortedList:_insertNode(node)
621
+ function ObservableSortedList._insertNode<T>(self: ObservableSortedList<T>, node: SortedNode.SortedNode<T>)
552
622
  assert(SortedNode.isSortedNode(node), "Bad SortedNode")
553
623
 
554
624
  if self._root == nil then
@@ -559,7 +629,7 @@ function ObservableSortedList:_insertNode(node)
559
629
  end
560
630
  end
561
631
 
562
- function ObservableSortedList:_removeNode(nodeToRemove)
632
+ function ObservableSortedList._removeNode<T>(self: ObservableSortedList<T>, nodeToRemove: SortedNode.SortedNode<T>)
563
633
  assert(SortedNode.isSortedNode(nodeToRemove), "Bad SortedNode")
564
634
 
565
635
  if self._root ~= nil then
@@ -572,7 +642,7 @@ end
572
642
  @param index number
573
643
  @return T?
574
644
  ]=]
575
- function ObservableSortedList:Get(index)
645
+ function ObservableSortedList.Get<T>(self: ObservableSortedList<T>, index: number): T?
576
646
  assert(type(index) == "number", "Bad index")
577
647
 
578
648
  local node = self:_findNodeAtIndex(index)
@@ -588,18 +658,18 @@ end
588
658
  @param node SortedNode
589
659
  @return T
590
660
  ]=]
591
- function ObservableSortedList:RemoveByKey(node)
661
+ function ObservableSortedList.RemoveByKey<T>(self: ObservableSortedList<T>, node: SortedNode.SortedNode<T>)
592
662
  assert(SortedNode.isSortedNode(node), "Bad node")
593
663
 
594
- self._maid[node] = nil
664
+ self._maid[node :: any] = nil
595
665
  end
596
666
 
597
667
  --[=[
598
668
  Cleans up the ObservableSortedList and sets the metatable to nil.
599
669
  ]=]
600
- function ObservableSortedList:Destroy()
670
+ function ObservableSortedList.Destroy<T>(self: ObservableSortedList<T>)
601
671
  self._maid:DoCleaning()
602
- setmetatable(self, nil)
672
+ setmetatable(self :: any, nil)
603
673
  end
604
674
 
605
675
  return ObservableSortedList
@@ -48,7 +48,7 @@ return function(target)
48
48
  local results = {}
49
49
  local inOrder = true
50
50
  local lastValue = nil
51
- for _, item in pairs(observableSortedList:GetList()) do
51
+ for _, item in observableSortedList:GetList() do
52
52
  if lastValue then
53
53
  if item.scoreValue.Value < lastValue then
54
54
  inOrder = false
@@ -1,20 +1,37 @@
1
+ --!strict
1
2
  --[=[
2
3
  @class SortFunctionUtils
3
4
  ]=]
4
5
 
5
- local require = require(script.Parent.loader).load(script)
6
-
7
6
  local SortFunctionUtils = {}
8
7
 
9
- function SortFunctionUtils.reverse(compare)
10
- compare = compare or SortFunctionUtils.default
11
- return function(a, b)
12
- return compare(b, a)
8
+ export type SortFunction<T> = (a: T, b: T) -> number
9
+
10
+ export type WrappedIterator<T...> = (...any) -> T...
11
+
12
+ --[=[
13
+ Reverses a given sort function
14
+
15
+ @param compare (a: T, b: T) -> number
16
+ @return (a: T, b: T) -> number
17
+ ]=]
18
+ function SortFunctionUtils.reverse<T>(compare: SortFunction<T>?): SortFunction<T>
19
+ local comparison = compare or SortFunctionUtils.default
20
+ return function(a: T, b: T): number
21
+ return (comparison :: any)(b, a)
13
22
  end
14
23
  end
15
24
 
16
- -- Higher numbers last
17
- function SortFunctionUtils.default(a, b)
25
+ --[=[
26
+ Sorts a given list of items using the given compare function
27
+
28
+ Higher numbers last
29
+
30
+ @param a T
31
+ @param b T
32
+ @return number
33
+ ]=]
34
+ function SortFunctionUtils.default(a: any, b: any): number
18
35
  -- equivalent of `return a - b` except it supports comparison of strings and stuff
19
36
  if b > a then
20
37
  return -1