@solana/codecs-data-structures 2.0.0-experimental.efe6f4d → 2.0.0-experimental.f054d90
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 +401 -436
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +403 -434
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +403 -434
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +401 -436
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +403 -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 -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/types/array-like-codec-size.d.ts.map +0 -1
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)}`);
|
|
41
|
-
}
|
|
42
|
-
function getArrayLikeCodecSizeDescription(size) {
|
|
43
|
-
return typeof size === "object" ? size.description : `${size}`;
|
|
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;
|
|
26
|
+
function getFixedSize(codec) {
|
|
27
|
+
return codecsCore.isFixedSize(codec) ? codec.fixedSize : null;
|
|
52
28
|
}
|
|
53
|
-
function
|
|
54
|
-
return
|
|
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];
|
|
71
|
+
}
|
|
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];
|
|
94
79
|
}
|
|
95
|
-
const [resolvedSize, newOffset] =
|
|
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,452 @@ 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
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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);
|
|
174
167
|
}
|
|
175
168
|
function getBooleanDecoder(config = {}) {
|
|
176
169
|
const size = config.size ?? codecsNumbers.getU8Decoder();
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
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);
|
|
188
182
|
}
|
|
189
183
|
function getBooleanCodec(config = {}) {
|
|
190
184
|
return codecsCore.combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
|
|
191
185
|
}
|
|
192
186
|
function getBytesEncoder(config = {}) {
|
|
193
187
|
const size = config.size ?? "variable";
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
};
|
|
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
209
|
function getBytesDecoder(config = {}) {
|
|
218
210
|
const size = config.size ?? "variable";
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const byteDecoder = {
|
|
222
|
-
decode: (bytes, offset = 0) => {
|
|
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
|
-
};
|
|
235
|
+
});
|
|
250
236
|
}
|
|
251
237
|
function getBytesCodec(config = {}) {
|
|
252
238
|
return codecsCore.combineCodec(getBytesEncoder(config), getBytesDecoder(config));
|
|
253
239
|
}
|
|
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
240
|
function getDataEnumEncoder(variants, config = {}) {
|
|
266
241
|
const prefix = config.size ?? codecsNumbers.getU8Encoder();
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
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
|
-
};
|
|
258
|
+
});
|
|
282
259
|
}
|
|
283
260
|
function getDataEnumDecoder(variants, config = {}) {
|
|
284
261
|
const prefix = config.size ?? codecsNumbers.getU8Decoder();
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
283
|
function getDataEnumCodec(variants, config = {}) {
|
|
304
|
-
return codecsCore.combineCodec(
|
|
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
|
}
|
|
349
|
+
function getTupleCodec(items) {
|
|
350
|
+
return codecsCore.combineCodec(
|
|
351
|
+
getTupleEncoder(items),
|
|
352
|
+
getTupleDecoder(items)
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/map.ts
|
|
316
357
|
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
|
-
};
|
|
358
|
+
return codecsCore.mapEncoder(
|
|
359
|
+
getArrayEncoder(getTupleEncoder([key, value]), config),
|
|
360
|
+
(map) => [...map.entries()]
|
|
361
|
+
);
|
|
328
362
|
}
|
|
329
363
|
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
|
-
};
|
|
364
|
+
return codecsCore.mapDecoder(
|
|
365
|
+
getArrayDecoder(getTupleDecoder([key, value]), config),
|
|
366
|
+
(entries) => new Map(entries)
|
|
367
|
+
);
|
|
355
368
|
}
|
|
356
369
|
function getMapCodec(key, value, config = {}) {
|
|
357
370
|
return codecsCore.combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
|
|
358
371
|
}
|
|
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
372
|
function getNullableEncoder(item, config = {}) {
|
|
375
373
|
const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
|
|
376
374
|
const fixed = config.fixed ?? false;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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;
|
|
384
|
+
}
|
|
384
385
|
}
|
|
385
|
-
|
|
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;
|
|
393
|
+
}
|
|
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
|
+
});
|
|
386
418
|
}
|
|
387
419
|
function getNullableDecoder(item, config = {}) {
|
|
388
420
|
const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
|
|
389
421
|
const fixed = config.fixed ?? false;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
444
|
+
}
|
|
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
|
+
});
|
|
407
459
|
}
|
|
408
460
|
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
|
-
};
|
|
461
|
+
const configCast = config;
|
|
462
|
+
return codecsCore.combineCodec(getNullableEncoder(item, configCast), getNullableDecoder(item, configCast));
|
|
430
463
|
}
|
|
431
464
|
function getScalarEnumEncoder(constructor, config = {}) {
|
|
432
465
|
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
|
-
};
|
|
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
|
+
});
|
|
454
485
|
}
|
|
455
486
|
function getScalarEnumDecoder(constructor, config = {}) {
|
|
456
487
|
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
|
-
};
|
|
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
|
+
});
|
|
479
500
|
}
|
|
480
501
|
function getScalarEnumCodec(constructor, config = {}) {
|
|
481
502
|
return codecsCore.combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
|
|
482
503
|
}
|
|
483
|
-
function
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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);
|
|
511
|
+
const minRange = 0;
|
|
512
|
+
const maxRange = enumValues.length - 1;
|
|
513
|
+
const allStringInputs = [
|
|
514
|
+
.../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
|
|
515
|
+
];
|
|
487
516
|
return {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
517
|
+
allStringInputs,
|
|
518
|
+
enumKeys,
|
|
519
|
+
enumValues,
|
|
520
|
+
maxRange,
|
|
521
|
+
minRange
|
|
491
522
|
};
|
|
492
523
|
}
|
|
493
524
|
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
|
-
};
|
|
525
|
+
return codecsCore.mapEncoder(getArrayEncoder(item, config), (set) => [...set]);
|
|
505
526
|
}
|
|
506
527
|
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
|
-
};
|
|
528
|
+
return codecsCore.mapDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
|
|
525
529
|
}
|
|
526
530
|
function getSetCodec(item, config = {}) {
|
|
527
531
|
return codecsCore.combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
|
|
528
532
|
}
|
|
529
|
-
function
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
return
|
|
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, 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
|
-
};
|
|
565
|
+
});
|
|
579
566
|
}
|
|
580
|
-
function
|
|
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
|
-
};
|
|
593
|
-
}
|
|
594
|
-
function getTupleCodec(items, config = {}) {
|
|
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: config.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: config.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;
|