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