@pezkuwi/types-codec 16.5.5

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.
Files changed (197) hide show
  1. package/README.md +3 -0
  2. package/build/abstract/Array.d.ts +89 -0
  3. package/build/abstract/Base.d.ts +75 -0
  4. package/build/abstract/Int.d.ts +80 -0
  5. package/build/abstract/Object.d.ts +67 -0
  6. package/build/abstract/index.d.ts +3 -0
  7. package/build/base/Compact.d.ts +88 -0
  8. package/build/base/DoNotConstruct.d.ts +63 -0
  9. package/build/base/Enum.d.ts +118 -0
  10. package/build/base/Int.d.ts +16 -0
  11. package/build/base/Null.d.ts +56 -0
  12. package/build/base/Option.d.ts +94 -0
  13. package/build/base/Result.d.ts +38 -0
  14. package/build/base/Tuple.d.ts +42 -0
  15. package/build/base/UInt.d.ts +15 -0
  16. package/build/base/Vec.d.ts +28 -0
  17. package/build/base/VecAny.d.ts +15 -0
  18. package/build/base/VecFixed.d.ts +30 -0
  19. package/build/base/index.d.ts +12 -0
  20. package/build/bundle.d.ts +7 -0
  21. package/build/extended/BTreeMap.d.ts +5 -0
  22. package/build/extended/BTreeSet.d.ts +64 -0
  23. package/build/extended/BitVec.d.ts +37 -0
  24. package/build/extended/Bytes.d.ts +29 -0
  25. package/build/extended/HashMap.d.ts +5 -0
  26. package/build/extended/Linkage.d.ts +37 -0
  27. package/build/extended/Map.d.ts +59 -0
  28. package/build/extended/OptionBool.d.ts +36 -0
  29. package/build/extended/Range.d.ts +29 -0
  30. package/build/extended/RangeInclusive.d.ts +6 -0
  31. package/build/extended/Type.d.ts +16 -0
  32. package/build/extended/U8aFixed.d.ts +16 -0
  33. package/build/extended/WrapperKeepOpaque.d.ts +40 -0
  34. package/build/extended/WrapperOpaque.d.ts +10 -0
  35. package/build/extended/index.d.ts +14 -0
  36. package/build/index.d.ts +2 -0
  37. package/build/native/Bool.d.ts +71 -0
  38. package/build/native/Date.d.ts +84 -0
  39. package/build/native/Float.d.ts +68 -0
  40. package/build/native/Json.d.ts +69 -0
  41. package/build/native/Raw.d.ts +87 -0
  42. package/build/native/Set.d.ts +84 -0
  43. package/build/native/Struct.d.ts +106 -0
  44. package/build/native/Text.d.ts +77 -0
  45. package/build/native/index.d.ts +8 -0
  46. package/build/packageDetect.d.ts +1 -0
  47. package/build/packageInfo.d.ts +6 -0
  48. package/build/primitive/F32.d.ts +11 -0
  49. package/build/primitive/F64.d.ts +11 -0
  50. package/build/primitive/I128.d.ts +11 -0
  51. package/build/primitive/I16.d.ts +11 -0
  52. package/build/primitive/I256.d.ts +11 -0
  53. package/build/primitive/I32.d.ts +11 -0
  54. package/build/primitive/I64.d.ts +11 -0
  55. package/build/primitive/I8.d.ts +11 -0
  56. package/build/primitive/ISize.d.ts +12 -0
  57. package/build/primitive/U128.d.ts +11 -0
  58. package/build/primitive/U16.d.ts +11 -0
  59. package/build/primitive/U256.d.ts +11 -0
  60. package/build/primitive/U32.d.ts +11 -0
  61. package/build/primitive/U64.d.ts +11 -0
  62. package/build/primitive/U8.d.ts +11 -0
  63. package/build/primitive/USize.d.ts +12 -0
  64. package/build/primitive/index.d.ts +16 -0
  65. package/build/types/codec.d.ts +113 -0
  66. package/build/types/helpers.d.ts +27 -0
  67. package/build/types/index.d.ts +4 -0
  68. package/build/types/interfaces.d.ts +74 -0
  69. package/build/types/registry.d.ts +67 -0
  70. package/build/utils/compareArray.d.ts +1 -0
  71. package/build/utils/compareMap.d.ts +1 -0
  72. package/build/utils/compareSet.d.ts +1 -0
  73. package/build/utils/decodeU8a.d.ts +26 -0
  74. package/build/utils/index.d.ts +8 -0
  75. package/build/utils/sanitize.d.ts +15 -0
  76. package/build/utils/sortValues.d.ts +12 -0
  77. package/build/utils/toConstructors.d.ts +16 -0
  78. package/build/utils/typesToMap.d.ts +2 -0
  79. package/build/utils/util.d.ts +3 -0
  80. package/package.json +34 -0
  81. package/src/abstract/Array.ts +213 -0
  82. package/src/abstract/Base.ts +129 -0
  83. package/src/abstract/Int.ts +271 -0
  84. package/src/abstract/Object.ts +99 -0
  85. package/src/abstract/index.ts +6 -0
  86. package/src/base/Compact.spec.ts +99 -0
  87. package/src/base/Compact.ts +198 -0
  88. package/src/base/DoNotConstruct.spec.ts +23 -0
  89. package/src/base/DoNotConstruct.ts +118 -0
  90. package/src/base/Enum.spec.ts +487 -0
  91. package/src/base/Enum.ts +460 -0
  92. package/src/base/Int.spec.ts +225 -0
  93. package/src/base/Int.ts +34 -0
  94. package/src/base/Null.spec.ts +41 -0
  95. package/src/base/Null.ts +96 -0
  96. package/src/base/Option.spec.ts +216 -0
  97. package/src/base/Option.ts +275 -0
  98. package/src/base/Result.spec.ts +64 -0
  99. package/src/base/Result.ts +79 -0
  100. package/src/base/Tuple.spec.ts +161 -0
  101. package/src/base/Tuple.ts +149 -0
  102. package/src/base/UInt.spec.ts +192 -0
  103. package/src/base/UInt.ts +30 -0
  104. package/src/base/Vec.spec.ts +224 -0
  105. package/src/base/Vec.ts +133 -0
  106. package/src/base/VecAny.ts +23 -0
  107. package/src/base/VecFixed.spec.ts +78 -0
  108. package/src/base/VecFixed.ts +92 -0
  109. package/src/base/index.ts +15 -0
  110. package/src/bundle.ts +13 -0
  111. package/src/checkTypes.manual.ts +12 -0
  112. package/src/extended/BTreeMap.spec.ts +245 -0
  113. package/src/extended/BTreeMap.ts +16 -0
  114. package/src/extended/BTreeSet.spec.ts +260 -0
  115. package/src/extended/BTreeSet.ts +233 -0
  116. package/src/extended/BitVec.spec.ts +97 -0
  117. package/src/extended/BitVec.ts +137 -0
  118. package/src/extended/Bytes.spec.ts +75 -0
  119. package/src/extended/Bytes.ts +88 -0
  120. package/src/extended/HashMap.spec.ts +36 -0
  121. package/src/extended/HashMap.ts +16 -0
  122. package/src/extended/Linkage.spec.ts +43 -0
  123. package/src/extended/Linkage.ts +81 -0
  124. package/src/extended/Map.spec.ts +123 -0
  125. package/src/extended/Map.ts +255 -0
  126. package/src/extended/OptionBool.spec.ts +49 -0
  127. package/src/extended/OptionBool.ts +93 -0
  128. package/src/extended/Range.spec.ts +37 -0
  129. package/src/extended/Range.ts +56 -0
  130. package/src/extended/RangeInclusive.ts +20 -0
  131. package/src/extended/Type.spec.ts +118 -0
  132. package/src/extended/Type.ts +29 -0
  133. package/src/extended/U8aFixed.spec.ts +117 -0
  134. package/src/extended/U8aFixed.ts +57 -0
  135. package/src/extended/WrapperKeepOpaque.spec.ts +101 -0
  136. package/src/extended/WrapperKeepOpaque.ts +128 -0
  137. package/src/extended/WrapperOpaque.spec.ts +58 -0
  138. package/src/extended/WrapperOpaque.ts +27 -0
  139. package/src/extended/index.ts +17 -0
  140. package/src/index.ts +6 -0
  141. package/src/mod.ts +4 -0
  142. package/src/native/Bool.spec.ts +74 -0
  143. package/src/native/Bool.ts +137 -0
  144. package/src/native/Date.spec.ts +85 -0
  145. package/src/native/Date.ts +169 -0
  146. package/src/native/Float.spec.ts +51 -0
  147. package/src/native/Float.ts +136 -0
  148. package/src/native/Json.ts +147 -0
  149. package/src/native/Raw.spec.ts +113 -0
  150. package/src/native/Raw.ts +171 -0
  151. package/src/native/Set.spec.ts +116 -0
  152. package/src/native/Set.ts +269 -0
  153. package/src/native/Struct.data.ts +4 -0
  154. package/src/native/Struct.spec.ts +411 -0
  155. package/src/native/Struct.ts +338 -0
  156. package/src/native/Text.spec.ts +85 -0
  157. package/src/native/Text.ts +184 -0
  158. package/src/native/index.ts +11 -0
  159. package/src/packageDetect.ts +11 -0
  160. package/src/packageInfo.ts +6 -0
  161. package/src/primitive/F32.ts +14 -0
  162. package/src/primitive/F64.ts +14 -0
  163. package/src/primitive/I128.ts +14 -0
  164. package/src/primitive/I16.ts +14 -0
  165. package/src/primitive/I256.ts +14 -0
  166. package/src/primitive/I32.ts +14 -0
  167. package/src/primitive/I64.ts +14 -0
  168. package/src/primitive/I8.ts +14 -0
  169. package/src/primitive/ISize.ts +21 -0
  170. package/src/primitive/U128.ts +14 -0
  171. package/src/primitive/U16.ts +14 -0
  172. package/src/primitive/U256.ts +14 -0
  173. package/src/primitive/U32.ts +14 -0
  174. package/src/primitive/U64.ts +14 -0
  175. package/src/primitive/U8.ts +14 -0
  176. package/src/primitive/USize.ts +21 -0
  177. package/src/primitive/index.ts +19 -0
  178. package/src/test/performance.ts +61 -0
  179. package/src/types/codec.ts +140 -0
  180. package/src/types/helpers.ts +50 -0
  181. package/src/types/index.ts +7 -0
  182. package/src/types/interfaces.ts +98 -0
  183. package/src/types/registry.ts +86 -0
  184. package/src/utils/compareArray.ts +22 -0
  185. package/src/utils/compareMap.ts +40 -0
  186. package/src/utils/compareSet.ts +23 -0
  187. package/src/utils/decodeU8a.ts +123 -0
  188. package/src/utils/index.ts +11 -0
  189. package/src/utils/sanitize.spec.ts +89 -0
  190. package/src/utils/sanitize.ts +290 -0
  191. package/src/utils/sortValues.ts +103 -0
  192. package/src/utils/toConstructors.ts +46 -0
  193. package/src/utils/typesToMap.ts +14 -0
  194. package/src/utils/util.ts +8 -0
  195. package/tsconfig.build.json +16 -0
  196. package/tsconfig.build.tsbuildinfo +1 -0
  197. package/tsconfig.spec.json +21 -0
