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