@solana/codecs-data-structures 2.0.0-experimental.ce145c8 → 2.0.0-experimental.cee6f23
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/dist/index.browser.cjs +370 -478
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +374 -476
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +372 -476
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +372 -478
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +372 -476
- package/dist/index.node.js.map +1 -1
- package/dist/types/array.d.ts +39 -10
- package/dist/types/array.d.ts.map +1 -0
- package/dist/types/assertions.d.ts.map +1 -0
- package/dist/types/bit-array.d.ts +9 -9
- package/dist/types/bit-array.d.ts.map +1 -0
- package/dist/types/boolean.d.ts +22 -10
- package/dist/types/boolean.d.ts.map +1 -0
- package/dist/types/bytes.d.ts +18 -9
- package/dist/types/bytes.d.ts.map +1 -0
- package/dist/types/data-enum.d.ts +20 -20
- package/dist/types/data-enum.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -14
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/map.d.ts +28 -10
- package/dist/types/map.d.ts.map +1 -0
- package/dist/types/nullable.d.ts +28 -10
- package/dist/types/nullable.d.ts.map +1 -0
- package/dist/types/scalar-enum.d.ts +22 -10
- package/dist/types/scalar-enum.d.ts.map +1 -0
- package/dist/types/set.d.ts +28 -10
- package/dist/types/set.d.ts.map +1 -0
- package/dist/types/struct.d.ts +28 -18
- package/dist/types/struct.d.ts.map +1 -0
- package/dist/types/tuple.d.ts +22 -15
- package/dist/types/tuple.d.ts.map +1 -0
- package/dist/types/unit.d.ts +4 -12
- package/dist/types/unit.d.ts.map +1 -0
- package/dist/types/utils.d.ts +10 -2
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +10 -10
- package/dist/index.development.js +0 -865
- package/dist/index.development.js.map +0 -1
- package/dist/index.production.min.js +0 -51
- package/dist/types/array-like-codec-size.d.ts +0 -20
package/dist/index.browser.cjs
CHANGED
|
@@ -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)}`);
|
|
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;
|
|
23
|
+
function getFixedSize(codec) {
|
|
24
|
+
return codecsCore.isFixedSize(codec) ? codec.fixedSize : null;
|
|
52
25
|
}
|
|
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
|
-
}
|
|
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
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
...arrayCodecHelper(item, size, options.description),
|
|
79
|
-
encode: (value) => {
|
|
31
|
+
function getArrayEncoder(item, config = {}) {
|
|
32
|
+
const size = config.size ?? codecsNumbers.getU32Encoder();
|
|
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);
|
|
82
46
|
}
|
|
83
|
-
|
|
47
|
+
if (typeof size === "object") {
|
|
48
|
+
offset = size.write(array.length, bytes, offset);
|
|
49
|
+
}
|
|
50
|
+
array.forEach((value) => {
|
|
51
|
+
offset = item.write(value, bytes, offset);
|
|
52
|
+
});
|
|
53
|
+
return offset;
|
|
84
54
|
}
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function getArrayDecoder(item,
|
|
88
|
-
const size =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function getArrayDecoder(item, config = {}) {
|
|
58
|
+
const size = config.size ?? codecsNumbers.getU32Decoder();
|
|
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
|
-
function getArrayCodec(item,
|
|
108
|
-
return codecsCore.combineCodec(getArrayEncoder(item,
|
|
88
|
+
function getArrayCodec(item, config = {}) {
|
|
89
|
+
return codecsCore.combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
|
|
109
90
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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 = {}) {
|
|
99
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
100
|
+
const backward = parsedConfig.backward ?? false;
|
|
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, options = {}) => {
|
|
|
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
|
-
|
|
117
|
+
bytes.set(bytesToAdd, offset);
|
|
118
|
+
return size;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function getBitArrayDecoder(size, config = {}) {
|
|
123
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
124
|
+
const backward = parsedConfig.backward ?? false;
|
|
125
|
+
return codecsCore.createDecoder({
|
|
132
126
|
fixedSize: size,
|
|
133
|
-
|
|
134
|
-
};
|
|
135
|
-
};
|
|
136
|
-
var getBitArrayDecoder = (size, options = {}) => {
|
|
137
|
-
const parsedOptions = typeof options === "boolean" ? { backward: options } : options;
|
|
138
|
-
const backward = parsedOptions.backward ?? false;
|
|
139
|
-
const backwardSuffix = backward ? "; backward" : "";
|
|
140
|
-
return {
|
|
141
|
-
decode(bytes, offset = 0) {
|
|
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, options = {}) => {
|
|
|
155
141
|
}
|
|
156
142
|
});
|
|
157
143
|
return [booleans, offset + size];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
codecsCore.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
maxSize: size.fixedSize
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
function getBooleanCodec(options = {}) {
|
|
190
|
-
return codecsCore.combineCodec(getBooleanEncoder(options), getBooleanDecoder(options));
|
|
191
|
-
}
|
|
192
|
-
function getBytesEncoder(options = {}) {
|
|
193
|
-
const size = options.size ?? "variable";
|
|
194
|
-
const sizeDescription = typeof size === "object" ? size.description : `${size}`;
|
|
195
|
-
const description = options.description ?? `bytes(${sizeDescription})`;
|
|
196
|
-
const byteEncoder = {
|
|
197
|
-
description,
|
|
198
|
-
encode: (value) => value,
|
|
199
|
-
fixedSize: null,
|
|
200
|
-
maxSize: null
|
|
201
|
-
};
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function getBitArrayCodec(size, config = {}) {
|
|
148
|
+
return codecsCore.combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
|
|
149
|
+
}
|
|
150
|
+
function getBooleanEncoder(config = {}) {
|
|
151
|
+
const size = config.size ?? codecsNumbers.getU8Encoder();
|
|
152
|
+
codecsCore.assertIsFixedSize(size, "Codec [bool] requires a fixed size.");
|
|
153
|
+
return codecsCore.mapEncoder(size, (value) => value ? 1 : 0);
|
|
154
|
+
}
|
|
155
|
+
function getBooleanDecoder(config = {}) {
|
|
156
|
+
const size = config.size ?? codecsNumbers.getU8Decoder();
|
|
157
|
+
codecsCore.assertIsFixedSize(size, "Codec [bool] requires a fixed size.");
|
|
158
|
+
return codecsCore.mapDecoder(size, (value) => Number(value) === 1);
|
|
159
|
+
}
|
|
160
|
+
function getBooleanCodec(config = {}) {
|
|
161
|
+
return codecsCore.combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
|
|
162
|
+
}
|
|
163
|
+
function getBytesEncoder(config = {}) {
|
|
164
|
+
const size = config.size ?? "variable";
|
|
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
|
-
function getBytesDecoder(
|
|
218
|
-
const size =
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
const byteDecoder = {
|
|
222
|
-
decode: (bytes, offset = 0) => {
|
|
186
|
+
function getBytesDecoder(config = {}) {
|
|
187
|
+
const size = config.size ?? "variable";
|
|
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
|
-
};
|
|
250
|
-
}
|
|
251
|
-
function getBytesCodec(
|
|
252
|
-
return codecsCore.combineCodec(getBytesEncoder(
|
|
253
|
-
}
|
|
254
|
-
function
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (discriminator < 0) {
|
|
272
|
-
throw new Error(
|
|
273
|
-
`Invalid data enum variant. Expected one of [${variants.map(([key]) => key).join(", ")}], got "${variant.__kind}".`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
const variantPrefix = prefix.encode(discriminator);
|
|
277
|
-
const variantSerializer = variants[discriminator][1];
|
|
278
|
-
const variantBytes = variantSerializer.encode(variant);
|
|
279
|
-
return codecsCore.mergeBytes([variantPrefix, variantBytes]);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function getBytesCodec(config = {}) {
|
|
215
|
+
return codecsCore.combineCodec(getBytesEncoder(config), getBytesDecoder(config));
|
|
216
|
+
}
|
|
217
|
+
function getDataEnumEncoder(variants, config = {}) {
|
|
218
|
+
const prefix = config.size ?? codecsNumbers.getU8Encoder();
|
|
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
|
-
};
|
|
282
|
-
}
|
|
283
|
-
function getDataEnumDecoder(variants,
|
|
284
|
-
const prefix =
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function getDataEnumDecoder(variants, config = {}) {
|
|
238
|
+
const prefix = config.size ?? codecsNumbers.getU8Decoder();
|
|
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, options = {}) {
|
|
|
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
|
-
function getDataEnumCodec(variants,
|
|
304
|
-
return codecsCore.combineCodec(getDataEnumEncoder(variants,
|
|
258
|
+
function getDataEnumCodec(variants, config = {}) {
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
return
|
|
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;
|
|
326
301
|
}
|
|
327
|
-
};
|
|
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
|
+
});
|
|
328
319
|
}
|
|
329
|
-
function
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
320
|
+
function getTupleCodec(items) {
|
|
321
|
+
return codecsCore.combineCodec(
|
|
322
|
+
getTupleEncoder(items),
|
|
323
|
+
getTupleDecoder(items)
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/map.ts
|
|
328
|
+
function getMapEncoder(key, value, config = {}) {
|
|
329
|
+
return codecsCore.mapEncoder(
|
|
330
|
+
getArrayEncoder(getTupleEncoder([key, value]), config),
|
|
331
|
+
(map) => [...map.entries()]
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
function getMapDecoder(key, value, config = {}) {
|
|
335
|
+
return codecsCore.mapDecoder(
|
|
336
|
+
getArrayDecoder(getTupleDecoder([key, value]), config),
|
|
337
|
+
(entries) => new Map(entries)
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
function getMapCodec(key, value, config = {}) {
|
|
341
|
+
return codecsCore.combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
|
|
342
|
+
}
|
|
343
|
+
function getNullableEncoder(item, config = {}) {
|
|
344
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
|
|
345
|
+
const fixed = config.fixed ?? false;
|
|
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;
|
|
337
359
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
offset =
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
offset = kOffset;
|
|
348
|
-
const [decodedValue, vOffset] = value.decode(bytes, offset);
|
|
349
|
-
offset = vOffset;
|
|
350
|
-
map.set(decodedKey, decodedValue);
|
|
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);
|
|
351
369
|
}
|
|
352
|
-
return
|
|
370
|
+
return offset;
|
|
353
371
|
}
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
function
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
codecsCore.
|
|
364
|
-
codecsCore.assertFixedSizeCodec(prefix, "Fixed nullables can only be used with fixed-size prefix.");
|
|
365
|
-
descriptionSuffix += "; fixed";
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function getNullableDecoder(item, config = {}) {
|
|
375
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
|
|
376
|
+
const fixed = config.fixed ?? false;
|
|
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.");
|
|
366
382
|
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
367
383
|
}
|
|
368
|
-
return {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
function getNullableEncoder(item, options = {}) {
|
|
375
|
-
const prefix = options.prefix ?? codecsNumbers.getU8Encoder();
|
|
376
|
-
const fixed = options.fixed ?? false;
|
|
377
|
-
return {
|
|
378
|
-
...nullableCodecHelper(item, prefix, fixed, options.description),
|
|
379
|
-
encode: (option) => {
|
|
380
|
-
const prefixByte = prefix.encode(Number(option !== null));
|
|
381
|
-
let itemBytes = option !== null ? item.encode(option) : new Uint8Array();
|
|
382
|
-
itemBytes = fixed ? codecsCore.fixBytes(itemBytes, item.fixedSize) : itemBytes;
|
|
383
|
-
return codecsCore.mergeBytes([prefixByte, itemBytes]);
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
function getNullableDecoder(item, options = {}) {
|
|
388
|
-
const prefix = options.prefix ?? codecsNumbers.getU8Decoder();
|
|
389
|
-
const fixed = options.fixed ?? false;
|
|
390
|
-
return {
|
|
391
|
-
...nullableCodecHelper(item, prefix, fixed, options.description),
|
|
392
|
-
decode: (bytes, offset = 0) => {
|
|
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
|
+
});
|
|
398
|
+
}
|
|
399
|
+
function getNullableCodec(item, config = {}) {
|
|
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
|
+
});
|
|
407
434
|
}
|
|
408
|
-
function
|
|
409
|
-
return codecsCore.combineCodec(
|
|
435
|
+
function getScalarEnumCodec(constructor, config = {}) {
|
|
436
|
+
return codecsCore.combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
|
|
410
437
|
}
|
|
411
|
-
function
|
|
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
|
|
432
|
-
|
|
433
|
-
const { description, fixedSize, maxSize, minRange, maxRange, stringValues, enumKeys, enumValues } = scalarEnumCoderHelper(constructor, prefix, options.description);
|
|
434
|
-
return {
|
|
435
|
-
description,
|
|
436
|
-
encode: (value) => {
|
|
437
|
-
const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
|
|
438
|
-
const isInvalidString = typeof value === "string" && !stringValues.includes(value);
|
|
439
|
-
if (isInvalidNumber || isInvalidString) {
|
|
440
|
-
throw new Error(
|
|
441
|
-
`Invalid scalar enum variant. Expected one of [${stringValues.join(", ")}] or a number between ${minRange} and ${maxRange}, got "${value}".`
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
if (typeof value === "number")
|
|
445
|
-
return prefix.encode(value);
|
|
446
|
-
const valueIndex = enumValues.indexOf(value);
|
|
447
|
-
if (valueIndex >= 0)
|
|
448
|
-
return prefix.encode(valueIndex);
|
|
449
|
-
return prefix.encode(enumKeys.indexOf(value));
|
|
450
|
-
},
|
|
451
|
-
fixedSize,
|
|
452
|
-
maxSize
|
|
453
|
-
};
|
|
454
|
+
function getSetEncoder(item, config = {}) {
|
|
455
|
+
return codecsCore.mapEncoder(getArrayEncoder(item, config), (set) => [...set]);
|
|
454
456
|
}
|
|
455
|
-
function
|
|
456
|
-
|
|
457
|
-
const { description, fixedSize, maxSize, minRange, maxRange, isNumericEnum, enumValues } = scalarEnumCoderHelper(
|
|
458
|
-
constructor,
|
|
459
|
-
prefix,
|
|
460
|
-
options.description
|
|
461
|
-
);
|
|
462
|
-
return {
|
|
463
|
-
decode: (bytes, offset = 0) => {
|
|
464
|
-
codecsCore.assertByteArrayIsNotEmptyForCodec("enum", bytes, offset);
|
|
465
|
-
const [value, newOffset] = prefix.decode(bytes, offset);
|
|
466
|
-
const valueAsNumber = Number(value);
|
|
467
|
-
offset = newOffset;
|
|
468
|
-
if (valueAsNumber < minRange || valueAsNumber > maxRange) {
|
|
469
|
-
throw new Error(
|
|
470
|
-
`Enum discriminator out of range. Expected a number between ${minRange} and ${maxRange}, got ${valueAsNumber}.`
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
return [isNumericEnum ? valueAsNumber : enumValues[valueAsNumber], offset];
|
|
474
|
-
},
|
|
475
|
-
description,
|
|
476
|
-
fixedSize,
|
|
477
|
-
maxSize
|
|
478
|
-
};
|
|
457
|
+
function getSetDecoder(item, config = {}) {
|
|
458
|
+
return codecsCore.mapDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
|
|
479
459
|
}
|
|
480
|
-
function
|
|
481
|
-
return codecsCore.combineCodec(
|
|
460
|
+
function getSetCodec(item, config = {}) {
|
|
461
|
+
return codecsCore.combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
|
|
482
462
|
}
|
|
483
|
-
function
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
return {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
encode: (set) => {
|
|
498
|
-
if (typeof size === "number" && set.size !== size) {
|
|
499
|
-
assertValidNumberOfItemsForCodec("set", size, set.size);
|
|
500
|
-
}
|
|
501
|
-
const itemBytes = Array.from(set, (value) => item.encode(value));
|
|
502
|
-
return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, set.size), ...itemBytes]);
|
|
503
|
-
}
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
function getSetDecoder(item, options = {}) {
|
|
507
|
-
const size = options.size ?? codecsNumbers.getU32Decoder();
|
|
508
|
-
return {
|
|
509
|
-
...setCodecHelper(item, size, options.description),
|
|
510
|
-
decode: (bytes, offset = 0) => {
|
|
511
|
-
const set = /* @__PURE__ */ new Set();
|
|
512
|
-
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
513
|
-
return [set, offset];
|
|
514
|
-
}
|
|
515
|
-
const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
|
|
516
|
-
offset = newOffset;
|
|
517
|
-
for (let i = 0; i < resolvedSize; i += 1) {
|
|
518
|
-
const [value, newOffset2] = item.decode(bytes, offset);
|
|
519
|
-
offset = newOffset2;
|
|
520
|
-
set.add(value);
|
|
521
|
-
}
|
|
522
|
-
return [set, offset];
|
|
523
|
-
}
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
function getSetCodec(item, options = {}) {
|
|
527
|
-
return codecsCore.combineCodec(getSetEncoder(item, options), getSetDecoder(item, options));
|
|
528
|
-
}
|
|
529
|
-
function structCodecHelper(fields, description) {
|
|
530
|
-
const fieldDescriptions = fields.map(([name, codec]) => `${String(name)}: ${codec.description}`).join(", ");
|
|
531
|
-
return {
|
|
532
|
-
description: description ?? `struct(${fieldDescriptions})`,
|
|
533
|
-
fixedSize: sumCodecSizes(fields.map(([, field]) => field.fixedSize)),
|
|
534
|
-
maxSize: sumCodecSizes(fields.map(([, field]) => field.maxSize))
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
function getStructEncoder(fields, options = {}) {
|
|
538
|
-
return {
|
|
539
|
-
...structCodecHelper(fields, options.description),
|
|
540
|
-
encode: (struct) => {
|
|
541
|
-
const fieldBytes = fields.map(([key, codec]) => codec.encode(struct[key]));
|
|
542
|
-
return codecsCore.mergeBytes(fieldBytes);
|
|
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, options = {}) {
|
|
561
|
-
return codecsCore.combineCodec(getStructEncoder(fields, options), getStructDecoder(fields, options));
|
|
562
|
-
}
|
|
563
|
-
function tupleCodecHelper(items, description) {
|
|
564
|
-
const itemDescriptions = items.map((item) => item.description).join(", ");
|
|
565
|
-
return {
|
|
566
|
-
description: description ?? `tuple(${itemDescriptions})`,
|
|
567
|
-
fixedSize: sumCodecSizes(items.map((item) => item.fixedSize)),
|
|
568
|
-
maxSize: sumCodecSizes(items.map((item) => item.maxSize))
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
function getTupleEncoder(items, options = {}) {
|
|
572
|
-
return {
|
|
573
|
-
...tupleCodecHelper(items, options.description),
|
|
574
|
-
encode: (value) => {
|
|
575
|
-
assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
|
|
576
|
-
return codecsCore.mergeBytes(items.map((item, index) => item.encode(value[index])));
|
|
577
|
-
}
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
function getTupleDecoder(items, options = {}) {
|
|
581
|
-
return {
|
|
582
|
-
...tupleCodecHelper(items, options.description),
|
|
583
|
-
decode: (bytes, offset = 0) => {
|
|
584
|
-
const values = [];
|
|
585
|
-
items.forEach((codec) => {
|
|
586
|
-
const [newValue, newOffset] = codec.decode(bytes, offset);
|
|
587
|
-
values.push(newValue);
|
|
588
|
-
offset = newOffset;
|
|
589
|
-
});
|
|
590
|
-
return [values, offset];
|
|
591
|
-
}
|
|
592
|
-
};
|
|
495
|
+
});
|
|
593
496
|
}
|
|
594
|
-
function
|
|
595
|
-
return codecsCore.combineCodec(
|
|
596
|
-
getTupleEncoder(items, options),
|
|
597
|
-
getTupleDecoder(items, options)
|
|
598
|
-
);
|
|
497
|
+
function getStructCodec(fields) {
|
|
498
|
+
return codecsCore.combineCodec(getStructEncoder(fields), getStructDecoder(fields));
|
|
599
499
|
}
|
|
600
|
-
function getUnitEncoder(
|
|
601
|
-
return {
|
|
602
|
-
description: options.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: options.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;
|