@quenty/observablecollection 12.40.0 → 12.41.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 +6 -0
- package/package.json +10 -10
- package/src/Shared/ObservableCountingMap.spec.lua +2 -4
- package/src/Shared/ObservableList.spec.lua +3 -5
- package/src/Shared/ObservableMap.spec.lua +5 -7
- package/src/Shared/ObservableMapList.spec.lua +2 -4
- package/src/Shared/SortedList/ObservableSortedList.spec.lua +13 -14
- package/src/Shared/SortedList/SortFunctionUtils.spec.lua +2 -4
- package/src/Shared/SortedList/SortedNode.spec.lua +1 -3
- package/src/Shared/SortedList/SortedNodeValue.lua +7 -0
- package/src/Shared/SortedList/SortedNodeValue.spec.lua +1 -3
- package/src/Shared/SortedList/UnifiedChangedSpanTracker.spec.lua +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
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.41.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@12.40.0...@quenty/observablecollection@12.41.0) (2026-07-18)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- pin translation behavior with tests and fix camelCase key generation ([#737](https://github.com/Quenty/NevermoreEngine/issues/737)) ([1b7a536](https://github.com/Quenty/NevermoreEngine/commit/1b7a536dde7e124f8432e57612ec8138dd835d75))
|
|
11
|
+
|
|
6
12
|
# [12.40.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/observablecollection@12.39.0...@quenty/observablecollection@12.40.0) (2026-07-18)
|
|
7
13
|
|
|
8
14
|
**Note:** Version bump only for package @quenty/observablecollection
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/observablecollection",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.41.0",
|
|
4
4
|
"description": "A set of observable collections, such as sets, maps, sorted lists, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -30,28 +30,28 @@
|
|
|
30
30
|
"Quenty"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@quenty/baseobject": "10.
|
|
33
|
+
"@quenty/baseobject": "10.14.0",
|
|
34
34
|
"@quenty/binarysearch": "2.4.0",
|
|
35
|
-
"@quenty/brio": "14.
|
|
35
|
+
"@quenty/brio": "14.32.0",
|
|
36
36
|
"@quenty/ducktype": "5.11.0",
|
|
37
|
-
"@quenty/instanceutils": "13.
|
|
37
|
+
"@quenty/instanceutils": "13.32.0",
|
|
38
38
|
"@quenty/loader": "10.11.0",
|
|
39
|
-
"@quenty/maid": "3.
|
|
39
|
+
"@quenty/maid": "3.10.0",
|
|
40
40
|
"@quenty/nevermore-test-runner": "1.4.0",
|
|
41
|
-
"@quenty/promise": "10.
|
|
42
|
-
"@quenty/rx": "13.
|
|
41
|
+
"@quenty/promise": "10.20.0",
|
|
42
|
+
"@quenty/rx": "13.30.0",
|
|
43
43
|
"@quenty/signal": "7.13.1",
|
|
44
44
|
"@quenty/steputils": "3.6.3",
|
|
45
45
|
"@quenty/symbol": "3.5.2",
|
|
46
46
|
"@quenty/table": "3.9.2",
|
|
47
|
-
"@quenty/valueobject": "13.
|
|
47
|
+
"@quenty/valueobject": "13.33.0",
|
|
48
48
|
"@quentystudios/jest-lua": "3.10.0-quenty.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@quenty/blend": "12.
|
|
51
|
+
"@quenty/blend": "12.39.0"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "647acfad93dca41c38f59cda247d2bfc0fff36d4"
|
|
57
57
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
--!
|
|
1
|
+
--!strict
|
|
2
2
|
--[[
|
|
3
3
|
@class ObservableCountingMap.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local ObservableCountingMap = require("ObservableCountingMap")
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
--!
|
|
1
|
+
--!strict
|
|
2
2
|
--[[
|
|
3
3
|
@class ObservableList.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local ObservableList = require("ObservableList")
|
|
@@ -37,7 +35,7 @@ describe("ObservableList.new()", function()
|
|
|
37
35
|
|
|
38
36
|
it("should allow false as a value", function()
|
|
39
37
|
expect(observableList:Get(2)).toEqual(nil)
|
|
40
|
-
observableList:Add(false)
|
|
38
|
+
observableList:Add(false :: any)
|
|
41
39
|
expect(observableList:Get(2)).toEqual(false)
|
|
42
40
|
end)
|
|
43
41
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
--!
|
|
1
|
+
--!strict
|
|
2
2
|
--[[
|
|
3
3
|
@class ObservableMap.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local ObservableMap = require("ObservableMap")
|
|
@@ -39,9 +37,9 @@ describe("ObservableMap.new()", function()
|
|
|
39
37
|
end)
|
|
40
38
|
|
|
41
39
|
it("should allow false as a key", function()
|
|
42
|
-
expect(observableMap:Get(false)).toEqual(nil)
|
|
43
|
-
observableMap:Set(false, "Hello")
|
|
44
|
-
expect(observableMap:Get(false)).toEqual("Hello")
|
|
40
|
+
expect(observableMap:Get(false :: any)).toEqual(nil)
|
|
41
|
+
observableMap:Set(false :: any, "Hello")
|
|
42
|
+
expect(observableMap:Get(false :: any)).toEqual("Hello")
|
|
45
43
|
end)
|
|
46
44
|
|
|
47
45
|
it("should fire off events for a specific key", function()
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
--!
|
|
1
|
+
--!strict
|
|
2
2
|
--[[
|
|
3
3
|
@class ObservableMapList.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local ObservableMapList = require("ObservableMapList")
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
@class ObservableSortedList.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Brio = require("Brio")
|
|
11
9
|
local Jest = require("Jest")
|
|
@@ -59,8 +57,9 @@ describe("ObservableSortedList", function()
|
|
|
59
57
|
it("should accept an observable as sort value", function()
|
|
60
58
|
local maid = Maid.new()
|
|
61
59
|
local list = maid:Add(ObservableSortedList.new())
|
|
62
|
-
|
|
63
|
-
list:Add("
|
|
60
|
+
-- Cast: the recursive Observable type does not unify structurally inside Add's union.
|
|
61
|
+
list:Add("b", Rx.of(2) :: any)
|
|
62
|
+
list:Add("a", Rx.of(1) :: any)
|
|
64
63
|
|
|
65
64
|
expect(list:Get(1)).toEqual("a")
|
|
66
65
|
expect(list:Get(2)).toEqual("b")
|
|
@@ -332,7 +331,7 @@ describe("ObservableSortedList", function()
|
|
|
332
331
|
local removeA = list:Add("a", 1)
|
|
333
332
|
list:_testForceFireEvents()
|
|
334
333
|
|
|
335
|
-
local seenBrios: { Brio.Brio<string> } = {}
|
|
334
|
+
local seenBrios: { Brio.Brio<string, any> } = {}
|
|
336
335
|
local sub = list:ObserveItemsBrio():Subscribe(function(brio)
|
|
337
336
|
table.insert(seenBrios, brio)
|
|
338
337
|
end)
|
|
@@ -917,7 +916,7 @@ describe("ObservableSortedList", function()
|
|
|
917
916
|
expect(list:GetList()).toEqual({ "a", "b", "c" })
|
|
918
917
|
|
|
919
918
|
-- Emit nil - B should be removed from tree
|
|
920
|
-
sortValue.Value = nil
|
|
919
|
+
sortValue.Value = nil :: any
|
|
921
920
|
expect(list:GetList()).toEqual({ "a", "c" })
|
|
922
921
|
expect(list:Contains("b")).toEqual(false)
|
|
923
922
|
|
|
@@ -943,7 +942,7 @@ describe("ObservableSortedList", function()
|
|
|
943
942
|
expect(seenBrios[2]:IsDead()).toEqual(false)
|
|
944
943
|
|
|
945
944
|
-- Emit nil - B's brio should die
|
|
946
|
-
sortValue.Value = nil
|
|
945
|
+
sortValue.Value = nil :: any
|
|
947
946
|
list:_testForceFireEvents()
|
|
948
947
|
|
|
949
948
|
expect(seenBrios[2]:IsDead()).toEqual(true)
|
|
@@ -958,7 +957,7 @@ describe("ObservableSortedList", function()
|
|
|
958
957
|
local list = maid:Add(ObservableSortedList.new())
|
|
959
958
|
|
|
960
959
|
list:Add("a", 1)
|
|
961
|
-
list:Add("b", Rx.EMPTY)
|
|
960
|
+
list:Add("b", Rx.EMPTY :: any)
|
|
962
961
|
list:Add("c", 3)
|
|
963
962
|
|
|
964
963
|
-- B should never enter the tree
|
|
@@ -989,7 +988,7 @@ describe("ObservableSortedList", function()
|
|
|
989
988
|
expect(list:GetList()).toEqual({ "a", "b", "c" })
|
|
990
989
|
|
|
991
990
|
-- Disappear
|
|
992
|
-
sortValue.Value = nil
|
|
991
|
+
sortValue.Value = nil :: any
|
|
993
992
|
expect(list:GetList()).toEqual({ "a", "c" })
|
|
994
993
|
|
|
995
994
|
-- Reappear at different position
|
|
@@ -1012,7 +1011,7 @@ describe("ObservableSortedList", function()
|
|
|
1012
1011
|
expect(list:GetList()).toEqual({ "a", "b", "c" })
|
|
1013
1012
|
|
|
1014
1013
|
-- Go nil then come back in the same frame
|
|
1015
|
-
sortValue.Value = nil
|
|
1014
|
+
sortValue.Value = nil :: any
|
|
1016
1015
|
sortValue.Value = 2
|
|
1017
1016
|
|
|
1018
1017
|
expect(list:GetList()).toEqual({ "a", "b", "c" })
|
|
@@ -1134,7 +1133,7 @@ describe("ObservableSortedList", function()
|
|
|
1134
1133
|
expect(list:GetList()).toEqual({ "a", "b" })
|
|
1135
1134
|
|
|
1136
1135
|
-- Set nil (removes from tree) then also call cleanup
|
|
1137
|
-
sortValue.Value = nil
|
|
1136
|
+
sortValue.Value = nil :: any
|
|
1138
1137
|
remove()
|
|
1139
1138
|
|
|
1140
1139
|
expect(list:GetList()).toEqual({ "a" })
|
|
@@ -1248,7 +1247,7 @@ describe("ObservableSortedList", function()
|
|
|
1248
1247
|
list:Add("b", sortValue:Observe())
|
|
1249
1248
|
list:_testForceFireEvents()
|
|
1250
1249
|
|
|
1251
|
-
local seenBrios: { Brio.Brio<string> } = {}
|
|
1250
|
+
local seenBrios: { Brio.Brio<string, any> } = {}
|
|
1252
1251
|
local sub = list:ObserveItemsBrio():Subscribe(function(brio)
|
|
1253
1252
|
table.insert(seenBrios, brio)
|
|
1254
1253
|
end)
|
|
@@ -1256,7 +1255,7 @@ describe("ObservableSortedList", function()
|
|
|
1256
1255
|
expect(#seenBrios).toEqual(2)
|
|
1257
1256
|
|
|
1258
1257
|
-- Remove via nil
|
|
1259
|
-
sortValue.Value = nil
|
|
1258
|
+
sortValue.Value = nil :: any
|
|
1260
1259
|
list:_testForceFireEvents()
|
|
1261
1260
|
|
|
1262
1261
|
expect(seenBrios[2]:IsDead()).toEqual(true)
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
@class SortFunctionUtils.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local SortFunctionUtils = require("SortFunctionUtils")
|
|
@@ -59,7 +57,7 @@ describe("SortFunctionUtils", function()
|
|
|
59
57
|
describe("emptyIterator", function()
|
|
60
58
|
it("should return nothing", function()
|
|
61
59
|
local count = 0
|
|
62
|
-
for _ in SortFunctionUtils.emptyIterator do
|
|
60
|
+
for _ in SortFunctionUtils.emptyIterator :: any do
|
|
63
61
|
count += 1
|
|
64
62
|
end
|
|
65
63
|
expect(count).toEqual(0)
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
@class SortedNode.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local SortedNode = require("SortedNode")
|
|
@@ -70,6 +70,13 @@ function SortedNodeValue.__lt<T>(self: SortedNodeValue<T>, other: SortedNodeValu
|
|
|
70
70
|
return self._compare(self._value, other._value) < 0
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
function SortedNodeValue.__le<T>(self: SortedNodeValue<T>, other: SortedNodeValue<T>): boolean
|
|
74
|
+
assert(SortedNodeValue.isSortedNodeValue(other), "Bad other")
|
|
75
|
+
assert(other._compare == self._compare, "Bad compare")
|
|
76
|
+
|
|
77
|
+
return self._compare(self._value, other._value) <= 0
|
|
78
|
+
end
|
|
79
|
+
|
|
73
80
|
function SortedNodeValue.__gt<T>(self: SortedNodeValue<T>, other: SortedNodeValue<T>): boolean
|
|
74
81
|
assert(SortedNodeValue.isSortedNodeValue(other), "Bad other")
|
|
75
82
|
assert(other._compare == self._compare, "Bad compare")
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
@class SortedNodeValue.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local SortFunctionUtils = require("SortFunctionUtils")
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
@class UnifiedChangedSpanTracker.spec.lua
|
|
4
4
|
]]
|
|
5
5
|
|
|
6
|
-
local require = (
|
|
7
|
-
game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
-
).bootstrapStory(script) :: typeof(require(script.Parent.loader).load(script))
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
7
|
|
|
10
8
|
local Jest = require("Jest")
|
|
11
9
|
local UnifiedChangedSpanTracker = require("UnifiedChangedSpanTracker")
|