@solana/codecs-data-structures 2.0.0-canary-20240731173615
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/LICENSE +20 -0
- package/README.md +728 -0
- package/dist/index.browser.cjs +709 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.mjs +653 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.native.mjs +653 -0
- package/dist/index.native.mjs.map +1 -0
- package/dist/index.node.cjs +709 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.mjs +653 -0
- package/dist/index.node.mjs.map +1 -0
- package/dist/types/array.d.ts +62 -0
- package/dist/types/array.d.ts.map +1 -0
- package/dist/types/assertions.d.ts +3 -0
- package/dist/types/assertions.d.ts.map +1 -0
- package/dist/types/bit-array.d.ts +31 -0
- package/dist/types/bit-array.d.ts.map +1 -0
- package/dist/types/boolean.d.ts +41 -0
- package/dist/types/boolean.d.ts.map +1 -0
- package/dist/types/bytes.d.ts +23 -0
- package/dist/types/bytes.d.ts.map +1 -0
- package/dist/types/constant.d.ts +16 -0
- package/dist/types/constant.d.ts.map +1 -0
- package/dist/types/discriminated-union.d.ts +97 -0
- package/dist/types/discriminated-union.d.ts.map +1 -0
- package/dist/types/enum-helpers.d.ts +51 -0
- package/dist/types/enum-helpers.d.ts.map +1 -0
- package/dist/types/enum.d.ts +57 -0
- package/dist/types/enum.d.ts.map +1 -0
- package/dist/types/hidden-prefix.d.ts +20 -0
- package/dist/types/hidden-prefix.d.ts.map +1 -0
- package/dist/types/hidden-suffix.d.ts +20 -0
- package/dist/types/hidden-suffix.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/map.d.ts +54 -0
- package/dist/types/map.d.ts.map +1 -0
- package/dist/types/nullable.d.ts +95 -0
- package/dist/types/nullable.d.ts.map +1 -0
- package/dist/types/set.d.ts +51 -0
- package/dist/types/set.d.ts.map +1 -0
- package/dist/types/struct.d.ts +33 -0
- package/dist/types/struct.d.ts.map +1 -0
- package/dist/types/tuple.d.ts +31 -0
- package/dist/types/tuple.d.ts.map +1 -0
- package/dist/types/union.d.ts +32 -0
- package/dist/types/union.d.ts.map +1 -0
- package/dist/types/unit.d.ts +14 -0
- package/dist/types/unit.d.ts.map +1 -0
- package/dist/types/utils.d.ts +24 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
import { createEncoder, getEncodedSize, createDecoder, combineCodec, assertByteArrayHasEnoughBytesForCodec, transformEncoder, transformDecoder, containsBytes, isFixedSize, assertIsFixedSize, fixEncoderSize, fixDecoderSize } from '@solana/codecs-core';
|
|
2
|
+
import { getU32Encoder, getU32Decoder, getU8Encoder, getU8Decoder } from '@solana/codecs-numbers';
|
|
3
|
+
import { SolanaError, SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SOLANA_ERROR__CODECS__INVALID_CONSTANT, SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT, SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE } from '@solana/errors';
|
|
4
|
+
|
|
5
|
+
// src/array.ts
|
|
6
|
+
function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
|
|
7
|
+
if (expected !== actual) {
|
|
8
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {
|
|
9
|
+
actual,
|
|
10
|
+
codecDescription,
|
|
11
|
+
expected
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function maxCodecSizes(sizes) {
|
|
16
|
+
return sizes.reduce(
|
|
17
|
+
(all, size) => all === null || size === null ? null : Math.max(all, size),
|
|
18
|
+
0
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
function sumCodecSizes(sizes) {
|
|
22
|
+
return sizes.reduce((all, size) => all === null || size === null ? null : all + size, 0);
|
|
23
|
+
}
|
|
24
|
+
function getFixedSize(codec) {
|
|
25
|
+
return isFixedSize(codec) ? codec.fixedSize : null;
|
|
26
|
+
}
|
|
27
|
+
function getMaxSize(codec) {
|
|
28
|
+
return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/array.ts
|
|
32
|
+
function getArrayEncoder(item, config = {}) {
|
|
33
|
+
const size = config.size ?? getU32Encoder();
|
|
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) => {
|
|
45
|
+
if (typeof size === "number") {
|
|
46
|
+
assertValidNumberOfItemsForCodec("array", size, array.length);
|
|
47
|
+
}
|
|
48
|
+
if (typeof size === "object") {
|
|
49
|
+
offset = size.write(array.length, bytes, offset);
|
|
50
|
+
}
|
|
51
|
+
array.forEach((value) => {
|
|
52
|
+
offset = item.write(value, bytes, offset);
|
|
53
|
+
});
|
|
54
|
+
return offset;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function getArrayDecoder(item, config = {}) {
|
|
59
|
+
const size = config.size ?? getU32Decoder();
|
|
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 = [];
|
|
67
|
+
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
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];
|
|
77
|
+
}
|
|
78
|
+
const [resolvedSize, newOffset] = typeof size === "number" ? [size, offset] : size.read(bytes, offset);
|
|
79
|
+
offset = newOffset;
|
|
80
|
+
for (let i = 0; i < resolvedSize; i += 1) {
|
|
81
|
+
const [value, newOffset2] = item.read(bytes, offset);
|
|
82
|
+
offset = newOffset2;
|
|
83
|
+
array.push(value);
|
|
84
|
+
}
|
|
85
|
+
return [array, offset];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function getArrayCodec(item, config = {}) {
|
|
90
|
+
return combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
|
|
91
|
+
}
|
|
92
|
+
function computeArrayLikeCodecSize(size, itemSize) {
|
|
93
|
+
if (typeof size !== "number") return null;
|
|
94
|
+
if (size === 0) return 0;
|
|
95
|
+
return itemSize === null ? null : itemSize * size;
|
|
96
|
+
}
|
|
97
|
+
function getBitArrayEncoder(size, config = {}) {
|
|
98
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
99
|
+
const backward = parsedConfig.backward ?? false;
|
|
100
|
+
return createEncoder({
|
|
101
|
+
fixedSize: size,
|
|
102
|
+
write(value, bytes, offset) {
|
|
103
|
+
const bytesToAdd = [];
|
|
104
|
+
for (let i = 0; i < size; i += 1) {
|
|
105
|
+
let byte = 0;
|
|
106
|
+
for (let j = 0; j < 8; j += 1) {
|
|
107
|
+
const feature = Number(value[i * 8 + j] ?? 0);
|
|
108
|
+
byte |= feature << (backward ? j : 7 - j);
|
|
109
|
+
}
|
|
110
|
+
if (backward) {
|
|
111
|
+
bytesToAdd.unshift(byte);
|
|
112
|
+
} else {
|
|
113
|
+
bytesToAdd.push(byte);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
bytes.set(bytesToAdd, offset);
|
|
117
|
+
return size;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function getBitArrayDecoder(size, config = {}) {
|
|
122
|
+
const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
|
|
123
|
+
const backward = parsedConfig.backward ?? false;
|
|
124
|
+
return createDecoder({
|
|
125
|
+
fixedSize: size,
|
|
126
|
+
read(bytes, offset) {
|
|
127
|
+
assertByteArrayHasEnoughBytesForCodec("bitArray", size, bytes, offset);
|
|
128
|
+
const booleans = [];
|
|
129
|
+
let slice = bytes.slice(offset, offset + size);
|
|
130
|
+
slice = backward ? slice.reverse() : slice;
|
|
131
|
+
slice.forEach((byte) => {
|
|
132
|
+
for (let i = 0; i < 8; i += 1) {
|
|
133
|
+
if (backward) {
|
|
134
|
+
booleans.push(Boolean(byte & 1));
|
|
135
|
+
byte >>= 1;
|
|
136
|
+
} else {
|
|
137
|
+
booleans.push(Boolean(byte & 128));
|
|
138
|
+
byte <<= 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return [booleans, offset + size];
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function getBitArrayCodec(size, config = {}) {
|
|
147
|
+
return combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
|
|
148
|
+
}
|
|
149
|
+
function getBooleanEncoder(config = {}) {
|
|
150
|
+
return transformEncoder(config.size ?? getU8Encoder(), (value) => value ? 1 : 0);
|
|
151
|
+
}
|
|
152
|
+
function getBooleanDecoder(config = {}) {
|
|
153
|
+
return transformDecoder(config.size ?? getU8Decoder(), (value) => Number(value) === 1);
|
|
154
|
+
}
|
|
155
|
+
function getBooleanCodec(config = {}) {
|
|
156
|
+
return combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
|
|
157
|
+
}
|
|
158
|
+
function getBytesEncoder() {
|
|
159
|
+
return createEncoder({
|
|
160
|
+
getSizeFromValue: (value) => value.length,
|
|
161
|
+
write: (value, bytes, offset) => {
|
|
162
|
+
bytes.set(value, offset);
|
|
163
|
+
return offset + value.length;
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function getBytesDecoder() {
|
|
168
|
+
return createDecoder({
|
|
169
|
+
read: (bytes, offset) => {
|
|
170
|
+
const slice = bytes.slice(offset);
|
|
171
|
+
return [slice, offset + slice.length];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function getBytesCodec() {
|
|
176
|
+
return combineCodec(getBytesEncoder(), getBytesDecoder());
|
|
177
|
+
}
|
|
178
|
+
var getBase16Decoder = () => createDecoder({
|
|
179
|
+
read(bytes, offset) {
|
|
180
|
+
const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
|
|
181
|
+
return [value, bytes.length];
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
function getConstantEncoder(constant) {
|
|
185
|
+
return createEncoder({
|
|
186
|
+
fixedSize: constant.length,
|
|
187
|
+
write: (_, bytes, offset) => {
|
|
188
|
+
bytes.set(constant, offset);
|
|
189
|
+
return offset + constant.length;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function getConstantDecoder(constant) {
|
|
194
|
+
return createDecoder({
|
|
195
|
+
fixedSize: constant.length,
|
|
196
|
+
read: (bytes, offset) => {
|
|
197
|
+
const base16 = getBase16Decoder();
|
|
198
|
+
if (!containsBytes(bytes, constant, offset)) {
|
|
199
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {
|
|
200
|
+
constant,
|
|
201
|
+
data: bytes,
|
|
202
|
+
hexConstant: base16.decode(constant),
|
|
203
|
+
hexData: base16.decode(bytes),
|
|
204
|
+
offset
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
return [void 0, offset + constant.length];
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function getConstantCodec(constant) {
|
|
212
|
+
return combineCodec(getConstantEncoder(constant), getConstantDecoder(constant));
|
|
213
|
+
}
|
|
214
|
+
function getTupleEncoder(items) {
|
|
215
|
+
const fixedSize = sumCodecSizes(items.map(getFixedSize));
|
|
216
|
+
const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
|
|
217
|
+
return createEncoder({
|
|
218
|
+
...fixedSize === null ? {
|
|
219
|
+
getSizeFromValue: (value) => items.map((item, index) => getEncodedSize(value[index], item)).reduce((all, one) => all + one, 0),
|
|
220
|
+
maxSize
|
|
221
|
+
} : { fixedSize },
|
|
222
|
+
write: (value, bytes, offset) => {
|
|
223
|
+
assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
|
|
224
|
+
items.forEach((item, index) => {
|
|
225
|
+
offset = item.write(value[index], bytes, offset);
|
|
226
|
+
});
|
|
227
|
+
return offset;
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function getTupleDecoder(items) {
|
|
232
|
+
const fixedSize = sumCodecSizes(items.map(getFixedSize));
|
|
233
|
+
const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
|
|
234
|
+
return createDecoder({
|
|
235
|
+
...fixedSize === null ? { maxSize } : { fixedSize },
|
|
236
|
+
read: (bytes, offset) => {
|
|
237
|
+
const values = [];
|
|
238
|
+
items.forEach((item) => {
|
|
239
|
+
const [newValue, newOffset] = item.read(bytes, offset);
|
|
240
|
+
values.push(newValue);
|
|
241
|
+
offset = newOffset;
|
|
242
|
+
});
|
|
243
|
+
return [values, offset];
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function getTupleCodec(items) {
|
|
248
|
+
return combineCodec(
|
|
249
|
+
getTupleEncoder(items),
|
|
250
|
+
getTupleDecoder(items)
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
function getUnionEncoder(variants, getIndexFromValue) {
|
|
254
|
+
const fixedSize = getUnionFixedSize(variants);
|
|
255
|
+
const write = (variant, bytes, offset) => {
|
|
256
|
+
const index = getIndexFromValue(variant);
|
|
257
|
+
assertValidVariantIndex(variants, index);
|
|
258
|
+
return variants[index].write(variant, bytes, offset);
|
|
259
|
+
};
|
|
260
|
+
if (fixedSize !== null) {
|
|
261
|
+
return createEncoder({ fixedSize, write });
|
|
262
|
+
}
|
|
263
|
+
const maxSize = getUnionMaxSize(variants);
|
|
264
|
+
return createEncoder({
|
|
265
|
+
...maxSize !== null ? { maxSize } : {},
|
|
266
|
+
getSizeFromValue: (variant) => {
|
|
267
|
+
const index = getIndexFromValue(variant);
|
|
268
|
+
assertValidVariantIndex(variants, index);
|
|
269
|
+
return getEncodedSize(variant, variants[index]);
|
|
270
|
+
},
|
|
271
|
+
write
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function getUnionDecoder(variants, getIndexFromBytes) {
|
|
275
|
+
const fixedSize = getUnionFixedSize(variants);
|
|
276
|
+
const read = (bytes, offset) => {
|
|
277
|
+
const index = getIndexFromBytes(bytes, offset);
|
|
278
|
+
assertValidVariantIndex(variants, index);
|
|
279
|
+
return variants[index].read(bytes, offset);
|
|
280
|
+
};
|
|
281
|
+
if (fixedSize !== null) {
|
|
282
|
+
return createDecoder({ fixedSize, read });
|
|
283
|
+
}
|
|
284
|
+
const maxSize = getUnionMaxSize(variants);
|
|
285
|
+
return createDecoder({ ...maxSize !== null ? { maxSize } : {}, read });
|
|
286
|
+
}
|
|
287
|
+
function getUnionCodec(variants, getIndexFromValue, getIndexFromBytes) {
|
|
288
|
+
return combineCodec(
|
|
289
|
+
getUnionEncoder(variants, getIndexFromValue),
|
|
290
|
+
getUnionDecoder(variants, getIndexFromBytes)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function assertValidVariantIndex(variants, index) {
|
|
294
|
+
if (typeof variants[index] === "undefined") {
|
|
295
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, {
|
|
296
|
+
maxRange: variants.length - 1,
|
|
297
|
+
minRange: 0,
|
|
298
|
+
variant: index
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function getUnionFixedSize(variants) {
|
|
303
|
+
if (variants.length === 0) return 0;
|
|
304
|
+
if (!isFixedSize(variants[0])) return null;
|
|
305
|
+
const variantSize = variants[0].fixedSize;
|
|
306
|
+
const sameSizedVariants = variants.every((variant) => isFixedSize(variant) && variant.fixedSize === variantSize);
|
|
307
|
+
return sameSizedVariants ? variantSize : null;
|
|
308
|
+
}
|
|
309
|
+
function getUnionMaxSize(variants) {
|
|
310
|
+
return maxCodecSizes(variants.map((variant) => getMaxSize(variant)));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// src/discriminated-union.ts
|
|
314
|
+
function getDiscriminatedUnionEncoder(variants, config = {}) {
|
|
315
|
+
const discriminatorProperty = config.discriminator ?? "__kind";
|
|
316
|
+
const prefix = config.size ?? getU8Encoder();
|
|
317
|
+
return getUnionEncoder(
|
|
318
|
+
variants.map(
|
|
319
|
+
([, variant], index) => transformEncoder(getTupleEncoder([prefix, variant]), (value) => [index, value])
|
|
320
|
+
),
|
|
321
|
+
(value) => getVariantDiscriminator(variants, value[discriminatorProperty])
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
function getDiscriminatedUnionDecoder(variants, config = {}) {
|
|
325
|
+
const discriminatorProperty = config.discriminator ?? "__kind";
|
|
326
|
+
const prefix = config.size ?? getU8Decoder();
|
|
327
|
+
return getUnionDecoder(
|
|
328
|
+
variants.map(
|
|
329
|
+
([discriminator, variant]) => transformDecoder(getTupleDecoder([prefix, variant]), ([, value]) => ({
|
|
330
|
+
[discriminatorProperty]: discriminator,
|
|
331
|
+
...value
|
|
332
|
+
}))
|
|
333
|
+
),
|
|
334
|
+
(bytes, offset) => Number(prefix.read(bytes, offset)[0])
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
function getDiscriminatedUnionCodec(variants, config = {}) {
|
|
338
|
+
return combineCodec(
|
|
339
|
+
getDiscriminatedUnionEncoder(variants, config),
|
|
340
|
+
getDiscriminatedUnionDecoder(variants, config)
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
function getVariantDiscriminator(variants, discriminatorValue) {
|
|
344
|
+
const discriminator = variants.findIndex(([key]) => discriminatorValue === key);
|
|
345
|
+
if (discriminator < 0) {
|
|
346
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT, {
|
|
347
|
+
value: discriminatorValue,
|
|
348
|
+
variants: variants.map(([key]) => key)
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
return discriminator;
|
|
352
|
+
}
|
|
353
|
+
var getDataEnumEncoder = getDiscriminatedUnionEncoder;
|
|
354
|
+
var getDataEnumDecoder = getDiscriminatedUnionDecoder;
|
|
355
|
+
var getDataEnumCodec = getDiscriminatedUnionCodec;
|
|
356
|
+
|
|
357
|
+
// src/enum-helpers.ts
|
|
358
|
+
function getEnumStats(constructor) {
|
|
359
|
+
const numericalValues = [
|
|
360
|
+
...new Set(Object.values(constructor).filter((v) => typeof v === "number"))
|
|
361
|
+
].sort();
|
|
362
|
+
const enumRecord = Object.fromEntries(Object.entries(constructor).slice(numericalValues.length));
|
|
363
|
+
const enumKeys = Object.keys(enumRecord);
|
|
364
|
+
const enumValues = Object.values(enumRecord);
|
|
365
|
+
const stringValues = [
|
|
366
|
+
.../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
|
|
367
|
+
];
|
|
368
|
+
return { enumKeys, enumRecord, enumValues, numericalValues, stringValues };
|
|
369
|
+
}
|
|
370
|
+
function getEnumIndexFromVariant({
|
|
371
|
+
enumKeys,
|
|
372
|
+
enumValues,
|
|
373
|
+
variant
|
|
374
|
+
}) {
|
|
375
|
+
const valueIndex = findLastIndex(enumValues, (value) => value === variant);
|
|
376
|
+
if (valueIndex >= 0) return valueIndex;
|
|
377
|
+
return enumKeys.findIndex((key) => key === variant);
|
|
378
|
+
}
|
|
379
|
+
function getEnumIndexFromDiscriminator({
|
|
380
|
+
discriminator,
|
|
381
|
+
enumKeys,
|
|
382
|
+
enumValues,
|
|
383
|
+
useValuesAsDiscriminators
|
|
384
|
+
}) {
|
|
385
|
+
if (!useValuesAsDiscriminators) {
|
|
386
|
+
return discriminator >= 0 && discriminator < enumKeys.length ? discriminator : -1;
|
|
387
|
+
}
|
|
388
|
+
return findLastIndex(enumValues, (value) => value === discriminator);
|
|
389
|
+
}
|
|
390
|
+
function findLastIndex(array, predicate) {
|
|
391
|
+
let l = array.length;
|
|
392
|
+
while (l--) {
|
|
393
|
+
if (predicate(array[l], l, array)) return l;
|
|
394
|
+
}
|
|
395
|
+
return -1;
|
|
396
|
+
}
|
|
397
|
+
function formatNumericalValues(values) {
|
|
398
|
+
if (values.length === 0) return "";
|
|
399
|
+
let range = [values[0], values[0]];
|
|
400
|
+
const ranges = [];
|
|
401
|
+
for (let index = 1; index < values.length; index++) {
|
|
402
|
+
const value = values[index];
|
|
403
|
+
if (range[1] + 1 === value) {
|
|
404
|
+
range[1] = value;
|
|
405
|
+
} else {
|
|
406
|
+
ranges.push(range[0] === range[1] ? `${range[0]}` : `${range[0]}-${range[1]}`);
|
|
407
|
+
range = [value, value];
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
ranges.push(range[0] === range[1] ? `${range[0]}` : `${range[0]}-${range[1]}`);
|
|
411
|
+
return ranges.join(", ");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/enum.ts
|
|
415
|
+
function getEnumEncoder(constructor, config = {}) {
|
|
416
|
+
const prefix = config.size ?? getU8Encoder();
|
|
417
|
+
const useValuesAsDiscriminators = config.useValuesAsDiscriminators ?? false;
|
|
418
|
+
const { enumKeys, enumValues, numericalValues, stringValues } = getEnumStats(constructor);
|
|
419
|
+
if (useValuesAsDiscriminators && enumValues.some((value) => typeof value === "string")) {
|
|
420
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, {
|
|
421
|
+
stringValues: enumValues.filter((v) => typeof v === "string")
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return transformEncoder(prefix, (variant) => {
|
|
425
|
+
const index = getEnumIndexFromVariant({ enumKeys, enumValues, variant });
|
|
426
|
+
if (index < 0) {
|
|
427
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {
|
|
428
|
+
formattedNumericalValues: formatNumericalValues(numericalValues),
|
|
429
|
+
numericalValues,
|
|
430
|
+
stringValues,
|
|
431
|
+
variant
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return useValuesAsDiscriminators ? enumValues[index] : index;
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
function getEnumDecoder(constructor, config = {}) {
|
|
438
|
+
const prefix = config.size ?? getU8Decoder();
|
|
439
|
+
const useValuesAsDiscriminators = config.useValuesAsDiscriminators ?? false;
|
|
440
|
+
const { enumKeys, enumValues, numericalValues } = getEnumStats(constructor);
|
|
441
|
+
if (useValuesAsDiscriminators && enumValues.some((value) => typeof value === "string")) {
|
|
442
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, {
|
|
443
|
+
stringValues: enumValues.filter((v) => typeof v === "string")
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
return transformDecoder(prefix, (value) => {
|
|
447
|
+
const discriminator = Number(value);
|
|
448
|
+
const index = getEnumIndexFromDiscriminator({
|
|
449
|
+
discriminator,
|
|
450
|
+
enumKeys,
|
|
451
|
+
enumValues,
|
|
452
|
+
useValuesAsDiscriminators
|
|
453
|
+
});
|
|
454
|
+
if (index < 0) {
|
|
455
|
+
const validDiscriminators = useValuesAsDiscriminators ? numericalValues : [...Array(enumKeys.length).keys()];
|
|
456
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
457
|
+
discriminator,
|
|
458
|
+
formattedValidDiscriminators: formatNumericalValues(validDiscriminators),
|
|
459
|
+
validDiscriminators
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
return enumValues[index];
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
function getEnumCodec(constructor, config = {}) {
|
|
466
|
+
return combineCodec(getEnumEncoder(constructor, config), getEnumDecoder(constructor, config));
|
|
467
|
+
}
|
|
468
|
+
var getScalarEnumEncoder = getEnumEncoder;
|
|
469
|
+
var getScalarEnumDecoder = getEnumDecoder;
|
|
470
|
+
var getScalarEnumCodec = getEnumCodec;
|
|
471
|
+
function getHiddenPrefixEncoder(encoder, prefixedEncoders) {
|
|
472
|
+
return transformEncoder(
|
|
473
|
+
getTupleEncoder([...prefixedEncoders, encoder]),
|
|
474
|
+
(value) => [...prefixedEncoders.map(() => void 0), value]
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
function getHiddenPrefixDecoder(decoder, prefixedDecoders) {
|
|
478
|
+
return transformDecoder(
|
|
479
|
+
getTupleDecoder([...prefixedDecoders, decoder]),
|
|
480
|
+
(tuple) => tuple[tuple.length - 1]
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
function getHiddenPrefixCodec(codec, prefixedCodecs) {
|
|
484
|
+
return combineCodec(getHiddenPrefixEncoder(codec, prefixedCodecs), getHiddenPrefixDecoder(codec, prefixedCodecs));
|
|
485
|
+
}
|
|
486
|
+
function getHiddenSuffixEncoder(encoder, suffixedEncoders) {
|
|
487
|
+
return transformEncoder(
|
|
488
|
+
getTupleEncoder([encoder, ...suffixedEncoders]),
|
|
489
|
+
(value) => [value, ...suffixedEncoders.map(() => void 0)]
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
function getHiddenSuffixDecoder(decoder, suffixedDecoders) {
|
|
493
|
+
return transformDecoder(
|
|
494
|
+
getTupleDecoder([decoder, ...suffixedDecoders]),
|
|
495
|
+
(tuple) => tuple[0]
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
function getHiddenSuffixCodec(codec, suffixedCodecs) {
|
|
499
|
+
return combineCodec(getHiddenSuffixEncoder(codec, suffixedCodecs), getHiddenSuffixDecoder(codec, suffixedCodecs));
|
|
500
|
+
}
|
|
501
|
+
function getMapEncoder(key, value, config = {}) {
|
|
502
|
+
return transformEncoder(
|
|
503
|
+
getArrayEncoder(getTupleEncoder([key, value]), config),
|
|
504
|
+
(map) => [...map.entries()]
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
function getMapDecoder(key, value, config = {}) {
|
|
508
|
+
return transformDecoder(
|
|
509
|
+
getArrayDecoder(getTupleDecoder([key, value]), config),
|
|
510
|
+
(entries) => new Map(entries)
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
function getMapCodec(key, value, config = {}) {
|
|
514
|
+
return combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
|
|
515
|
+
}
|
|
516
|
+
function getUnitEncoder() {
|
|
517
|
+
return createEncoder({
|
|
518
|
+
fixedSize: 0,
|
|
519
|
+
write: (_value, _bytes, offset) => offset
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
function getUnitDecoder() {
|
|
523
|
+
return createDecoder({
|
|
524
|
+
fixedSize: 0,
|
|
525
|
+
read: (_bytes, offset) => [void 0, offset]
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
function getUnitCodec() {
|
|
529
|
+
return combineCodec(getUnitEncoder(), getUnitDecoder());
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/nullable.ts
|
|
533
|
+
function getNullableEncoder(item, config = {}) {
|
|
534
|
+
const prefix = (() => {
|
|
535
|
+
if (config.prefix === null) {
|
|
536
|
+
return transformEncoder(getUnitEncoder(), (_boolean) => void 0);
|
|
537
|
+
}
|
|
538
|
+
return getBooleanEncoder({ size: config.prefix ?? getU8Encoder() });
|
|
539
|
+
})();
|
|
540
|
+
const noneValue = (() => {
|
|
541
|
+
if (config.noneValue === "zeroes") {
|
|
542
|
+
assertIsFixedSize(item);
|
|
543
|
+
return fixEncoderSize(getUnitEncoder(), item.fixedSize);
|
|
544
|
+
}
|
|
545
|
+
if (!config.noneValue) {
|
|
546
|
+
return getUnitEncoder();
|
|
547
|
+
}
|
|
548
|
+
return getConstantEncoder(config.noneValue);
|
|
549
|
+
})();
|
|
550
|
+
return getUnionEncoder(
|
|
551
|
+
[
|
|
552
|
+
transformEncoder(getTupleEncoder([prefix, noneValue]), (_value) => [
|
|
553
|
+
false,
|
|
554
|
+
void 0
|
|
555
|
+
]),
|
|
556
|
+
transformEncoder(getTupleEncoder([prefix, item]), (value) => [true, value])
|
|
557
|
+
],
|
|
558
|
+
(variant) => Number(variant !== null)
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
function getNullableDecoder(item, config = {}) {
|
|
562
|
+
const prefix = (() => {
|
|
563
|
+
if (config.prefix === null) {
|
|
564
|
+
return transformDecoder(getUnitDecoder(), () => false);
|
|
565
|
+
}
|
|
566
|
+
return getBooleanDecoder({ size: config.prefix ?? getU8Decoder() });
|
|
567
|
+
})();
|
|
568
|
+
const noneValue = (() => {
|
|
569
|
+
if (config.noneValue === "zeroes") {
|
|
570
|
+
assertIsFixedSize(item);
|
|
571
|
+
return fixDecoderSize(getUnitDecoder(), item.fixedSize);
|
|
572
|
+
}
|
|
573
|
+
if (!config.noneValue) {
|
|
574
|
+
return getUnitDecoder();
|
|
575
|
+
}
|
|
576
|
+
return getConstantDecoder(config.noneValue);
|
|
577
|
+
})();
|
|
578
|
+
return getUnionDecoder(
|
|
579
|
+
[
|
|
580
|
+
transformDecoder(getTupleDecoder([prefix, noneValue]), () => null),
|
|
581
|
+
transformDecoder(getTupleDecoder([prefix, item]), ([, value]) => value)
|
|
582
|
+
],
|
|
583
|
+
(bytes, offset) => {
|
|
584
|
+
if (config.prefix === null && !config.noneValue) {
|
|
585
|
+
return Number(offset < bytes.length);
|
|
586
|
+
}
|
|
587
|
+
if (config.prefix === null && config.noneValue != null) {
|
|
588
|
+
const zeroValue = config.noneValue === "zeroes" ? new Uint8Array(noneValue.fixedSize).fill(0) : config.noneValue;
|
|
589
|
+
return containsBytes(bytes, zeroValue, offset) ? 0 : 1;
|
|
590
|
+
}
|
|
591
|
+
return Number(prefix.read(bytes, offset)[0]);
|
|
592
|
+
}
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
function getNullableCodec(item, config = {}) {
|
|
596
|
+
return combineCodec(
|
|
597
|
+
getNullableEncoder(item, config),
|
|
598
|
+
getNullableDecoder(item, config)
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
function getSetEncoder(item, config = {}) {
|
|
602
|
+
return transformEncoder(getArrayEncoder(item, config), (set) => [...set]);
|
|
603
|
+
}
|
|
604
|
+
function getSetDecoder(item, config = {}) {
|
|
605
|
+
return transformDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
|
|
606
|
+
}
|
|
607
|
+
function getSetCodec(item, config = {}) {
|
|
608
|
+
return combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
|
|
609
|
+
}
|
|
610
|
+
function getStructEncoder(fields) {
|
|
611
|
+
const fieldCodecs = fields.map(([, codec]) => codec);
|
|
612
|
+
const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
|
|
613
|
+
const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
|
|
614
|
+
return createEncoder({
|
|
615
|
+
...fixedSize === null ? {
|
|
616
|
+
getSizeFromValue: (value) => fields.map(([key, codec]) => getEncodedSize(value[key], codec)).reduce((all, one) => all + one, 0),
|
|
617
|
+
maxSize
|
|
618
|
+
} : { fixedSize },
|
|
619
|
+
write: (struct, bytes, offset) => {
|
|
620
|
+
fields.forEach(([key, codec]) => {
|
|
621
|
+
offset = codec.write(struct[key], bytes, offset);
|
|
622
|
+
});
|
|
623
|
+
return offset;
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
function getStructDecoder(fields) {
|
|
628
|
+
const fieldCodecs = fields.map(([, codec]) => codec);
|
|
629
|
+
const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
|
|
630
|
+
const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
|
|
631
|
+
return createDecoder({
|
|
632
|
+
...fixedSize === null ? { maxSize } : { fixedSize },
|
|
633
|
+
read: (bytes, offset) => {
|
|
634
|
+
const struct = {};
|
|
635
|
+
fields.forEach(([key, codec]) => {
|
|
636
|
+
const [value, newOffset] = codec.read(bytes, offset);
|
|
637
|
+
offset = newOffset;
|
|
638
|
+
struct[key] = value;
|
|
639
|
+
});
|
|
640
|
+
return [struct, offset];
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
function getStructCodec(fields) {
|
|
645
|
+
return combineCodec(
|
|
646
|
+
getStructEncoder(fields),
|
|
647
|
+
getStructDecoder(fields)
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export { assertValidNumberOfItemsForCodec, getArrayCodec, getArrayDecoder, getArrayEncoder, getBitArrayCodec, getBitArrayDecoder, getBitArrayEncoder, getBooleanCodec, getBooleanDecoder, getBooleanEncoder, getBytesCodec, getBytesDecoder, getBytesEncoder, getConstantCodec, getConstantDecoder, getConstantEncoder, getDataEnumCodec, getDataEnumDecoder, getDataEnumEncoder, getDiscriminatedUnionCodec, getDiscriminatedUnionDecoder, getDiscriminatedUnionEncoder, getEnumCodec, getEnumDecoder, getEnumEncoder, getHiddenPrefixCodec, getHiddenPrefixDecoder, getHiddenPrefixEncoder, getHiddenSuffixCodec, getHiddenSuffixDecoder, getHiddenSuffixEncoder, getMapCodec, getMapDecoder, getMapEncoder, getNullableCodec, getNullableDecoder, getNullableEncoder, getScalarEnumCodec, getScalarEnumDecoder, getScalarEnumEncoder, getSetCodec, getSetDecoder, getSetEncoder, getStructCodec, getStructDecoder, getStructEncoder, getTupleCodec, getTupleDecoder, getTupleEncoder, getUnionCodec, getUnionDecoder, getUnionEncoder, getUnitCodec, getUnitDecoder, getUnitEncoder };
|
|
652
|
+
//# sourceMappingURL=index.native.mjs.map
|
|
653
|
+
//# sourceMappingURL=index.native.mjs.map
|