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