@quenty/observablecollection 12.10.1-canary.513.484c203.0 → 12.11.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,17 +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
- ## [12.10.1-canary.513.484c203.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@12.10.0...@quenty/observablecollection@12.10.1-canary.513.484c203.0) (2024-10-24)
6
+ ## [12.11.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@12.11.0...@quenty/observablecollection@12.11.1) (2024-11-04)
7
7
 
8
+ **Note:** Version bump only for package @quenty/observablecollection
8
9
 
9
- ### Features
10
10
 
11
- * Add __iter implementations ([b8e614a](https://github.com/Quenty/NevermoreEngine/commit/b8e614a8fda875c03237dc6cde18cf817beec0c4))
12
11
 
13
12
 
14
- ### Performance Improvements
15
13
 
16
- * Use ObservableSubscriptionTable and stop debug validating integrity ([dbe74ba](https://github.com/Quenty/NevermoreEngine/commit/dbe74ba23b3b541f687999e22e60322fe11bbd2c))
14
+ # [12.11.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@12.10.0...@quenty/observablecollection@12.11.0) (2024-11-03)
15
+
16
+ **Note:** Version bump only for package @quenty/observablecollection
17
17
 
18
18
 
19
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/observablecollection",
3
- "version": "12.10.1-canary.513.484c203.0",
3
+ "version": "12.11.1",
4
4
  "description": "A set of observable collections, such as sets, maps, sorted lists, and more.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -27,23 +27,23 @@
27
27
  "Quenty"
28
28
  ],
29
29
  "dependencies": {
30
- "@quenty/baseobject": "10.7.0",
31
- "@quenty/brio": "14.10.1-canary.513.484c203.0",
32
- "@quenty/ducktype": "5.7.0",
33
- "@quenty/loader": "10.7.0",
34
- "@quenty/maid": "3.4.0",
35
- "@quenty/promise": "10.7.1-canary.513.484c203.0",
36
- "@quenty/rx": "13.10.1-canary.513.484c203.0",
37
- "@quenty/signal": "7.8.0",
38
- "@quenty/steputils": "3.5.2",
39
- "@quenty/symbol": "3.2.0",
40
- "@quenty/valueobject": "13.10.1-canary.513.484c203.0"
30
+ "@quenty/baseobject": "^10.7.1",
31
+ "@quenty/brio": "^14.11.1",
32
+ "@quenty/ducktype": "^5.7.1",
33
+ "@quenty/loader": "^10.7.1",
34
+ "@quenty/maid": "^3.4.0",
35
+ "@quenty/promise": "^10.7.1",
36
+ "@quenty/rx": "^13.11.1",
37
+ "@quenty/signal": "^7.8.1",
38
+ "@quenty/steputils": "^3.5.2",
39
+ "@quenty/symbol": "^3.2.0",
40
+ "@quenty/valueobject": "^13.11.1"
41
41
  },
42
42
  "devDependencies": {
43
- "@quenty/blend": "12.10.1-canary.513.484c203.0"
43
+ "@quenty/blend": "^12.11.1"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "484c2031829caf7e983cae58a6aa6f0ceef1d059"
48
+ "gitHead": "01c43a0ddd3c5e0cb2d9027313dbfa9852eedef1"
49
49
  }
@@ -73,15 +73,6 @@ function ObservableCountingMap.isObservableMap(value)
73
73
  return DuckTypeUtils.isImplementation(ObservableCountingMap, value)
74
74
  end
75
75
 
76
- --[=[
77
- Allows iteration over the observable counting map
78
-
79
- @return (T) -> ((T, nextIndex: any) -> ...any, T?)
80
- ]=]
81
- function ObservableCountingMap:__iter()
82
- return pairs(self._map)
83
- end
84
-
85
76
  --[=[
86
77
  Observes the current set of active keys
87
78
  @return Observable<{ T }>
@@ -89,19 +89,6 @@ function ObservableList:Observe()
89
89
  })
90
90
  end
91
91
 
92
- --[=[
93
- Allows iteration over the observable map
94
-
95
- @return (T) -> ((T, nextIndex: any) -> ...any, T?)
96
- ]=]
97
- function ObservableList:__iter()
98
- return coroutine.wrap(function()
99
- for index, value in self._keyList do
100
- coroutine.yield(index, self._contents[value])
101
- end
102
- end)
103
- end
104
-
105
92
  --[=[
106
93
  Observes all items in the list
107
94
  @return Observable<Brio<T>>
@@ -74,16 +74,6 @@ function ObservableMap.isObservableMap(value)
74
74
  return DuckTypeUtils.isImplementation(ObservableMap, value)
75
75
  end
76
76
 
77
- --[=[
78
- Allows iteration over the observable map
79
-
80
- @return (T) -> ((T, nextIndex: any) -> ...any, T?)
81
- ]=]
82
- function ObservableMap:__iter()
83
- return pairs(self._map)
84
- end
85
-
86
-
87
77
  --[=[
88
78
  Observes all keys in the map
89
79
  @return Observable<Brio<TKey>>
@@ -65,15 +65,6 @@ function ObservableSet.isObservableSet(value)
65
65
  return DuckTypeUtils.isImplementation(ObservableSet, value)
66
66
  end
67
67
 
68
- --[=[
69
- Allows iteration over the observable set
70
-
71
- @return (T) -> ((T, nextIndex: any) -> ...any, T?)
72
- ]=]
73
- function ObservableSet:__iter()
74
- return pairs(self._set)
75
- end
76
-
77
68
  --[=[
78
69
  Observes all items in the set
79
70
  @return Observable<Brio<T>>
@@ -60,12 +60,13 @@ function ObservableSortedList.new(isReversed, compare)
60
60
 
61
61
  self._indexObservers = self._maid:Add(ObservableSubscriptionTable.new())
62
62
  self._contentIndexObservers = self._maid:Add(ObservableSubscriptionTable.new())
63
- self._keyObservables = self._maid:Add(ObservableSubscriptionTable.new())
64
63
 
65
64
  self._sortValue = {} -- { [Symbol]: number }
66
65
  self._contents = {} -- { [Symbol]: T }
67
66
  self._indexes = {} -- { [Symbol]: number }
68
67
 
68
+ self._keyObservables = {} -- { [Symbol]: { Subscription } }
69
+
69
70
  self._isReversed = isReversed or false
70
71
  self._compare = compare or defaultCompare
71
72
 
@@ -123,19 +124,6 @@ function ObservableSortedList:Observe()
123
124
  })
124
125
  end
125
126
 
126
- --[=[
127
- Allows iteration over the observable map
128
-
129
- @return (T) -> ((T, nextIndex: any) -> ...any, T?)
130
- ]=]
131
- function ObservableSortedList:__iter()
132
- return coroutine.wrap(function()
133
- for index, value in self._keyList do
134
- coroutine.yield(index, self._contents[value])
135
- end
136
- end)
137
- end
138
-
139
127
  function ObservableSortedList:Contains(value)
140
128
  -- TODO: Binary search
141
129
  for _, item in pairs(self._contents) do
@@ -251,16 +239,33 @@ end
251
239
  function ObservableSortedList:ObserveIndexByKey(key)
252
240
  assert(Symbol.isSymbol(key), "Bad key")
253
241
 
254
- return self._keyObservables:Observe(key):Pipe({
255
- Rx.startFrom(function()
256
- local currentIndex = self._indexes[key]
257
- if currentIndex then
258
- return { currentIndex }
259
- else
260
- return {}
242
+ return Observable.new(function(sub)
243
+ local maid = Maid.new()
244
+ self._keyObservables[key] = self._keyObservables[key] or {}
245
+ table.insert(self._keyObservables[key], sub)
246
+
247
+ local currentIndex = self._indexes[key]
248
+ if currentIndex then
249
+ sub:Fire(currentIndex)
250
+ end
251
+
252
+ maid:GiveTask(function()
253
+ local list = self._keyObservables[key]
254
+ if not list then
255
+ return
261
256
  end
262
- end);
263
- })
257
+
258
+ local index = table.find(list, sub)
259
+ if index then
260
+ table.remove(list, index)
261
+ if #list == 0 then
262
+ self._keyObservables[key] = nil
263
+ end
264
+ end
265
+ end)
266
+
267
+ return maid
268
+ end)
264
269
  end
265
270
 
266
271
  --[=[
@@ -332,10 +337,15 @@ function ObservableSortedList:Add(item, observeValue)
332
337
  end
333
338
 
334
339
  maid:GiveTask(function()
340
+ local observableSubs = self._keyObservables[key]
341
+ self._keyObservables[key] = nil
342
+
335
343
  self:_removeItemByKey(key, item)
336
344
 
337
345
  -- Fire off the index change on the value
338
- self._keyObservables:Complete(key)
346
+ if observableSubs then
347
+ self:_completeSubs(observableSubs)
348
+ end
339
349
 
340
350
  self._contents[key] = nil
341
351
  self._sortValue[key] = nil
@@ -349,7 +359,7 @@ function ObservableSortedList:Add(item, observeValue)
349
359
  end
350
360
 
351
361
  function ObservableSortedList:_assignSortValue(key, item, sortValue)
352
- -- self:_debugVerifyIntegrity()
362
+ self:_debugVerifyIntegrity()
353
363
 
354
364
  if sortValue ~= nil then
355
365
  local currentIndex = self._indexes[key]
@@ -358,12 +368,18 @@ function ObservableSortedList:_assignSortValue(key, item, sortValue)
358
368
  self._sortValue[key] = sortValue
359
369
  self:_updateIndex(key, item, targetIndex, sortValue)
360
370
  else
371
+ local observableSubs = self._keyObservables[key]
372
+
361
373
  -- calling this also may unsubscribe some observables.
362
374
  self:_removeItemByKey(key, item)
363
- self._keyObservables:Complete(key)
375
+
376
+ if observableSubs then
377
+ -- fire nil index
378
+ self:_fireSubs(observableSubs, nil)
379
+ end
364
380
  end
365
381
 
366
- -- self:_debugVerifyIntegrity()
382
+ self:_debugVerifyIntegrity()
367
383
  end
368
384
 
369
385
 
@@ -580,7 +596,11 @@ function ObservableSortedList:_queueDeferredChange()
580
596
  if self._indexes[lastChange.key] == lastChange.newIndex then
581
597
  changed = true
582
598
 
583
- self._keyObservables:Fire(lastChange.key, lastChange.newIndex)
599
+ local subs = self._keyObservables[lastChange.key]
600
+ if subs then
601
+ self:_fireSubs(subs, lastChange.newIndex)
602
+ end
603
+
584
604
  self._indexObservers:Fire(lastChange.newIndex, self._contents[lastChange.key])
585
605
  end
586
606
  end
@@ -662,9 +682,7 @@ function ObservableSortedList:_lowBinarySearch(sortValue)
662
682
  while true do
663
683
  local mid = math.floor((minIndex + maxIndex) / 2)
664
684
  local compareValue = self._compare(self._sortValue[self._keyList[mid]], sortValue)
665
- if type(compareValue) ~= "number" then
666
- error(string.format("Bad compareValue, expected number, got %q", type(compareValue)))
667
- end
685
+ assert(type(compareValue) == "number", "Expecting number")
668
686
 
669
687
  if self._isReversed then
670
688
  compareValue = -compareValue
@@ -684,6 +702,16 @@ function ObservableSortedList:_lowBinarySearch(sortValue)
684
702
  end
685
703
  end
686
704
 
705
+ function ObservableSortedList:_debugSortValuesToString()
706
+ local values = {}
707
+
708
+ for _, key in pairs(self._keyList) do
709
+ table.insert(values, string.format("%4d", self._sortValue[key]))
710
+ end
711
+
712
+ return table.concat(values, ", ")
713
+ end
714
+
687
715
  function ObservableSortedList:_debugVerifyIntegrity()
688
716
  for i=2, #self._keyList do
689
717
  local compare = self._compare(self._sortValue[self._keyList[i-1]], self._sortValue[self._keyList[i]])
@@ -702,14 +730,23 @@ function ObservableSortedList:_debugVerifyIntegrity()
702
730
  end
703
731
  end
704
732
 
705
- function ObservableSortedList:_debugSortValuesToString()
706
- local values = {}
707
-
708
- for _, key in pairs(self._keyList) do
709
- table.insert(values, string.format("%4d", self._sortValue[key]))
733
+ function ObservableSortedList:_fireSubs(list, index)
734
+ for _, sub in pairs(list) do
735
+ if sub:IsPending() then
736
+ task.spawn(function()
737
+ sub:Fire(index)
738
+ end)
739
+ end
710
740
  end
741
+ end
711
742
 
712
- return table.concat(values, ", ")
743
+ function ObservableSortedList:_completeSubs(list)
744
+ for _, sub in pairs(list) do
745
+ if sub:IsPending() then
746
+ sub:Fire(nil)
747
+ sub:Complete()
748
+ end
749
+ end
713
750
  end
714
751
 
715
752
  --[=[