@solana/codecs-data-structures 2.0.0-experimental.7ed772d → 2.0.0-experimental.803b2d8
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 +117 -63
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +118 -64
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +118 -64
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +117 -63
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +118 -64
- package/dist/index.node.js.map +1 -1
- package/dist/types/array.d.ts +3 -18
- package/dist/types/array.d.ts.map +1 -1
- package/dist/types/assertions.d.ts.map +1 -1
- package/dist/types/boolean.d.ts.map +1 -1
- package/dist/types/data-enum.d.ts +16 -18
- package/dist/types/data-enum.d.ts.map +1 -1
- package/dist/types/index.d.ts +13 -13
- package/dist/types/map.d.ts +4 -19
- package/dist/types/map.d.ts.map +1 -1
- package/dist/types/nullable.d.ts.map +1 -1
- package/dist/types/scalar-enum.d.ts +36 -17
- package/dist/types/scalar-enum.d.ts.map +1 -1
- package/dist/types/set.d.ts +4 -19
- package/dist/types/set.d.ts.map +1 -1
- package/dist/types/struct.d.ts +15 -30
- package/dist/types/struct.d.ts.map +1 -1
- package/package.json +13 -34
- package/dist/index.development.js +0 -800
- package/dist/index.development.js.map +0 -1
- package/dist/index.production.min.js +0 -47
package/dist/index.browser.cjs
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
var codecsCore = require('@solana/codecs-core');
|
|
4
4
|
var codecsNumbers = require('@solana/codecs-numbers');
|
|
5
|
+
var errors = require('@solana/errors');
|
|
5
6
|
|
|
6
7
|
// src/array.ts
|
|
7
|
-
|
|
8
|
-
// src/assertions.ts
|
|
9
8
|
function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
|
|
10
9
|
if (expected !== actual) {
|
|
11
|
-
throw new
|
|
10
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_ITEMS, {
|
|
11
|
+
actual,
|
|
12
|
+
codecDescription,
|
|
13
|
+
expected
|
|
14
|
+
});
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
function maxCodecSizes(sizes) {
|
|
@@ -30,9 +33,6 @@ function getMaxSize(codec) {
|
|
|
30
33
|
// src/array.ts
|
|
31
34
|
function getArrayEncoder(item, config = {}) {
|
|
32
35
|
const size = config.size ?? codecsNumbers.getU32Encoder();
|
|
33
|
-
if (size === "remainder") {
|
|
34
|
-
codecsCore.assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
|
|
35
|
-
}
|
|
36
36
|
const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));
|
|
37
37
|
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
38
38
|
return codecsCore.createEncoder({
|
|
@@ -59,9 +59,6 @@ function getArrayEncoder(item, config = {}) {
|
|
|
59
59
|
}
|
|
60
60
|
function getArrayDecoder(item, config = {}) {
|
|
61
61
|
const size = config.size ?? codecsNumbers.getU32Decoder();
|
|
62
|
-
if (size === "remainder") {
|
|
63
|
-
codecsCore.assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
|
|
64
|
-
}
|
|
65
62
|
const itemSize = getFixedSize(item);
|
|
66
63
|
const fixedSize = computeArrayLikeCodecSize(size, itemSize);
|
|
67
64
|
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
@@ -72,7 +69,15 @@ function getArrayDecoder(item, config = {}) {
|
|
|
72
69
|
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
73
70
|
return [array, offset];
|
|
74
71
|
}
|
|
75
|
-
|
|
72
|
+
if (size === "remainder") {
|
|
73
|
+
while (offset < bytes.length) {
|
|
74
|
+
const [value, newOffset2] = item.read(bytes, offset);
|
|
75
|
+
offset = newOffset2;
|
|
76
|
+
array.push(value);
|
|
77
|
+
}
|
|
78
|
+
return [array, offset];
|
|
79
|
+
}
|
|
80
|
+
const [resolvedSize, newOffset] = typeof size === "number" ? [size, offset] : size.read(bytes, offset);
|
|
76
81
|
offset = newOffset;
|
|
77
82
|
for (let i = 0; i < resolvedSize; i += 1) {
|
|
78
83
|
const [value, newOffset2] = item.read(bytes, offset);
|
|
@@ -86,27 +91,6 @@ function getArrayDecoder(item, config = {}) {
|
|
|
86
91
|
function getArrayCodec(item, config = {}) {
|
|
87
92
|
return codecsCore.combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
|
|
88
93
|
}
|
|
89
|
-
function readArrayLikeCodecSize(size, itemSize, bytes, offset) {
|
|
90
|
-
if (typeof size === "number") {
|
|
91
|
-
return [size, offset];
|
|
92
|
-
}
|
|
93
|
-
if (typeof size === "object") {
|
|
94
|
-
return size.read(bytes, offset);
|
|
95
|
-
}
|
|
96
|
-
if (size === "remainder") {
|
|
97
|
-
if (itemSize === null) {
|
|
98
|
-
throw new Error('Codecs of "remainder" size must have fixed-size items.');
|
|
99
|
-
}
|
|
100
|
-
const remainder = Math.max(0, bytes.length - offset);
|
|
101
|
-
if (remainder % itemSize !== 0) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
`The remainder of the byte array (${remainder} bytes) cannot be split into chunks of ${itemSize} bytes. Codecs of "remainder" size must have a remainder that is a multiple of its item size. In other words, ${remainder} modulo ${itemSize} should be equal to zero.`
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
return [remainder / itemSize, offset];
|
|
107
|
-
}
|
|
108
|
-
throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
|
|
109
|
-
}
|
|
110
94
|
function computeArrayLikeCodecSize(size, itemSize) {
|
|
111
95
|
if (typeof size !== "number")
|
|
112
96
|
return null;
|
|
@@ -168,12 +152,32 @@ function getBitArrayCodec(size, config = {}) {
|
|
|
168
152
|
}
|
|
169
153
|
function getBooleanEncoder(config = {}) {
|
|
170
154
|
const size = config.size ?? codecsNumbers.getU8Encoder();
|
|
171
|
-
|
|
155
|
+
try {
|
|
156
|
+
codecsCore.assertIsFixedSize(size);
|
|
157
|
+
} catch (e) {
|
|
158
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
159
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
|
|
160
|
+
codecDescription: "bool"
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
throw e;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
172
166
|
return codecsCore.mapEncoder(size, (value) => value ? 1 : 0);
|
|
173
167
|
}
|
|
174
168
|
function getBooleanDecoder(config = {}) {
|
|
175
169
|
const size = config.size ?? codecsNumbers.getU8Decoder();
|
|
176
|
-
|
|
170
|
+
try {
|
|
171
|
+
codecsCore.assertIsFixedSize(size);
|
|
172
|
+
} catch (e) {
|
|
173
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
174
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
|
|
175
|
+
codecDescription: "bool"
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
throw e;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
177
181
|
return codecsCore.mapDecoder(size, (value) => Number(value) === 1);
|
|
178
182
|
}
|
|
179
183
|
function getBooleanCodec(config = {}) {
|
|
@@ -264,9 +268,11 @@ function getDataEnumDecoder(variants, config = {}) {
|
|
|
264
268
|
offset = dOffset;
|
|
265
269
|
const variantField = variants[Number(discriminator)] ?? null;
|
|
266
270
|
if (!variantField) {
|
|
267
|
-
throw new
|
|
268
|
-
|
|
269
|
-
|
|
271
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
272
|
+
discriminator,
|
|
273
|
+
maxRange: variants.length - 1,
|
|
274
|
+
minRange: 0
|
|
275
|
+
});
|
|
270
276
|
}
|
|
271
277
|
const [variant, vOffset] = variantField[1].read(bytes, offset);
|
|
272
278
|
offset = vOffset;
|
|
@@ -275,7 +281,10 @@ function getDataEnumDecoder(variants, config = {}) {
|
|
|
275
281
|
});
|
|
276
282
|
}
|
|
277
283
|
function getDataEnumCodec(variants, config = {}) {
|
|
278
|
-
return codecsCore.combineCodec(
|
|
284
|
+
return codecsCore.combineCodec(
|
|
285
|
+
getDataEnumEncoder(variants, config),
|
|
286
|
+
getDataEnumDecoder(variants, config)
|
|
287
|
+
);
|
|
279
288
|
}
|
|
280
289
|
function getDataEnumFixedSize(variants, prefix) {
|
|
281
290
|
if (variants.length === 0)
|
|
@@ -297,9 +306,10 @@ function getDataEnumMaxSize(variants, prefix) {
|
|
|
297
306
|
function getVariantDiscriminator(variants, variant) {
|
|
298
307
|
const discriminator = variants.findIndex(([key]) => variant.__kind === key);
|
|
299
308
|
if (discriminator < 0) {
|
|
300
|
-
throw new
|
|
301
|
-
|
|
302
|
-
|
|
309
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_DATA_ENUM_VARIANT, {
|
|
310
|
+
value: variant.__kind,
|
|
311
|
+
variants: variants.map(([key]) => key)
|
|
312
|
+
});
|
|
303
313
|
}
|
|
304
314
|
return discriminator;
|
|
305
315
|
}
|
|
@@ -364,8 +374,24 @@ function getNullableEncoder(item, config = {}) {
|
|
|
364
374
|
const fixed = config.fixed ?? false;
|
|
365
375
|
const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
|
|
366
376
|
if (fixed || isZeroSizeItem) {
|
|
367
|
-
|
|
368
|
-
|
|
377
|
+
try {
|
|
378
|
+
codecsCore.assertIsFixedSize(item);
|
|
379
|
+
} catch (e) {
|
|
380
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
381
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
|
|
382
|
+
} else {
|
|
383
|
+
throw e;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
try {
|
|
387
|
+
codecsCore.assertIsFixedSize(prefix);
|
|
388
|
+
} catch (e) {
|
|
389
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
390
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
|
|
391
|
+
} else {
|
|
392
|
+
throw e;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
369
395
|
const fixedSize = prefix.fixedSize + item.fixedSize;
|
|
370
396
|
return codecsCore.createEncoder({
|
|
371
397
|
fixedSize,
|
|
@@ -396,8 +422,24 @@ function getNullableDecoder(item, config = {}) {
|
|
|
396
422
|
let fixedSize = null;
|
|
397
423
|
const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
|
|
398
424
|
if (fixed || isZeroSizeItem) {
|
|
399
|
-
|
|
400
|
-
|
|
425
|
+
try {
|
|
426
|
+
codecsCore.assertIsFixedSize(item);
|
|
427
|
+
} catch (e) {
|
|
428
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
429
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
|
|
430
|
+
} else {
|
|
431
|
+
throw e;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
codecsCore.assertIsFixedSize(prefix);
|
|
436
|
+
} catch (e) {
|
|
437
|
+
if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
|
|
438
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
|
|
439
|
+
} else {
|
|
440
|
+
throw e;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
401
443
|
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
402
444
|
}
|
|
403
445
|
return codecsCore.createDecoder({
|
|
@@ -421,14 +463,17 @@ function getNullableCodec(item, config = {}) {
|
|
|
421
463
|
}
|
|
422
464
|
function getScalarEnumEncoder(constructor, config = {}) {
|
|
423
465
|
const prefix = config.size ?? codecsNumbers.getU8Encoder();
|
|
424
|
-
const { minRange, maxRange,
|
|
466
|
+
const { minRange, maxRange, allStringInputs, enumKeys, enumValues } = getScalarEnumStats(constructor);
|
|
425
467
|
return codecsCore.mapEncoder(prefix, (value) => {
|
|
426
468
|
const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
|
|
427
|
-
const isInvalidString = typeof value === "string" && !
|
|
469
|
+
const isInvalidString = typeof value === "string" && !allStringInputs.includes(value);
|
|
428
470
|
if (isInvalidNumber || isInvalidString) {
|
|
429
|
-
throw new
|
|
430
|
-
|
|
431
|
-
|
|
471
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_SCALAR_ENUM_VARIANT, {
|
|
472
|
+
maxRange,
|
|
473
|
+
minRange,
|
|
474
|
+
value,
|
|
475
|
+
variants: allStringInputs
|
|
476
|
+
});
|
|
432
477
|
}
|
|
433
478
|
if (typeof value === "number")
|
|
434
479
|
return value;
|
|
@@ -440,34 +485,40 @@ function getScalarEnumEncoder(constructor, config = {}) {
|
|
|
440
485
|
}
|
|
441
486
|
function getScalarEnumDecoder(constructor, config = {}) {
|
|
442
487
|
const prefix = config.size ?? codecsNumbers.getU8Decoder();
|
|
443
|
-
const { minRange, maxRange,
|
|
488
|
+
const { minRange, maxRange, enumKeys } = getScalarEnumStats(constructor);
|
|
444
489
|
return codecsCore.mapDecoder(prefix, (value) => {
|
|
445
490
|
const valueAsNumber = Number(value);
|
|
446
491
|
if (valueAsNumber < minRange || valueAsNumber > maxRange) {
|
|
447
|
-
throw new
|
|
448
|
-
|
|
449
|
-
|
|
492
|
+
throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
493
|
+
discriminator: valueAsNumber,
|
|
494
|
+
maxRange,
|
|
495
|
+
minRange
|
|
496
|
+
});
|
|
450
497
|
}
|
|
451
|
-
return
|
|
498
|
+
return constructor[enumKeys[valueAsNumber]];
|
|
452
499
|
});
|
|
453
500
|
}
|
|
454
501
|
function getScalarEnumCodec(constructor, config = {}) {
|
|
455
502
|
return codecsCore.combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
|
|
456
503
|
}
|
|
457
504
|
function getScalarEnumStats(constructor) {
|
|
458
|
-
const
|
|
459
|
-
const
|
|
460
|
-
|
|
505
|
+
const numericValues = Object.values(constructor).filter((v) => typeof v === "number");
|
|
506
|
+
const deduplicatedConstructor = Object.fromEntries(
|
|
507
|
+
Object.entries(constructor).slice(numericValues.length)
|
|
508
|
+
);
|
|
509
|
+
const enumKeys = Object.keys(deduplicatedConstructor);
|
|
510
|
+
const enumValues = Object.values(deduplicatedConstructor);
|
|
461
511
|
const minRange = 0;
|
|
462
|
-
const maxRange =
|
|
463
|
-
const
|
|
512
|
+
const maxRange = enumValues.length - 1;
|
|
513
|
+
const allStringInputs = [
|
|
514
|
+
.../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
|
|
515
|
+
];
|
|
464
516
|
return {
|
|
517
|
+
allStringInputs,
|
|
465
518
|
enumKeys,
|
|
466
519
|
enumValues,
|
|
467
|
-
isNumericEnum,
|
|
468
520
|
maxRange,
|
|
469
|
-
minRange
|
|
470
|
-
stringValues
|
|
521
|
+
minRange
|
|
471
522
|
};
|
|
472
523
|
}
|
|
473
524
|
function getSetEncoder(item, config = {}) {
|
|
@@ -514,7 +565,10 @@ function getStructDecoder(fields) {
|
|
|
514
565
|
});
|
|
515
566
|
}
|
|
516
567
|
function getStructCodec(fields) {
|
|
517
|
-
return codecsCore.combineCodec(
|
|
568
|
+
return codecsCore.combineCodec(
|
|
569
|
+
getStructEncoder(fields),
|
|
570
|
+
getStructDecoder(fields)
|
|
571
|
+
);
|
|
518
572
|
}
|
|
519
573
|
function getUnitEncoder() {
|
|
520
574
|
return codecsCore.createEncoder({
|