@solana/codecs-data-structures 2.0.0-experimental.df45965 → 2.0.0-experimental.e00f668
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/README.md +482 -4
- package/dist/index.browser.cjs +452 -487
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +456 -485
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +454 -485
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +452 -487
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +456 -485
- package/dist/index.node.js.map +1 -1
- package/dist/types/array.d.ts +39 -10
- package/dist/types/array.d.ts.map +1 -0
- package/dist/types/assertions.d.ts.map +1 -0
- package/dist/types/bit-array.d.ts +9 -9
- package/dist/types/bit-array.d.ts.map +1 -0
- package/dist/types/boolean.d.ts +22 -10
- package/dist/types/boolean.d.ts.map +1 -0
- package/dist/types/bytes.d.ts +18 -9
- package/dist/types/bytes.d.ts.map +1 -0
- package/dist/types/data-enum.d.ts +22 -24
- package/dist/types/data-enum.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -14
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/map.d.ts +28 -10
- package/dist/types/map.d.ts.map +1 -0
- package/dist/types/nullable.d.ts +28 -10
- package/dist/types/nullable.d.ts.map +1 -0
- package/dist/types/scalar-enum.d.ts +46 -15
- package/dist/types/scalar-enum.d.ts.map +1 -0
- package/dist/types/set.d.ts +28 -10
- package/dist/types/set.d.ts.map +1 -0
- package/dist/types/struct.d.ts +16 -21
- package/dist/types/struct.d.ts.map +1 -0
- package/dist/types/tuple.d.ts +22 -15
- package/dist/types/tuple.d.ts.map +1 -0
- package/dist/types/unit.d.ts +4 -12
- package/dist/types/unit.d.ts.map +1 -0
- package/dist/types/utils.d.ts +10 -2
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +13 -34
- package/dist/index.development.js +0 -865
- package/dist/index.development.js.map +0 -1
- package/dist/index.production.min.js +0 -51
- package/dist/types/array-like-codec-size.d.ts +0 -20
package/dist/index.browser.cjs
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
var codecsCore = require('@solana/codecs-core');
|
|
4
4
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
5
|
+
var errors = require('@solana/errors');
|
|
5
6
|
|
|
6
7
|
// src/array.ts
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
|
|
9
|
+
if (expected !== actual) {
|
|
10
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_ITEMS, {
|
|
11
|
+
actual,
|
|
12
|
+
codecDescription,
|
|
13
|
+
expected
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
9
17
|
function maxCodecSizes(sizes) {
|
|
10
18
|
return sizes.reduce(
|
|
11
19
|
(all, size) => all === null || size === null ? null : Math.max(all, size),
|
|
@@ -15,106 +23,88 @@ function maxCodecSizes(sizes) {
|
|
|
15
23
|
function sumCodecSizes(sizes) {
|
|
16
24
|
return sizes.reduce((all, size) => all === null || size === null ? null : all + size, 0);
|
|
17
25
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function decodeArrayLikeCodecSize(size, childrenSizes, bytes, offset) {
|
|
21
|
-
if (typeof size === "number") {
|
|
22
|
-
return [size, offset];
|
|
23
|
-
}
|
|
24
|
-
if (typeof size === "object") {
|
|
25
|
-
return size.decode(bytes, offset);
|
|
26
|
-
}
|
|
27
|
-
if (size === "remainder") {
|
|
28
|
-
const childrenSize = sumCodecSizes(childrenSizes);
|
|
29
|
-
if (childrenSize === null) {
|
|
30
|
-
throw new Error('Codecs of "remainder" size must have fixed-size items.');
|
|
31
|
-
}
|
|
32
|
-
const remainder = bytes.slice(offset).length;
|
|
33
|
-
if (remainder % childrenSize !== 0) {
|
|
34
|
-
throw new Error(
|
|
35
|
-
`The remainder of the byte array (${remainder} bytes) cannot be split into chunks of ${childrenSize} bytes. Codecs of "remainder" size must have a remainder that is a multiple of its item size. In other words, ${remainder} modulo ${childrenSize} should be equal to zero.`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
return [remainder / childrenSize, offset];
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
|
|
26
|
+
function getFixedSize(codec) {
|
|
27
|
+
return codecsCore.isFixedSize(codec) ? codec.fixedSize : null;
|
|
41
28
|
}
|
|
42
|
-
function
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
function getArrayLikeCodecSizeFromChildren(size, childrenSizes) {
|
|
46
|
-
if (typeof size !== "number")
|
|
47
|
-
return null;
|
|
48
|
-
if (size === 0)
|
|
49
|
-
return 0;
|
|
50
|
-
const childrenSize = sumCodecSizes(childrenSizes);
|
|
51
|
-
return childrenSize === null ? null : childrenSize * size;
|
|
52
|
-
}
|
|
53
|
-
function getArrayLikeCodecSizePrefix(size, realSize) {
|
|
54
|
-
return typeof size === "object" ? size.encode(realSize) : new Uint8Array();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// src/assertions.ts
|
|
58
|
-
function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
|
|
59
|
-
if (expected !== actual) {
|
|
60
|
-
throw new Error(`Expected [${codecDescription}] to have ${expected} items, got ${actual}.`);
|
|
61
|
-
}
|
|
29
|
+
function getMaxSize(codec) {
|
|
30
|
+
return codecsCore.isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;
|
|
62
31
|
}
|
|
63
32
|
|
|
64
33
|
// src/array.ts
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
...arrayCodecHelper(item, size, options.description),
|
|
79
|
-
encode: (value) => {
|
|
34
|
+
function getArrayEncoder(item, config = {}) {
|
|
35
|
+
const size = config.size ?? codecsNumbers.getU32Encoder();
|
|
36
|
+
const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));
|
|
37
|
+
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
38
|
+
return codecsCore.createEncoder({
|
|
39
|
+
...fixedSize !== null ? { fixedSize } : {
|
|
40
|
+
getSizeFromValue: (array) => {
|
|
41
|
+
const prefixSize = typeof size === "object" ? codecsCore.getEncodedSize(array.length, size) : 0;
|
|
42
|
+
return prefixSize + [...array].reduce((all, value) => all + codecsCore.getEncodedSize(value, item), 0);
|
|
43
|
+
},
|
|
44
|
+
maxSize
|
|
45
|
+
},
|
|
46
|
+
write: (array, bytes, offset) => {
|
|
80
47
|
if (typeof size === "number") {
|
|
81
|
-
assertValidNumberOfItemsForCodec("array", size,
|
|
48
|
+
assertValidNumberOfItemsForCodec("array", size, array.length);
|
|
82
49
|
}
|
|
83
|
-
|
|
50
|
+
if (typeof size === "object") {
|
|
51
|
+
offset = size.write(array.length, bytes, offset);
|
|
52
|
+
}
|
|
53
|
+
array.forEach((value) => {
|
|
54
|
+
offset = item.write(value, bytes, offset);
|
|
55
|
+
});
|
|
56
|
+
return offset;
|
|
84
57
|
}
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function getArrayDecoder(item,
|
|
88
|
-
const size =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function getArrayDecoder(item, config = {}) {
|
|
61
|
+
const size = config.size ?? codecsNumbers.getU32Decoder();
|
|
62
|
+
const itemSize = getFixedSize(item);
|
|
63
|
+
const fixedSize = computeArrayLikeCodecSize(size, itemSize);
|
|
64
|
+
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
65
|
+
return codecsCore.createDecoder({
|
|
66
|
+
...fixedSize !== null ? { fixedSize } : { maxSize },
|
|
67
|
+
read: (bytes, offset) => {
|
|
68
|
+
const array = [];
|
|
92
69
|
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
93
|
-
return [
|
|
70
|
+
return [array, offset];
|
|
94
71
|
}
|
|
95
|
-
|
|
72
|
+
if (size === "remainder") {
|
|
73
|
+
while (offset < bytes.length) {
|
|
74
|
+
const [value, newOffset2] = item.read(bytes, offset);
|
|
75
|
+
offset = newOffset2;
|
|
76
|
+
array.push(value);
|
|
77
|
+
}
|
|
78
|
+
return [array, offset];
|
|
79
|
+
}
|
|
80
|
+
const [resolvedSize, newOffset] = typeof size === "number" ? [size, offset] : size.read(bytes, offset);
|
|
96
81
|
offset = newOffset;
|
|
97
|
-
const values = [];
|
|
98
82
|
for (let i = 0; i < resolvedSize; i += 1) {
|
|
99
|
-
const [value, newOffset2] = item.
|
|
100
|
-
values.push(value);
|
|
83
|
+
const [value, newOffset2] = item.read(bytes, offset);
|
|
101
84
|
offset = newOffset2;
|
|
85
|
+
array.push(value);
|
|
102
86
|
}
|
|
103
|
-
return [
|
|
87
|
+
return [array, offset];
|
|
104
88
|
}
|
|
105
|
-
};
|
|
89
|
+
});
|
|
106
90
|
}
|
|
107
|
-
function getArrayCodec(item,
|
|
108
|
-
return codecsCore.combineCodec(getArrayEncoder(item,
|
|
91
|
+
function getArrayCodec(item, config = {}) {
|
|
92
|
+
return codecsCore.combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
|
|
109
93
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
94
|
+
function computeArrayLikeCodecSize(size, itemSize) {
|
|
95
|
+
if (typeof size !== "number")
|
|
96
|
+
return null;
|
|
97
|
+
if (size === 0)
|
|
98
|
+
return 0;
|
|
99
|
+
return itemSize === null ? null : itemSize * size;
|
|
100
|
+
}
|
|
101
|
+
function getBitArrayEncoder(size, config = {}) {
|
|
102
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
103
|
+
const backward = parsedConfig.backward ?? false;
|
|
104
|
+
return codecsCore.createEncoder({
|
|
105
|
+
fixedSize: size,
|
|
106
|
+
write(value, bytes, offset) {
|
|
107
|
+
const bytesToAdd = [];
|
|
118
108
|
for (let i = 0; i < size; i += 1) {
|
|
119
109
|
let byte = 0;
|
|
120
110
|
for (let j = 0; j < 8; j += 1) {
|
|
@@ -122,23 +112,22 @@ var getBitArrayEncoder = (size, options = {}) => {
|
|
|
122
112
|
byte |= feature << (backward ? j : 7 - j);
|
|
123
113
|
}
|
|
124
114
|
if (backward) {
|
|
125
|
-
|
|
115
|
+
bytesToAdd.unshift(byte);
|
|
126
116
|
} else {
|
|
127
|
-
|
|
117
|
+
bytesToAdd.push(byte);
|
|
128
118
|
}
|
|
129
119
|
}
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
bytes.set(bytesToAdd, offset);
|
|
121
|
+
return size;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function getBitArrayDecoder(size, config = {}) {
|
|
126
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
127
|
+
const backward = parsedConfig.backward ?? false;
|
|
128
|
+
return codecsCore.createDecoder({
|
|
132
129
|
fixedSize: size,
|
|
133
|
-
|
|
134
|
-
};
|
|
135
|
-
};
|
|
136
|
-
var getBitArrayDecoder = (size, options = {}) => {
|
|
137
|
-
const parsedOptions = typeof options === "boolean" ? { backward: options } : options;
|
|
138
|
-
const backward = parsedOptions.backward ?? false;
|
|
139
|
-
const backwardSuffix = backward ? "; backward" : "";
|
|
140
|
-
return {
|
|
141
|
-
decode(bytes, offset = 0) {
|
|
130
|
+
read(bytes, offset) {
|
|
142
131
|
codecsCore.assertByteArrayHasEnoughBytesForCodec("bitArray", size, bytes, offset);
|
|
143
132
|
const booleans = [];
|
|
144
133
|
let slice = bytes.slice(offset, offset + size);
|
|
@@ -155,476 +144,452 @@ var getBitArrayDecoder = (size, options = {}) => {
|
|
|
155
144
|
}
|
|
156
145
|
});
|
|
157
146
|
return [booleans, offset + size];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
codecsCore.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function getBitArrayCodec(size, config = {}) {
|
|
151
|
+
return codecsCore.combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
|
|
152
|
+
}
|
|
153
|
+
function getBooleanEncoder(config = {}) {
|
|
154
|
+
const size = config.size ?? codecsNumbers.getU8Encoder();
|
|
155
|
+
try {
|
|
156
|
+
codecsCore.assertIsFixedSize(size);
|
|
157
|
+
} catch (e) {
|
|
158
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
159
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
|
|
160
|
+
codecDescription: "bool"
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
throw e;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return codecsCore.mapEncoder(size, (value) => value ? 1 : 0);
|
|
167
|
+
}
|
|
168
|
+
function getBooleanDecoder(config = {}) {
|
|
169
|
+
const size = config.size ?? codecsNumbers.getU8Decoder();
|
|
170
|
+
try {
|
|
171
|
+
codecsCore.assertIsFixedSize(size);
|
|
172
|
+
} catch (e) {
|
|
173
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
174
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
|
|
175
|
+
codecDescription: "bool"
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
throw e;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return codecsCore.mapDecoder(size, (value) => Number(value) === 1);
|
|
182
|
+
}
|
|
183
|
+
function getBooleanCodec(config = {}) {
|
|
184
|
+
return codecsCore.combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
|
|
185
|
+
}
|
|
186
|
+
function getBytesEncoder(config = {}) {
|
|
187
|
+
const size = config.size ?? "variable";
|
|
188
|
+
const byteEncoder = codecsCore.createEncoder({
|
|
189
|
+
getSizeFromValue: (value) => value.length,
|
|
190
|
+
write: (value, bytes, offset) => {
|
|
191
|
+
bytes.set(value, offset);
|
|
192
|
+
return offset + value.length;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
202
195
|
if (size === "variable") {
|
|
203
196
|
return byteEncoder;
|
|
204
197
|
}
|
|
205
198
|
if (typeof size === "number") {
|
|
206
|
-
return codecsCore.fixEncoder(byteEncoder, size
|
|
199
|
+
return codecsCore.fixEncoder(byteEncoder, size);
|
|
207
200
|
}
|
|
208
|
-
return {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return codecsCore.mergeBytes([lengthBytes, contentBytes]);
|
|
201
|
+
return codecsCore.createEncoder({
|
|
202
|
+
getSizeFromValue: (value) => codecsCore.getEncodedSize(value.length, size) + value.length,
|
|
203
|
+
write: (value, bytes, offset) => {
|
|
204
|
+
offset = size.write(value.length, bytes, offset);
|
|
205
|
+
return byteEncoder.write(value, bytes, offset);
|
|
214
206
|
}
|
|
215
|
-
};
|
|
207
|
+
});
|
|
216
208
|
}
|
|
217
|
-
function getBytesDecoder(
|
|
218
|
-
const size =
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const byteDecoder = {
|
|
222
|
-
decode: (bytes, offset = 0) => {
|
|
209
|
+
function getBytesDecoder(config = {}) {
|
|
210
|
+
const size = config.size ?? "variable";
|
|
211
|
+
const byteDecoder = codecsCore.createDecoder({
|
|
212
|
+
read: (bytes, offset) => {
|
|
223
213
|
const slice = bytes.slice(offset);
|
|
224
214
|
return [slice, offset + slice.length];
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
fixedSize: null,
|
|
228
|
-
maxSize: null
|
|
229
|
-
};
|
|
215
|
+
}
|
|
216
|
+
});
|
|
230
217
|
if (size === "variable") {
|
|
231
218
|
return byteDecoder;
|
|
232
219
|
}
|
|
233
220
|
if (typeof size === "number") {
|
|
234
|
-
return codecsCore.fixDecoder(byteDecoder, size
|
|
221
|
+
return codecsCore.fixDecoder(byteDecoder, size);
|
|
235
222
|
}
|
|
236
|
-
return {
|
|
237
|
-
|
|
238
|
-
decode: (bytes, offset = 0) => {
|
|
223
|
+
return codecsCore.createDecoder({
|
|
224
|
+
read: (bytes, offset) => {
|
|
239
225
|
codecsCore.assertByteArrayIsNotEmptyForCodec("bytes", bytes, offset);
|
|
240
|
-
const [lengthBigInt, lengthOffset] = size.
|
|
226
|
+
const [lengthBigInt, lengthOffset] = size.read(bytes, offset);
|
|
241
227
|
const length = Number(lengthBigInt);
|
|
242
228
|
offset = lengthOffset;
|
|
243
229
|
const contentBytes = bytes.slice(offset, offset + length);
|
|
244
230
|
codecsCore.assertByteArrayHasEnoughBytesForCodec("bytes", length, contentBytes);
|
|
245
|
-
const [value, contentOffset] = byteDecoder.
|
|
231
|
+
const [value, contentOffset] = byteDecoder.read(contentBytes, 0);
|
|
246
232
|
offset += contentOffset;
|
|
247
233
|
return [value, offset];
|
|
248
234
|
}
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
function getBytesCodec(
|
|
252
|
-
return codecsCore.combineCodec(getBytesEncoder(
|
|
253
|
-
}
|
|
254
|
-
function
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (discriminator < 0) {
|
|
272
|
-
throw new Error(
|
|
273
|
-
`Invalid data enum variant. Expected one of [${variants.map(([key]) => key).join(", ")}], got "${variant.__kind}".`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
const variantPrefix = prefix.encode(discriminator);
|
|
277
|
-
const variantSerializer = variants[discriminator][1];
|
|
278
|
-
const variantBytes = variantSerializer.encode(variant);
|
|
279
|
-
return codecsCore.mergeBytes([variantPrefix, variantBytes]);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function getBytesCodec(config = {}) {
|
|
238
|
+
return codecsCore.combineCodec(getBytesEncoder(config), getBytesDecoder(config));
|
|
239
|
+
}
|
|
240
|
+
function getDataEnumEncoder(variants, config = {}) {
|
|
241
|
+
const prefix = config.size ?? codecsNumbers.getU8Encoder();
|
|
242
|
+
const fixedSize = getDataEnumFixedSize(variants, prefix);
|
|
243
|
+
return codecsCore.createEncoder({
|
|
244
|
+
...fixedSize !== null ? { fixedSize } : {
|
|
245
|
+
getSizeFromValue: (variant) => {
|
|
246
|
+
const discriminator = getVariantDiscriminator(variants, variant);
|
|
247
|
+
const variantEncoder = variants[discriminator][1];
|
|
248
|
+
return codecsCore.getEncodedSize(discriminator, prefix) + codecsCore.getEncodedSize(variant, variantEncoder);
|
|
249
|
+
},
|
|
250
|
+
maxSize: getDataEnumMaxSize(variants, prefix)
|
|
251
|
+
},
|
|
252
|
+
write: (variant, bytes, offset) => {
|
|
253
|
+
const discriminator = getVariantDiscriminator(variants, variant);
|
|
254
|
+
offset = prefix.write(discriminator, bytes, offset);
|
|
255
|
+
const variantEncoder = variants[discriminator][1];
|
|
256
|
+
return variantEncoder.write(variant, bytes, offset);
|
|
280
257
|
}
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
function getDataEnumDecoder(variants,
|
|
284
|
-
const prefix =
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function getDataEnumDecoder(variants, config = {}) {
|
|
261
|
+
const prefix = config.size ?? codecsNumbers.getU8Decoder();
|
|
262
|
+
const fixedSize = getDataEnumFixedSize(variants, prefix);
|
|
263
|
+
return codecsCore.createDecoder({
|
|
264
|
+
...fixedSize !== null ? { fixedSize } : { maxSize: getDataEnumMaxSize(variants, prefix) },
|
|
265
|
+
read: (bytes, offset) => {
|
|
288
266
|
codecsCore.assertByteArrayIsNotEmptyForCodec("dataEnum", bytes, offset);
|
|
289
|
-
const [discriminator, dOffset] = prefix.
|
|
267
|
+
const [discriminator, dOffset] = prefix.read(bytes, offset);
|
|
290
268
|
offset = dOffset;
|
|
291
269
|
const variantField = variants[Number(discriminator)] ?? null;
|
|
292
270
|
if (!variantField) {
|
|
293
|
-
throw new
|
|
294
|
-
|
|
295
|
-
|
|
271
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
272
|
+
discriminator,
|
|
273
|
+
maxRange: variants.length - 1,
|
|
274
|
+
minRange: 0
|
|
275
|
+
});
|
|
296
276
|
}
|
|
297
|
-
const [variant, vOffset] = variantField[1].
|
|
277
|
+
const [variant, vOffset] = variantField[1].read(bytes, offset);
|
|
298
278
|
offset = vOffset;
|
|
299
279
|
return [{ __kind: variantField[0], ...variant ?? {} }, offset];
|
|
300
280
|
}
|
|
301
|
-
};
|
|
281
|
+
});
|
|
302
282
|
}
|
|
303
|
-
function getDataEnumCodec(variants,
|
|
304
|
-
return codecsCore.combineCodec(
|
|
283
|
+
function getDataEnumCodec(variants, config = {}) {
|
|
284
|
+
return codecsCore.combineCodec(
|
|
285
|
+
getDataEnumEncoder(variants, config),
|
|
286
|
+
getDataEnumDecoder(variants, config)
|
|
287
|
+
);
|
|
305
288
|
}
|
|
306
|
-
function
|
|
307
|
-
if (
|
|
308
|
-
|
|
289
|
+
function getDataEnumFixedSize(variants, prefix) {
|
|
290
|
+
if (variants.length === 0)
|
|
291
|
+
return codecsCore.isFixedSize(prefix) ? prefix.fixedSize : null;
|
|
292
|
+
if (!codecsCore.isFixedSize(variants[0][1]))
|
|
293
|
+
return null;
|
|
294
|
+
const variantSize = variants[0][1].fixedSize;
|
|
295
|
+
const sameSizedVariants = variants.every(
|
|
296
|
+
(variant) => codecsCore.isFixedSize(variant[1]) && variant[1].fixedSize === variantSize
|
|
297
|
+
);
|
|
298
|
+
if (!sameSizedVariants)
|
|
299
|
+
return null;
|
|
300
|
+
return codecsCore.isFixedSize(prefix) ? prefix.fixedSize + variantSize : null;
|
|
301
|
+
}
|
|
302
|
+
function getDataEnumMaxSize(variants, prefix) {
|
|
303
|
+
const maxVariantSize = maxCodecSizes(variants.map(([, codec]) => getMaxSize(codec)));
|
|
304
|
+
return sumCodecSizes([getMaxSize(prefix), maxVariantSize]) ?? void 0;
|
|
305
|
+
}
|
|
306
|
+
function getVariantDiscriminator(variants, variant) {
|
|
307
|
+
const discriminator = variants.findIndex(([key]) => variant.__kind === key);
|
|
308
|
+
if (discriminator < 0) {
|
|
309
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_DATA_ENUM_VARIANT, {
|
|
310
|
+
value: variant.__kind,
|
|
311
|
+
variants: variants.map(([key]) => key)
|
|
312
|
+
});
|
|
309
313
|
}
|
|
310
|
-
return
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
314
|
+
return discriminator;
|
|
315
|
+
}
|
|
316
|
+
function getTupleEncoder(items) {
|
|
317
|
+
const fixedSize = sumCodecSizes(items.map(getFixedSize));
|
|
318
|
+
const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
|
|
319
|
+
return codecsCore.createEncoder({
|
|
320
|
+
...fixedSize === null ? {
|
|
321
|
+
getSizeFromValue: (value) => items.map((item, index) => codecsCore.getEncodedSize(value[index], item)).reduce((all, one) => all + one, 0),
|
|
322
|
+
maxSize
|
|
323
|
+
} : { fixedSize },
|
|
324
|
+
write: (value, bytes, offset) => {
|
|
325
|
+
assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
|
|
326
|
+
items.forEach((item, index) => {
|
|
327
|
+
offset = item.write(value[index], bytes, offset);
|
|
328
|
+
});
|
|
329
|
+
return offset;
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function getTupleDecoder(items) {
|
|
334
|
+
const fixedSize = sumCodecSizes(items.map(getFixedSize));
|
|
335
|
+
const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
|
|
336
|
+
return codecsCore.createDecoder({
|
|
337
|
+
...fixedSize === null ? { maxSize } : { fixedSize },
|
|
338
|
+
read: (bytes, offset) => {
|
|
339
|
+
const values = [];
|
|
340
|
+
items.forEach((item) => {
|
|
341
|
+
const [newValue, newOffset] = item.read(bytes, offset);
|
|
342
|
+
values.push(newValue);
|
|
343
|
+
offset = newOffset;
|
|
344
|
+
});
|
|
345
|
+
return [values, offset];
|
|
346
|
+
}
|
|
347
|
+
});
|
|
315
348
|
}
|
|
316
|
-
function
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
349
|
+
function getTupleCodec(items) {
|
|
350
|
+
return codecsCore.combineCodec(
|
|
351
|
+
getTupleEncoder(items),
|
|
352
|
+
getTupleDecoder(items)
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/map.ts
|
|
357
|
+
function getMapEncoder(key, value, config = {}) {
|
|
358
|
+
return codecsCore.mapEncoder(
|
|
359
|
+
getArrayEncoder(getTupleEncoder([key, value]), config),
|
|
360
|
+
(map) => [...map.entries()]
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
function getMapDecoder(key, value, config = {}) {
|
|
364
|
+
return codecsCore.mapDecoder(
|
|
365
|
+
getArrayDecoder(getTupleDecoder([key, value]), config),
|
|
366
|
+
(entries) => new Map(entries)
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function getMapCodec(key, value, config = {}) {
|
|
370
|
+
return codecsCore.combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
|
|
371
|
+
}
|
|
372
|
+
function getNullableEncoder(item, config = {}) {
|
|
373
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
|
|
374
|
+
const fixed = config.fixed ?? false;
|
|
375
|
+
const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
|
|
376
|
+
if (fixed || isZeroSizeItem) {
|
|
377
|
+
try {
|
|
378
|
+
codecsCore.assertIsFixedSize(item);
|
|
379
|
+
} catch (e) {
|
|
380
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
381
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
|
|
382
|
+
} else {
|
|
383
|
+
throw e;
|
|
323
384
|
}
|
|
324
|
-
const itemBytes = Array.from(map, ([k, v]) => codecsCore.mergeBytes([key.encode(k), value.encode(v)]));
|
|
325
|
-
return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, map.size), ...itemBytes]);
|
|
326
385
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const map = /* @__PURE__ */ new Map();
|
|
335
|
-
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
336
|
-
return [map, offset];
|
|
386
|
+
try {
|
|
387
|
+
codecsCore.assertIsFixedSize(prefix);
|
|
388
|
+
} catch (e) {
|
|
389
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
390
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
|
|
391
|
+
} else {
|
|
392
|
+
throw e;
|
|
337
393
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
offset
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
394
|
+
}
|
|
395
|
+
const fixedSize = prefix.fixedSize + item.fixedSize;
|
|
396
|
+
return codecsCore.createEncoder({
|
|
397
|
+
fixedSize,
|
|
398
|
+
write: (option, bytes, offset) => {
|
|
399
|
+
const prefixOffset = prefix.write(Number(option !== null), bytes, offset);
|
|
400
|
+
if (option !== null) {
|
|
401
|
+
item.write(option, bytes, prefixOffset);
|
|
402
|
+
}
|
|
403
|
+
return offset + fixedSize;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
return codecsCore.createEncoder({
|
|
408
|
+
getSizeFromValue: (option) => codecsCore.getEncodedSize(Number(option !== null), prefix) + (option !== null ? codecsCore.getEncodedSize(option, item) : 0),
|
|
409
|
+
maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? void 0,
|
|
410
|
+
write: (option, bytes, offset) => {
|
|
411
|
+
offset = prefix.write(Number(option !== null), bytes, offset);
|
|
412
|
+
if (option !== null) {
|
|
413
|
+
offset = item.write(option, bytes, offset);
|
|
414
|
+
}
|
|
415
|
+
return offset;
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function getNullableDecoder(item, config = {}) {
|
|
420
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
|
|
421
|
+
const fixed = config.fixed ?? false;
|
|
422
|
+
let fixedSize = null;
|
|
423
|
+
const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
|
|
424
|
+
if (fixed || isZeroSizeItem) {
|
|
425
|
+
try {
|
|
426
|
+
codecsCore.assertIsFixedSize(item);
|
|
427
|
+
} catch (e) {
|
|
428
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
429
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
|
|
430
|
+
} else {
|
|
431
|
+
throw e;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
codecsCore.assertIsFixedSize(prefix);
|
|
436
|
+
} catch (e) {
|
|
437
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
438
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
|
|
439
|
+
} else {
|
|
440
|
+
throw e;
|
|
351
441
|
}
|
|
352
|
-
return [map, offset];
|
|
353
442
|
}
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
function getMapCodec(key, value, options = {}) {
|
|
357
|
-
return codecsCore.combineCodec(getMapEncoder(key, value, options), getMapDecoder(key, value, options));
|
|
358
|
-
}
|
|
359
|
-
function nullableCodecHelper(item, prefix, fixed, description) {
|
|
360
|
-
let descriptionSuffix = `; ${prefix.description}`;
|
|
361
|
-
let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;
|
|
362
|
-
if (fixed) {
|
|
363
|
-
codecsCore.assertFixedSizeCodec(item, "Fixed nullables can only be used with fixed-size codecs.");
|
|
364
|
-
codecsCore.assertFixedSizeCodec(prefix, "Fixed nullables can only be used with fixed-size prefix.");
|
|
365
|
-
descriptionSuffix += "; fixed";
|
|
366
443
|
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
367
444
|
}
|
|
368
|
-
return {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
function getNullableEncoder(item, options = {}) {
|
|
375
|
-
const prefix = options.prefix ?? codecsNumbers.getU8Encoder();
|
|
376
|
-
const fixed = options.fixed ?? false;
|
|
377
|
-
return {
|
|
378
|
-
...nullableCodecHelper(item, prefix, fixed, options.description),
|
|
379
|
-
encode: (option) => {
|
|
380
|
-
const prefixByte = prefix.encode(Number(option !== null));
|
|
381
|
-
let itemBytes = option !== null ? item.encode(option) : new Uint8Array();
|
|
382
|
-
itemBytes = fixed ? codecsCore.fixBytes(itemBytes, item.fixedSize) : itemBytes;
|
|
383
|
-
return codecsCore.mergeBytes([prefixByte, itemBytes]);
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
function getNullableDecoder(item, options = {}) {
|
|
388
|
-
const prefix = options.prefix ?? codecsNumbers.getU8Decoder();
|
|
389
|
-
const fixed = options.fixed ?? false;
|
|
390
|
-
return {
|
|
391
|
-
...nullableCodecHelper(item, prefix, fixed, options.description),
|
|
392
|
-
decode: (bytes, offset = 0) => {
|
|
445
|
+
return codecsCore.createDecoder({
|
|
446
|
+
...fixedSize === null ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? void 0 } : { fixedSize },
|
|
447
|
+
read: (bytes, offset) => {
|
|
393
448
|
if (bytes.length - offset <= 0) {
|
|
394
449
|
return [null, offset];
|
|
395
450
|
}
|
|
396
|
-
const
|
|
397
|
-
const [isSome, prefixOffset] = prefix.decode(bytes, offset);
|
|
398
|
-
offset = prefixOffset;
|
|
451
|
+
const [isSome, prefixOffset] = prefix.read(bytes, offset);
|
|
399
452
|
if (isSome === 0) {
|
|
400
|
-
return [null,
|
|
453
|
+
return [null, fixedSize !== null ? offset + fixedSize : prefixOffset];
|
|
401
454
|
}
|
|
402
|
-
const [value, newOffset] = item.
|
|
403
|
-
offset
|
|
404
|
-
return [value, fixed ? fixedOffset : offset];
|
|
455
|
+
const [value, newOffset] = item.read(bytes, prefixOffset);
|
|
456
|
+
return [value, fixedSize !== null ? offset + fixedSize : newOffset];
|
|
405
457
|
}
|
|
406
|
-
};
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
function getNullableCodec(item, config = {}) {
|
|
461
|
+
const configCast = config;
|
|
462
|
+
return codecsCore.combineCodec(getNullableEncoder(item, configCast), getNullableDecoder(item, configCast));
|
|
463
|
+
}
|
|
464
|
+
function getScalarEnumEncoder(constructor, config = {}) {
|
|
465
|
+
const prefix = config.size ?? codecsNumbers.getU8Encoder();
|
|
466
|
+
const { minRange, maxRange, allStringInputs, enumKeys, enumValues } = getScalarEnumStats(constructor);
|
|
467
|
+
return codecsCore.mapEncoder(prefix, (value) => {
|
|
468
|
+
const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
|
|
469
|
+
const isInvalidString = typeof value === "string" && !allStringInputs.includes(value);
|
|
470
|
+
if (isInvalidNumber || isInvalidString) {
|
|
471
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_SCALAR_ENUM_VARIANT, {
|
|
472
|
+
maxRange,
|
|
473
|
+
minRange,
|
|
474
|
+
value,
|
|
475
|
+
variants: allStringInputs
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (typeof value === "number")
|
|
479
|
+
return value;
|
|
480
|
+
const valueIndex = enumValues.indexOf(value);
|
|
481
|
+
if (valueIndex >= 0)
|
|
482
|
+
return valueIndex;
|
|
483
|
+
return enumKeys.indexOf(value);
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
function getScalarEnumDecoder(constructor, config = {}) {
|
|
487
|
+
const prefix = config.size ?? codecsNumbers.getU8Decoder();
|
|
488
|
+
const { minRange, maxRange, enumKeys } = getScalarEnumStats(constructor);
|
|
489
|
+
return codecsCore.mapDecoder(prefix, (value) => {
|
|
490
|
+
const valueAsNumber = Number(value);
|
|
491
|
+
if (valueAsNumber < minRange || valueAsNumber > maxRange) {
|
|
492
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
493
|
+
discriminator: valueAsNumber,
|
|
494
|
+
maxRange,
|
|
495
|
+
minRange
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
return constructor[enumKeys[valueAsNumber]];
|
|
499
|
+
});
|
|
407
500
|
}
|
|
408
|
-
function
|
|
409
|
-
return codecsCore.combineCodec(
|
|
501
|
+
function getScalarEnumCodec(constructor, config = {}) {
|
|
502
|
+
return codecsCore.combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
|
|
410
503
|
}
|
|
411
|
-
function
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
504
|
+
function getScalarEnumStats(constructor) {
|
|
505
|
+
const numericValues = Object.values(constructor).filter((v) => typeof v === "number");
|
|
506
|
+
const deduplicatedConstructor = Object.fromEntries(
|
|
507
|
+
Object.entries(constructor).slice(numericValues.length)
|
|
508
|
+
);
|
|
509
|
+
const enumKeys = Object.keys(deduplicatedConstructor);
|
|
510
|
+
const enumValues = Object.values(deduplicatedConstructor);
|
|
416
511
|
const minRange = 0;
|
|
417
|
-
const maxRange =
|
|
418
|
-
const
|
|
512
|
+
const maxRange = enumValues.length - 1;
|
|
513
|
+
const allStringInputs = [
|
|
514
|
+
.../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
|
|
515
|
+
];
|
|
419
516
|
return {
|
|
420
|
-
|
|
517
|
+
allStringInputs,
|
|
421
518
|
enumKeys,
|
|
422
519
|
enumValues,
|
|
423
|
-
fixedSize: prefix.fixedSize,
|
|
424
|
-
isNumericEnum,
|
|
425
520
|
maxRange,
|
|
426
|
-
|
|
427
|
-
minRange,
|
|
428
|
-
stringValues
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
|
-
function getScalarEnumEncoder(constructor, options = {}) {
|
|
432
|
-
const prefix = options.size ?? codecsNumbers.getU8Encoder();
|
|
433
|
-
const { description, fixedSize, maxSize, minRange, maxRange, stringValues, enumKeys, enumValues } = scalarEnumCoderHelper(constructor, prefix, options.description);
|
|
434
|
-
return {
|
|
435
|
-
description,
|
|
436
|
-
encode: (value) => {
|
|
437
|
-
const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
|
|
438
|
-
const isInvalidString = typeof value === "string" && !stringValues.includes(value);
|
|
439
|
-
if (isInvalidNumber || isInvalidString) {
|
|
440
|
-
throw new Error(
|
|
441
|
-
`Invalid scalar enum variant. Expected one of [${stringValues.join(", ")}] or a number between ${minRange} and ${maxRange}, got "${value}".`
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
if (typeof value === "number")
|
|
445
|
-
return prefix.encode(value);
|
|
446
|
-
const valueIndex = enumValues.indexOf(value);
|
|
447
|
-
if (valueIndex >= 0)
|
|
448
|
-
return prefix.encode(valueIndex);
|
|
449
|
-
return prefix.encode(enumKeys.indexOf(value));
|
|
450
|
-
},
|
|
451
|
-
fixedSize,
|
|
452
|
-
maxSize
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
function getScalarEnumDecoder(constructor, options = {}) {
|
|
456
|
-
const prefix = options.size ?? codecsNumbers.getU8Decoder();
|
|
457
|
-
const { description, fixedSize, maxSize, minRange, maxRange, isNumericEnum, enumValues } = scalarEnumCoderHelper(
|
|
458
|
-
constructor,
|
|
459
|
-
prefix,
|
|
460
|
-
options.description
|
|
461
|
-
);
|
|
462
|
-
return {
|
|
463
|
-
decode: (bytes, offset = 0) => {
|
|
464
|
-
codecsCore.assertByteArrayIsNotEmptyForCodec("enum", bytes, offset);
|
|
465
|
-
const [value, newOffset] = prefix.decode(bytes, offset);
|
|
466
|
-
const valueAsNumber = Number(value);
|
|
467
|
-
offset = newOffset;
|
|
468
|
-
if (valueAsNumber < minRange || valueAsNumber > maxRange) {
|
|
469
|
-
throw new Error(
|
|
470
|
-
`Enum discriminator out of range. Expected a number between ${minRange} and ${maxRange}, got ${valueAsNumber}.`
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
return [isNumericEnum ? valueAsNumber : enumValues[valueAsNumber], offset];
|
|
474
|
-
},
|
|
475
|
-
description,
|
|
476
|
-
fixedSize,
|
|
477
|
-
maxSize
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
function getScalarEnumCodec(constructor, options = {}) {
|
|
481
|
-
return codecsCore.combineCodec(getScalarEnumEncoder(constructor, options), getScalarEnumDecoder(constructor, options));
|
|
482
|
-
}
|
|
483
|
-
function setCodecHelper(item, size, description) {
|
|
484
|
-
if (size === "remainder" && item.fixedSize === null) {
|
|
485
|
-
throw new Error('Codecs of "remainder" size must have fixed-size items.');
|
|
486
|
-
}
|
|
487
|
-
return {
|
|
488
|
-
description: description ?? `set(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`,
|
|
489
|
-
fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]),
|
|
490
|
-
maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize])
|
|
521
|
+
minRange
|
|
491
522
|
};
|
|
492
523
|
}
|
|
493
|
-
function getSetEncoder(item,
|
|
494
|
-
|
|
495
|
-
return {
|
|
496
|
-
...setCodecHelper(item, size, options.description),
|
|
497
|
-
encode: (set) => {
|
|
498
|
-
if (typeof size === "number" && set.size !== size) {
|
|
499
|
-
assertValidNumberOfItemsForCodec("set", size, set.size);
|
|
500
|
-
}
|
|
501
|
-
const itemBytes = Array.from(set, (value) => item.encode(value));
|
|
502
|
-
return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, set.size), ...itemBytes]);
|
|
503
|
-
}
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
function getSetDecoder(item, options = {}) {
|
|
507
|
-
const size = options.size ?? codecsNumbers.getU32Decoder();
|
|
508
|
-
return {
|
|
509
|
-
...setCodecHelper(item, size, options.description),
|
|
510
|
-
decode: (bytes, offset = 0) => {
|
|
511
|
-
const set = /* @__PURE__ */ new Set();
|
|
512
|
-
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
513
|
-
return [set, offset];
|
|
514
|
-
}
|
|
515
|
-
const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
|
|
516
|
-
offset = newOffset;
|
|
517
|
-
for (let i = 0; i < resolvedSize; i += 1) {
|
|
518
|
-
const [value, newOffset2] = item.decode(bytes, offset);
|
|
519
|
-
offset = newOffset2;
|
|
520
|
-
set.add(value);
|
|
521
|
-
}
|
|
522
|
-
return [set, offset];
|
|
523
|
-
}
|
|
524
|
-
};
|
|
524
|
+
function getSetEncoder(item, config = {}) {
|
|
525
|
+
return codecsCore.mapEncoder(getArrayEncoder(item, config), (set) => [...set]);
|
|
525
526
|
}
|
|
526
|
-
function
|
|
527
|
-
return codecsCore.
|
|
527
|
+
function getSetDecoder(item, config = {}) {
|
|
528
|
+
return codecsCore.mapDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
|
|
528
529
|
}
|
|
529
|
-
function
|
|
530
|
-
|
|
531
|
-
return {
|
|
532
|
-
description: description ?? `struct(${fieldDescriptions})`,
|
|
533
|
-
fixedSize: sumCodecSizes(fields.map(([, field]) => field.fixedSize)),
|
|
534
|
-
maxSize: sumCodecSizes(fields.map(([, field]) => field.maxSize))
|
|
535
|
-
};
|
|
530
|
+
function getSetCodec(item, config = {}) {
|
|
531
|
+
return codecsCore.combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
|
|
536
532
|
}
|
|
537
|
-
function getStructEncoder(fields
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
533
|
+
function getStructEncoder(fields) {
|
|
534
|
+
const fieldCodecs = fields.map(([, codec]) => codec);
|
|
535
|
+
const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
|
|
536
|
+
const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
|
|
537
|
+
return codecsCore.createEncoder({
|
|
538
|
+
...fixedSize === null ? {
|
|
539
|
+
getSizeFromValue: (value) => fields.map(([key, codec]) => codecsCore.getEncodedSize(value[key], codec)).reduce((all, one) => all + one, 0),
|
|
540
|
+
maxSize
|
|
541
|
+
} : { fixedSize },
|
|
542
|
+
write: (struct, bytes, offset) => {
|
|
543
|
+
fields.forEach(([key, codec]) => {
|
|
544
|
+
offset = codec.write(struct[key], bytes, offset);
|
|
545
|
+
});
|
|
546
|
+
return offset;
|
|
543
547
|
}
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
function getStructDecoder(fields
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
function getStructDecoder(fields) {
|
|
551
|
+
const fieldCodecs = fields.map(([, codec]) => codec);
|
|
552
|
+
const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
|
|
553
|
+
const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
|
|
554
|
+
return codecsCore.createDecoder({
|
|
555
|
+
...fixedSize === null ? { maxSize } : { fixedSize },
|
|
556
|
+
read: (bytes, offset) => {
|
|
550
557
|
const struct = {};
|
|
551
558
|
fields.forEach(([key, codec]) => {
|
|
552
|
-
const [value, newOffset] = codec.
|
|
559
|
+
const [value, newOffset] = codec.read(bytes, offset);
|
|
553
560
|
offset = newOffset;
|
|
554
561
|
struct[key] = value;
|
|
555
562
|
});
|
|
556
563
|
return [struct, offset];
|
|
557
564
|
}
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
function getStructCodec(fields, options = {}) {
|
|
561
|
-
return codecsCore.combineCodec(getStructEncoder(fields, options), getStructDecoder(fields, options));
|
|
562
|
-
}
|
|
563
|
-
function tupleCodecHelper(items, description) {
|
|
564
|
-
const itemDescriptions = items.map((item) => item.description).join(", ");
|
|
565
|
-
return {
|
|
566
|
-
description: description ?? `tuple(${itemDescriptions})`,
|
|
567
|
-
fixedSize: sumCodecSizes(items.map((item) => item.fixedSize)),
|
|
568
|
-
maxSize: sumCodecSizes(items.map((item) => item.maxSize))
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
function getTupleEncoder(items, options = {}) {
|
|
572
|
-
return {
|
|
573
|
-
...tupleCodecHelper(items, options.description),
|
|
574
|
-
encode: (value) => {
|
|
575
|
-
assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
|
|
576
|
-
return codecsCore.mergeBytes(items.map((item, index) => item.encode(value[index])));
|
|
577
|
-
}
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
function getTupleDecoder(items, options = {}) {
|
|
581
|
-
return {
|
|
582
|
-
...tupleCodecHelper(items, options.description),
|
|
583
|
-
decode: (bytes, offset = 0) => {
|
|
584
|
-
const values = [];
|
|
585
|
-
items.forEach((codec) => {
|
|
586
|
-
const [newValue, newOffset] = codec.decode(bytes, offset);
|
|
587
|
-
values.push(newValue);
|
|
588
|
-
offset = newOffset;
|
|
589
|
-
});
|
|
590
|
-
return [values, offset];
|
|
591
|
-
}
|
|
592
|
-
};
|
|
565
|
+
});
|
|
593
566
|
}
|
|
594
|
-
function
|
|
567
|
+
function getStructCodec(fields) {
|
|
595
568
|
return codecsCore.combineCodec(
|
|
596
|
-
|
|
597
|
-
|
|
569
|
+
getStructEncoder(fields),
|
|
570
|
+
getStructDecoder(fields)
|
|
598
571
|
);
|
|
599
572
|
}
|
|
600
|
-
function getUnitEncoder(
|
|
601
|
-
return {
|
|
602
|
-
description: options.description ?? "unit",
|
|
603
|
-
encode: () => new Uint8Array(),
|
|
573
|
+
function getUnitEncoder() {
|
|
574
|
+
return codecsCore.createEncoder({
|
|
604
575
|
fixedSize: 0,
|
|
605
|
-
|
|
606
|
-
};
|
|
576
|
+
write: (_value, _bytes, offset) => offset
|
|
577
|
+
});
|
|
607
578
|
}
|
|
608
|
-
function getUnitDecoder(
|
|
609
|
-
return {
|
|
610
|
-
decode: (_bytes, offset = 0) => [void 0, offset],
|
|
611
|
-
description: options.description ?? "unit",
|
|
579
|
+
function getUnitDecoder() {
|
|
580
|
+
return codecsCore.createDecoder({
|
|
612
581
|
fixedSize: 0,
|
|
613
|
-
|
|
614
|
-
};
|
|
582
|
+
read: (_bytes, offset) => [void 0, offset]
|
|
583
|
+
});
|
|
615
584
|
}
|
|
616
|
-
function getUnitCodec(
|
|
617
|
-
return codecsCore.combineCodec(getUnitEncoder(
|
|
585
|
+
function getUnitCodec() {
|
|
586
|
+
return codecsCore.combineCodec(getUnitEncoder(), getUnitDecoder());
|
|
618
587
|
}
|
|
619
588
|
|
|
620
589
|
exports.assertValidNumberOfItemsForCodec = assertValidNumberOfItemsForCodec;
|
|
621
|
-
exports.decodeArrayLikeCodecSize = decodeArrayLikeCodecSize;
|
|
622
590
|
exports.getArrayCodec = getArrayCodec;
|
|
623
591
|
exports.getArrayDecoder = getArrayDecoder;
|
|
624
592
|
exports.getArrayEncoder = getArrayEncoder;
|
|
625
|
-
exports.getArrayLikeCodecSizeDescription = getArrayLikeCodecSizeDescription;
|
|
626
|
-
exports.getArrayLikeCodecSizeFromChildren = getArrayLikeCodecSizeFromChildren;
|
|
627
|
-
exports.getArrayLikeCodecSizePrefix = getArrayLikeCodecSizePrefix;
|
|
628
593
|
exports.getBitArrayCodec = getBitArrayCodec;
|
|
629
594
|
exports.getBitArrayDecoder = getBitArrayDecoder;
|
|
630
595
|
exports.getBitArrayEncoder = getBitArrayEncoder;
|