@quenty/rx 8.1.1 → 8.2.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 +11 -0
- package/package.json +8 -8
- package/src/Shared/Rx.lua +44 -9
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
|
+
# [8.2.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/rx@8.1.1...@quenty/rx@8.2.0) (2023-12-14)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Rx.switchAll() and Rx.flatMap() could previously leak subscriptions if subscriptions were swapped during the emission of the signal itself ([a58da12](https://github.com/Quenty/NevermoreEngine/commit/a58da122eb4a710c932d9bd4b44231566e7f0b11))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [8.1.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/rx@8.1.0...@quenty/rx@8.1.1) (2023-10-28)
|
|
7
18
|
|
|
8
19
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/rx",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "Quenty's reactive library for Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -28,17 +28,17 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@quenty/cancellabledelay": "^3.4.0",
|
|
31
|
-
"@quenty/canceltoken": "^7.
|
|
32
|
-
"@quenty/loader": "^7.
|
|
31
|
+
"@quenty/canceltoken": "^7.1.0",
|
|
32
|
+
"@quenty/loader": "^7.1.0",
|
|
33
33
|
"@quenty/maid": "^2.6.0",
|
|
34
|
-
"@quenty/promise": "^7.
|
|
35
|
-
"@quenty/signal": "^3.
|
|
34
|
+
"@quenty/promise": "^7.1.0",
|
|
35
|
+
"@quenty/signal": "^3.1.0",
|
|
36
36
|
"@quenty/symbol": "^2.2.0",
|
|
37
|
-
"@quenty/table": "^3.
|
|
38
|
-
"@quenty/throttle": "^7.
|
|
37
|
+
"@quenty/table": "^3.4.0",
|
|
38
|
+
"@quenty/throttle": "^7.1.0"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "2c2dbbc0cb2fbb46b4f3270c559c63890fe18b26"
|
|
44
44
|
}
|
package/src/Shared/Rx.lua
CHANGED
|
@@ -182,15 +182,29 @@ end
|
|
|
182
182
|
function Rx.merge(observables)
|
|
183
183
|
assert(type(observables) == "table", "Bad observables")
|
|
184
184
|
|
|
185
|
+
local totalCount = 0
|
|
185
186
|
for _, item in pairs(observables) do
|
|
186
187
|
assert(Observable.isObservable(item), "Not an observable")
|
|
188
|
+
totalCount = totalCount + 1
|
|
187
189
|
end
|
|
188
190
|
|
|
189
191
|
return Observable.new(function(sub)
|
|
190
192
|
local maid = Maid.new()
|
|
193
|
+
local pendingCount = totalCount
|
|
191
194
|
|
|
192
195
|
for _, observable in pairs(observables) do
|
|
193
|
-
maid:GiveTask(observable:Subscribe(
|
|
196
|
+
maid:GiveTask(observable:Subscribe(function(...)
|
|
197
|
+
sub:Fire(...)
|
|
198
|
+
end, function(...)
|
|
199
|
+
pendingCount = pendingCount - 1
|
|
200
|
+
sub:Fail(...)
|
|
201
|
+
end, function()
|
|
202
|
+
-- Only complete once all are complete
|
|
203
|
+
pendingCount = pendingCount - 1
|
|
204
|
+
if pendingCount == 0 then
|
|
205
|
+
sub:Complete()
|
|
206
|
+
end
|
|
207
|
+
end))
|
|
194
208
|
end
|
|
195
209
|
|
|
196
210
|
return maid
|
|
@@ -966,9 +980,13 @@ function Rx.switchAll()
|
|
|
966
980
|
currentInside = observable
|
|
967
981
|
outerMaid._innerSub = nil
|
|
968
982
|
|
|
969
|
-
|
|
983
|
+
local subscription = observable:Subscribe(
|
|
970
984
|
function(...)
|
|
971
|
-
|
|
985
|
+
if currentInside == observable then
|
|
986
|
+
sub:Fire(...)
|
|
987
|
+
else
|
|
988
|
+
warn(string.format("[Rx.switchAll] - Observable is still firing despite disconnect (%q)", observable._source))
|
|
989
|
+
end
|
|
972
990
|
end, -- Merge each inner observable
|
|
973
991
|
function(...)
|
|
974
992
|
if currentInside == observable then
|
|
@@ -984,6 +1002,13 @@ function Rx.switchAll()
|
|
|
984
1002
|
end
|
|
985
1003
|
end
|
|
986
1004
|
end)
|
|
1005
|
+
|
|
1006
|
+
if currentInside == observable then
|
|
1007
|
+
outerMaid._innerSub = subscription
|
|
1008
|
+
else
|
|
1009
|
+
-- We cleaned up while connecting
|
|
1010
|
+
subscription:Destroy()
|
|
1011
|
+
end
|
|
987
1012
|
end,
|
|
988
1013
|
function(...)
|
|
989
1014
|
sub:Fail(...) -- Also reflect failures up to the top!
|
|
@@ -1034,7 +1059,7 @@ function Rx.flatMap(project, resultSelector)
|
|
|
1034
1059
|
|
|
1035
1060
|
local innerMaid = Maid.new()
|
|
1036
1061
|
|
|
1037
|
-
innerMaid:
|
|
1062
|
+
local subscription = innerMaid:Add(observable:Subscribe(
|
|
1038
1063
|
function(...)
|
|
1039
1064
|
-- Merge each inner observable
|
|
1040
1065
|
if resultSelector then
|
|
@@ -1055,12 +1080,16 @@ function Rx.flatMap(project, resultSelector)
|
|
|
1055
1080
|
end
|
|
1056
1081
|
end))
|
|
1057
1082
|
|
|
1058
|
-
|
|
1083
|
+
if subscription:IsPending() then
|
|
1084
|
+
local key = maid:GiveTask(innerMaid)
|
|
1059
1085
|
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1086
|
+
-- Cleanup
|
|
1087
|
+
innerMaid:GiveTask(function()
|
|
1088
|
+
maid[key] = nil
|
|
1089
|
+
end)
|
|
1090
|
+
else
|
|
1091
|
+
subscription:Destroy()
|
|
1092
|
+
end
|
|
1064
1093
|
end,
|
|
1065
1094
|
function(...)
|
|
1066
1095
|
sub:Fail(...) -- Also reflect failures up to the top!
|
|
@@ -1794,6 +1823,12 @@ end
|
|
|
1794
1823
|
|
|
1795
1824
|
--[=[
|
|
1796
1825
|
Throttles emission of observables on the defer stack to the last emission.
|
|
1826
|
+
|
|
1827
|
+
:::tip
|
|
1828
|
+
There's a limited re-entrance amount for this. However, this can prevent computation being done repeatedly if
|
|
1829
|
+
stuff is being added all at once. Use with care.
|
|
1830
|
+
:::
|
|
1831
|
+
|
|
1797
1832
|
@return (source: Observable) -> Observable
|
|
1798
1833
|
]=]
|
|
1799
1834
|
function Rx.throttleDefer()
|