@@ -0,0 +1,245 @@
1
+ // Copyright 2017-2025 @polkadot/types-codec authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
+
6
+ import type { CodecClass, ITuple } from '@pezkuwi/types-codec/types';
7
+
8
+ import { TypeRegistry } from '@pezkuwi/types';
9
+ import { BTreeMap, Enum, I32, Option, Struct, Text, Tuple, U32 } from '@pezkuwi/types-codec';
10
+ import { stringToU8a } from '@pezkuwi/util';
11
+
12
+ const registry = new TypeRegistry();
13
+
14
+ class U32TextTuple extends (Tuple.with([U32, Text]) as unknown as CodecClass<ITuple<[U32, Text]>>) {}
15
+ // Reason: We purposefully want `text` to be the first key of the struct and take priority during sorting
16
+ // eslint-disable-next-line sort-keys
17
+ class MockStruct extends Struct.with({ text: Text, int: I32 }) {}
18
+ class MockEnum extends Enum.with({
19
+ Key1: MockStruct,
20
+ Key2: MockStruct,
21
+ Key3: U32TextTuple
22
+ }) {}
23
+ class MockOptionEnum extends Option.with(MockEnum) {}
24
+
25
+ const mockU32TextMap = new Map<Text, U32>();
26
+ const mockU32DuplicateTextMap = new Map<Text, U32>();
27
+ const mockU32TupleMap = new Map<ITuple<[U32, Text]>, U32>();
28
+ const mockU32I32Map = new Map<I32, U32>();
29
+ const mockU32StructMap = new Map<MockStruct, U32>();
30
+ const mockU32EnumMap = new Map<MockEnum, U32>();
31
+ const mockU32OptionEnumMap = new Map<MockOptionEnum, U32>();
32
+
33
+ mockU32TextMap.set(new Text(registry, 'bazzing'), new U32(registry, 69));
34
+
35
+ mockU32DuplicateTextMap.set(new Text(registry, 'bazzing'), new U32(registry, 42));
36
+ mockU32DuplicateTextMap.set(new Text(registry, 'bazzing'), new U32(registry, 43));
37
+
38
+ mockU32TupleMap.set((new U32TextTuple(registry, [2, 'ba'])), new U32(registry, 42));
39
+ mockU32TupleMap.set((new U32TextTuple(registry, [2, 'b'])), new U32(registry, 7));
40
+ mockU32TupleMap.set((new U32TextTuple(registry, [1, 'baz'])), new U32(registry, 13));
41
+
42
+ mockU32I32Map.set(new I32(registry, 255), new U32(registry, 69));
43
+ mockU32I32Map.set(new I32(registry, -255), new U32(registry, 42));
44
+ mockU32I32Map.set(new I32(registry, 1000), new U32(registry, 7));
45
+ mockU32I32Map.set(new I32(registry, -1000), new U32(registry, 25));
46
+ mockU32I32Map.set(new I32(registry, 0), new U32(registry, 13));
47
+
48
+ mockU32StructMap.set(new MockStruct(registry, { int: 1, text: 'b' }), new U32(registry, 42));
49
+ mockU32StructMap.set(new MockStruct(registry, { int: -1, text: 'b' }), new U32(registry, 7));
50
+ mockU32StructMap.set(new MockStruct(registry, { int: -1, text: 'ba' }), new U32(registry, 25));
51
+ mockU32StructMap.set(new MockStruct(registry, { int: -2, text: 'baz' }), new U32(registry, 13));
52
+
53
+ mockU32EnumMap.set(new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'ba']) }), new U32(registry, 13));
54
+ mockU32EnumMap.set(new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'b']) }), new U32(registry, 42));
55
+ mockU32EnumMap.set(new MockEnum(registry, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 7));
56
+ mockU32EnumMap.set(new MockEnum(registry, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }), new U32(registry, 25));
57
+ mockU32EnumMap.set(new MockEnum(registry, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 69));
58
+
59
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, null), new U32(registry, 13));
60
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, { Key3: new U32TextTuple(registry, [2, 'ba']) }), new U32(registry, 13));
61
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, { Key3: new U32TextTuple(registry, [2, 'b']) }), new U32(registry, 42));
62
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 7));
63
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }), new U32(registry, 25));
64
+ mockU32OptionEnumMap.set(new Option(registry, MockEnum, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 69));
65
+
66
+ describe('BTreeMap', (): void => {
67
+ it('decodes null', (): void => {
68
+ expect(
69
+ new (
70
+ BTreeMap.with(Text, U32)
71
+ )(registry, null).toString()
72
+ ).toEqual('{}');
73
+ });
74
+
75
+ it('decodes reusing instantiated inputs', (): void => {
76
+ const key = new Text(registry, 'foo');
77
+ const val = new Text(registry, 'bar');
78
+
79
+ expect(
80
+ (new (BTreeMap.with(Text, Text))(registry, new Map([[key, val]]))).eq(new Map([[key, val]]))
81
+ ).toBe(true);
82
+ });
83
+
84
+ it('decodes within more complicated types', (): void => {
85
+ const s = new Struct(registry, {
86
+ placeholder: U32,
87
+ value: 'BTreeMap<Text, U32>'
88
+ });
89
+
90
+ s.set('value', new (BTreeMap.with(Text, U32))(registry, mockU32TextMap));
91
+ expect(s.toString()).toBe('{"placeholder":0,"value":{"bazzing":69}}');
92
+ });
93
+
94
+ it('throws on duplicate keys', (): void => {
95
+ expect(
96
+ () => new (BTreeMap.with(Text, U32))(registry, mockU32DuplicateTextMap)
97
+ ).toThrow(/Duplicate value in BTreeMap/);
98
+ });
99
+
100
+ it('throws when it cannot decode', (): void => {
101
+ expect(
102
+ (): BTreeMap<Text, U32> => new (
103
+ BTreeMap.with(Text, U32)
104
+ )(registry, 'ABC')
105
+ ).toThrow(/Map: cannot decode type/);
106
+ });
107
+
108
+ it('correctly encodes length', (): void => {
109
+ expect(
110
+ new (
111
+ BTreeMap.with(Text, U32))(registry, mockU32TextMap).encodedLength
112
+ ).toEqual(13);
113
+ });
114
+
115
+ it('correctly sorts simple keys', (): void => {
116
+ expect(
117
+ Array.from(new (BTreeMap.with(I32, U32))(registry, mockU32I32Map).keys()).map((k) => k.toNumber())
118
+ ).toEqual([-1000, -255, 0, 255, 1000]);
119
+ });
120
+
121
+ it('correctly sorts tuple keys', (): void => {
122
+ expect(
123
+ Array.from(new (BTreeMap.with(U32TextTuple, U32))(registry, mockU32TupleMap).keys()).map((k) => k.toJSON())
124
+ ).toEqual([[1, 'baz'], [2, 'b'], [2, 'ba']]);
125
+ });
126
+
127
+ it('correctly sorts struct keys', (): void => {
128
+ expect(
129
+ Array.from(new (BTreeMap.with(MockStruct, U32))(registry, mockU32StructMap).keys()).map((k) => k.toJSON())
130
+ ).toEqual([
131
+ { int: -1, text: 'b' },
132
+ { int: 1, text: 'b' },
133
+ { int: -1, text: 'ba' },
134
+ { int: -2, text: 'baz' }
135
+ ]);
136
+ });
137
+
138
+ it('correctly sorts Option(Enum) keys', (): void => {
139
+ expect(
140
+ Array.from(new (BTreeMap.with(MockOptionEnum, U32))(registry, mockU32OptionEnumMap).keys()).map((k) => k.value.toJSON())
141
+ ).toEqual([
142
+ null,
143
+ { key1: { int: -1, text: 'b' } },
144
+ { key1: { int: 1, text: 'b' } },
145
+ { key2: { int: -1, text: 'b' } },
146
+ { key3: [2, 'b'] },
147
+ { key3: [2, 'ba'] }
148
+ ]);
149
+ });
150
+
151
+ it('correctly sorts enum keys', (): void => {
152
+ expect(
153
+ Array.from(new (BTreeMap.with(MockEnum, U32))(registry, mockU32EnumMap).keys()).map((k) => k.toJSON())
154
+ ).toEqual([
155
+ { key1: { int: -1, text: 'b' } },
156
+ { key1: { int: 1, text: 'b' } },
157
+ { key2: { int: -1, text: 'b' } },
158
+ { key3: [2, 'b'] },
159
+ { key3: [2, 'ba'] }
160
+ ]);
161
+ });
162
+
163
+ it('correctly serializes/deserializes to/from json with numeric keys', (): void => {
164
+ expect(
165
+ new (BTreeMap.with(I32, U32))(
166
+ registry,
167
+ new (BTreeMap.with(I32, U32))(registry, mockU32I32Map).toJSON()
168
+ ).toJSON()
169
+ ).toEqual({ '-1000': 25, '-255': 42, 0: 13, 1000: 7, 255: 69 });
170
+ });
171
+
172
+ it('correctly serializes/deserializes to/from json with text keys', (): void => {
173
+ expect(
174
+ new (BTreeMap.with(Text, U32))(
175
+ registry,
176
+ new (BTreeMap.with(Text, U32))(registry, mockU32TextMap).toJSON()
177
+ ).toJSON()
178
+ ).toEqual({ bazzing: 69 });
179
+ });
180
+
181
+ it('correctly serializes/deserializes to/from json with tuple keys', (): void => {
182
+ expect(
183
+ new (BTreeMap.with(U32TextTuple, U32))(
184
+ registry,
185
+ new (BTreeMap.with(U32TextTuple, U32))(registry, mockU32TupleMap).toJSON()
186
+ ).toJSON()
187
+ ).toEqual({ '[1,"baz"]': 13, '[2,"b"]': 7, '[2,"ba"]': 42 });
188
+ });
189
+
190
+ it('correctly serializes/deserializes to/from json with struct keys', (): void => {
191
+ expect(
192
+ new (BTreeMap.with(MockStruct, U32))(
193
+ registry,
194
+ new (BTreeMap.with(MockStruct, U32))(registry, mockU32StructMap).toJSON()
195
+ ).toJSON()
196
+ ).toEqual({
197
+ '{"text":"b","int":-1}': 7,
198
+ '{"text":"b","int":1}': 42,
199
+ '{"text":"ba","int":-1}': 25,
200
+ '{"text":"baz","int":-2}': 13
201
+ });
202
+ });
203
+
204
+ it('correctly serializes/deserializes to/from json with enum keys', (): void => {
205
+ expect(
206
+ new (BTreeMap.with(MockEnum, U32))(
207
+ registry,
208
+ new (BTreeMap.with(MockEnum, U32))(registry, mockU32EnumMap).toJSON()
209
+ ).toJSON()
210
+ ).toEqual({
211
+ '{"key1":{"text":"b","int":-1}}': 69,
212
+ '{"key1":{"text":"b","int":1}}': 25,
213
+ '{"key2":{"text":"b","int":-1}}': 7,
214
+ '{"key3":[2,"b"]}': 42,
215
+ '{"key3":[2,"ba"]}': 13
216
+ });
217
+ });
218
+
219
+ it('generates sane toRawTypes', (): void => {
220
+ expect(new (BTreeMap.with(Text, U32))(registry).toRawType()).toBe('BTreeMap<Text,u32>');
221
+ expect(new (BTreeMap.with(Text, Text))(registry).toRawType()).toBe('BTreeMap<Text,Text>');
222
+ expect(new (BTreeMap.with(Text, Struct.with({ a: U32, b: Text })))(registry).toRawType())
223
+ .toBe('BTreeMap<Text,{"a":"u32","b":"Text"}>');
224
+ });
225
+
226
+ it('has a sane inspect', (): void => {
227
+ expect(
228
+ new (BTreeMap.with(Text, Text))(registry, new Map([
229
+ [new Text(registry, '1'), new Text(registry, 'foo')],
230
+ [new Text(registry, '2'), new Text(registry, 'bar')],
231
+ [new Text(registry, '3'), new Text(registry, 'baz')]
232
+ ])).inspect()
233
+ ).toEqual({
234
+ inner: [
235
+ { outer: [new Uint8Array([1 << 2]), stringToU8a('1')] },
236
+ { outer: [new Uint8Array([3 << 2]), stringToU8a('foo')] },
237
+ { outer: [new Uint8Array([1 << 2]), stringToU8a('2')] },
238
+ { outer: [new Uint8Array([3 << 2]), stringToU8a('bar')] },
239
+ { outer: [new Uint8Array([1 << 2]), stringToU8a('3')] },
240
+ { outer: [new Uint8Array([3 << 2]), stringToU8a('baz')] }
241
+ ],
242
+ outer: [new Uint8Array([3 << 2])]
243
+ });
244
+ });
245
+ });
@@ -0,0 +1,16 @@
1
+ // Copyright 2017-2025 @polkadot/types-codec authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Codec, CodecClass, Registry } from '../types/index.js';
5
+
6
+ import { CodecMap } from './Map.js';
7
+
8
+ export class BTreeMap<K extends Codec = Codec, V extends Codec = Codec> extends CodecMap<K, V> {
9
+ public static with<K extends Codec, V extends Codec> (keyType: CodecClass<K> | string, valType: CodecClass<V> | string): CodecClass<CodecMap<K, V>> {
10
+ return class extends BTreeMap<K, V> {
11
+ constructor (registry: Registry, value?: Uint8Array | string | Map<any, any>) {
12
+ super(registry, keyType, valType, value, 'BTreeMap');
13
+ }
14
+ };
15
+ }
16
+ }
@@ -0,0 +1,260 @@
1
+ // Copyright 2017-2025 @polkadot/types-codec authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
+
6
+ import type { CodecClass, CodecTo } from '@pezkuwi/types-codec/types';
7
+ import type { ITuple } from '../types/interfaces.js';
8
+
9
+ import { TypeRegistry } from '@pezkuwi/types';
10
+ import { BTreeSet, Enum, I32, Option, Struct, Text, Tuple, U32 } from '@pezkuwi/types-codec';
11
+
12
+ const registry = new TypeRegistry();
13
+
14
+ class U32TextTuple extends (Tuple.with([U32, Text]) as unknown as CodecClass<ITuple<[U32, Text]>>) {}
15
+ // Reason: We purposefully want `text` to be the first key of the struct and take priority during sorting
16
+ // eslint-disable-next-line sort-keys
17
+ class MockStruct extends Struct.with({ text: Text, int: I32 }) {}
18
+ class MockEnum extends Enum.with({
19
+ Key1: MockStruct,
20
+ Key2: MockStruct,
21
+ Key3: U32TextTuple
22
+ }) {}
23
+ class MockOptionEnum extends Option.with(MockEnum) {}
24
+
25
+ const mockU32Set = new Set<U32>();
26
+
27
+ mockU32Set.add(new U32(registry, 2));
28
+ mockU32Set.add(new U32(registry, 24));
29
+ mockU32Set.add(new U32(registry, 30));
30
+ mockU32Set.add(new U32(registry, 80));
31
+
32
+ const mockU32SetString = '[2,24,30,80]';
33
+ const mockU32SetObject = [2, 24, 30, 80];
34
+ const mockU32SetHexString = '0x1002000000180000001e00000050000000';
35
+ const mockU32SetUint8Array = Uint8Array.from([16, 2, 0, 0, 0, 24, 0, 0, 0, 30, 0, 0, 0, 80, 0, 0, 0]);
36
+
37
+ const mockI32SetObj = [1000, 0, 255, -255, -1000];
38
+ const mockTextSetObj = [
39
+ new Text(registry, 'baz'),
40
+ new Text(registry, 'b'),
41
+ new Text(registry, 'bb'),
42
+ new Text(registry, 'ba'),
43
+ new Text(registry, 'c')
44
+ ];
45
+ const mockTupleSetObj = [
46
+ new U32TextTuple(registry, [2, 'ba']),
47
+ new U32TextTuple(registry, [2, 'bb']),
48
+ new U32TextTuple(registry, [2, 'b']),
49
+ new U32TextTuple(registry, [1, 'baz'])
50
+ ];
51
+ const mockStructSetObj = [
52
+ new MockStruct(registry, { int: 1, text: 'b' }),
53
+ new MockStruct(registry, { int: -1, text: 'b' }),
54
+ new MockStruct(registry, { int: -1, text: 'ba' }),
55
+ new MockStruct(registry, { int: -2, text: 'baz' })
56
+ ];
57
+ const mockEnumSetObj = [
58
+ new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'ba']) }),
59
+ new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'b']) }),
60
+ new MockEnum(registry, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }),
61
+ new MockEnum(registry, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }),
62
+ new MockEnum(registry, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) })
63
+ ];
64
+
65
+ const mockOptionEnumSetObj = [
66
+ new Option(registry, MockEnum, null),
67
+ new Option(registry, MockEnum, { Key3: new U32TextTuple(registry, [2, 'ba']) }),
68
+ new Option(registry, MockEnum, { Key3: new U32TextTuple(registry, [2, 'b']) }),
69
+ new Option(registry, MockEnum, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }),
70
+ new Option(registry, MockEnum, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }),
71
+ new Option(registry, MockEnum, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) })
72
+ ];
73
+ const mockDuplicateTextSetObj = [
74
+ new Text(registry, 'baz'),
75
+ new Text(registry, 'bb'),
76
+ new Text(registry, 'bb'), // duplicate.
77
+ new Text(registry, 'ba'),
78
+ new Text(registry, 'c')
79
+ ];
80
+
81
+ describe('BTreeSet', (): void => {
82
+ describe('decoding', (): void => {
83
+ const testDecode = (type: string, input: unknown, output: string): void =>
84
+ it(`can decode from ${type}`, (): void => {
85
+ const s = new BTreeSet(registry, U32, input as string);
86
+
87
+ expect(s.toString()).toBe(output);
88
+ });
89
+
90
+ testDecode('Set', mockU32Set, mockU32SetString);
91
+ testDecode('hex', mockU32SetHexString, mockU32SetString);
92
+ testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
93
+
94
+ testDecode('Set', mockU32Set, mockU32SetString);
95
+ testDecode('hex', mockU32SetHexString, mockU32SetString);
96
+ testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
97
+ });
98
+
99
+ describe('encoding multiple values', (): void => {
100
+ const testEncode = (to: CodecTo, expected: any): void =>
101
+ it(`can encode ${to}`, (): void => {
102
+ const s = new BTreeSet(registry, U32, mockU32Set);
103
+
104
+ expect(s[to]()).toEqual(expected);
105
+ });
106
+
107
+ testEncode('toHex', mockU32SetHexString);
108
+ testEncode('toJSON', mockU32SetObject);
109
+ testEncode('toU8a', mockU32SetUint8Array);
110
+ testEncode('toString', mockU32SetString);
111
+ });
112
+
113
+ it('decodes null', (): void => {
114
+ expect(
115
+ new (
116
+ BTreeSet.with(U32)
117
+ )(registry, null).toString()
118
+ ).toEqual('[]');
119
+ });
120
+
121
+ it('decodes reusing instantiated inputs', (): void => {
122
+ const foo = new Text(registry, 'bar');
123
+
124
+ expect(
125
+ (new BTreeSet(registry, Text, new Set([foo]))).eq(new Set([foo]))
126
+ ).toBe(true);
127
+ });
128
+
129
+ it('decodes within more complicated types', (): void => {
130
+ const s = new Struct(registry, {
131
+ placeholder: U32,
132
+ value: BTreeSet.with(U32)
133
+ });
134
+
135
+ s.set('value', new BTreeSet(registry, U32, mockU32Set));
136
+ expect(s.toString()).toBe('{"placeholder":0,"value":[2,24,30,80]}');
137
+ });
138
+
139
+ it('throws when it cannot decode', (): void => {
140
+ expect(
141
+ (): BTreeSet<U32> => new (
142
+ BTreeSet.with(U32)
143
+ )(registry, 'ABC')
144
+ ).toThrow(/BTreeSet: cannot decode type/);
145
+ });
146
+
147
+ describe('enocodedLength & initialU8aLength', (): void => {
148
+ it('correctly encodes length', (): void => {
149
+ expect(
150
+ new (
151
+ BTreeSet.with(U32))(registry, mockU32Set).encodedLength
152
+ ).toEqual(17);
153
+ });
154
+
155
+ it('correctly encodes/decodes empty', (): void => {
156
+ const none = new (BTreeSet.with(U32))(registry, []);
157
+
158
+ // only the length byte
159
+ expect(none.toHex()).toEqual('0x00');
160
+ expect(none.encodedLength).toEqual(1);
161
+ expect(
162
+ (new (BTreeSet.with(U32))(registry, none.toHex())).initialU8aLength
163
+ ).toEqual(none.encodedLength);
164
+ });
165
+
166
+ it('correctly encodes/decodes filled', (): void => {
167
+ const some = new (BTreeSet.with(U32))(registry, [1, 2]);
168
+
169
+ // length byte + 2 values, 2 << 2 with u32 values
170
+ expect(some.toHex()).toEqual('0x080100000002000000');
171
+ expect(some.encodedLength).toEqual(1 + (4 * 2));
172
+ expect(
173
+ (new (BTreeSet.with(U32))(registry, some.toHex())).initialU8aLength
174
+ ).toEqual(some.encodedLength);
175
+ });
176
+ });
177
+
178
+ describe('sorting', (): void => {
179
+ it('correctly sorts numeric values', (): void => {
180
+ expect(
181
+ Array.from(new (BTreeSet.with(I32))(registry, mockI32SetObj)).map((k) => k.toNumber())
182
+ ).toEqual([-1000, -255, 0, 255, 1000]);
183
+ });
184
+
185
+ it('correctly sorts text values', (): void => {
186
+ expect(
187
+ Array.from(new (BTreeSet.with(Text))(registry, mockTextSetObj)).map((k) => k.toString())
188
+ ).toEqual(['b', 'ba', 'baz', 'bb', 'c']);
189
+ });
190
+
191
+ it('Reject duplicate values', (): void => {
192
+ expect(
193
+ () => new (BTreeSet.with(Text))(registry, mockDuplicateTextSetObj)
194
+ ).toThrow(/Duplicate value in BTreeSet/);
195
+ });
196
+
197
+ it('correctly sorts complex tuple values', (): void => {
198
+ expect(
199
+ Array.from(new (BTreeSet.with(U32TextTuple))(registry, mockTupleSetObj)).map((k) => k.toJSON())
200
+ ).toEqual([[1, 'baz'], [2, 'b'], [2, 'ba'], [2, 'bb']]);
201
+ });
202
+
203
+ it('correctly sorts complex struct values', (): void => {
204
+ expect(
205
+ Array.from(new (BTreeSet.with(MockStruct))(registry, mockStructSetObj)).map((k) => k.toJSON())
206
+ ).toEqual([
207
+ { int: -1, text: 'b' },
208
+ { int: 1, text: 'b' },
209
+ { int: -1, text: 'ba' },
210
+ { int: -2, text: 'baz' }
211
+ ]);
212
+ });
213
+
214
+ it('correctly sorts complex Option(enum) values', (): void => {
215
+ expect(
216
+ Array.from(new (BTreeSet.with(MockOptionEnum))(registry, mockOptionEnumSetObj)).map((k) => k.value.toJSON())
217
+ ).toEqual([
218
+ null,
219
+ { key1: { int: -1, text: 'b' } },
220
+ { key1: { int: 1, text: 'b' } },
221
+ { key2: { int: -1, text: 'b' } },
222
+ { key3: [2, 'b'] },
223
+ { key3: [2, 'ba'] }
224
+ ]);
225
+ });
226
+
227
+ it('correctly sorts complex enum values', (): void => {
228
+ expect(
229
+ Array.from(new (BTreeSet.with(MockEnum))(registry, mockEnumSetObj)).map((k) => k.toJSON())
230
+ ).toEqual([
231
+ { key1: { int: -1, text: 'b' } },
232
+ { key1: { int: 1, text: 'b' } },
233
+ { key2: { int: -1, text: 'b' } },
234
+ { key3: [2, 'b'] },
235
+ { key3: [2, 'ba'] }
236
+ ]);
237
+ });
238
+ });
239
+
240
+ it('generates sane toRawTypes', (): void => {
241
+ expect(new (BTreeSet.with(U32))(registry).toRawType()).toBe('BTreeSet<u32>');
242
+ expect(new (BTreeSet.with(Text))(registry).toRawType()).toBe('BTreeSet<Text>');
243
+ expect(new (BTreeSet.with(Struct.with({ a: U32, b: Text })))(registry).toRawType())
244
+ .toBe('BTreeSet<{"a":"u32","b":"Text"}>');
245
+ });
246
+
247
+ it('has a sane inspect', (): void => {
248
+ expect(
249
+ new (BTreeSet.with(U32))(registry, [1, 2, 3, 4]).inspect()
250
+ ).toEqual({
251
+ inner: [
252
+ { outer: [new Uint8Array([1, 0, 0, 0])] },
253
+ { outer: [new Uint8Array([2, 0, 0, 0])] },
254
+ { outer: [new Uint8Array([3, 0, 0, 0])] },
255
+ { outer: [new Uint8Array([4, 0, 0, 0])] }
256
+ ],
257
+ outer: [new Uint8Array([4 << 2])]
258
+ });
259
+ });
260
+ });