@solana/codecs-data-structures 2.0.0-experimental.3bc22e7 → 2.0.0-experimental.3fc662d
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 +65 -63
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +66 -64
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js +66 -64
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +65 -63
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +66 -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/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/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.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
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__INVALID_NUMBER_OF_ITEMS, SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, SOLANA_ERROR__CODECS__INVALID_DATA_ENUM_VARIANT, SOLANA_ERROR__CODECS__INVALID_SCALAR_ENUM_VARIANT } from '@solana/errors';
|
|
3
4
|
|
|
4
5
|
// src/array.ts
|
|
5
|
-
|
|
6
|
-
// src/assertions.ts
|
|
7
6
|
function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
|
|
8
7
|
if (expected !== actual) {
|
|
9
|
-
throw new
|
|
8
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {
|
|
9
|
+
actual,
|
|
10
|
+
codecDescription,
|
|
11
|
+
expected
|
|
12
|
+
});
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
function maxCodecSizes(sizes) {
|
|
@@ -28,9 +31,6 @@ function getMaxSize(codec) {
|
|
|
28
31
|
// src/array.ts
|
|
29
32
|
function getArrayEncoder(item, config = {}) {
|
|
30
33
|
const size = config.size ?? getU32Encoder();
|
|
31
|
-
if (size === "remainder") {
|
|
32
|
-
assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
|
|
33
|
-
}
|
|
34
34
|
const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));
|
|
35
35
|
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
36
36
|
return createEncoder({
|
|
@@ -57,9 +57,6 @@ function getArrayEncoder(item, config = {}) {
|
|
|
57
57
|
}
|
|
58
58
|
function getArrayDecoder(item, config = {}) {
|
|
59
59
|
const size = config.size ?? getU32Decoder();
|
|
60
|
-
if (size === "remainder") {
|
|
61
|
-
assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
|
|
62
|
-
}
|
|
63
60
|
const itemSize = getFixedSize(item);
|
|
64
61
|
const fixedSize = computeArrayLikeCodecSize(size, itemSize);
|
|
65
62
|
const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
|
|
@@ -70,7 +67,15 @@ function getArrayDecoder(item, config = {}) {
|
|
|
70
67
|
if (typeof size === "object" && bytes.slice(offset).length === 0) {
|
|
71
68
|
return [array, offset];
|
|
72
69
|
}
|
|
73
|
-
|
|
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);
|
|
74
79
|
offset = newOffset;
|
|
75
80
|
for (let i = 0; i < resolvedSize; i += 1) {
|
|
76
81
|
const [value, newOffset2] = item.read(bytes, offset);
|
|
@@ -84,27 +89,6 @@ function getArrayDecoder(item, config = {}) {
|
|
|
84
89
|
function getArrayCodec(item, config = {}) {
|
|
85
90
|
return combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
|
|
86
91
|
}
|
|
87
|
-
function readArrayLikeCodecSize(size, itemSize, bytes, offset) {
|
|
88
|
-
if (typeof size === "number") {
|
|
89
|
-
return [size, offset];
|
|
90
|
-
}
|
|
91
|
-
if (typeof size === "object") {
|
|
92
|
-
return size.read(bytes, offset);
|
|
93
|
-
}
|
|
94
|
-
if (size === "remainder") {
|
|
95
|
-
if (itemSize === null) {
|
|
96
|
-
throw new Error('Codecs of "remainder" size must have fixed-size items.');
|
|
97
|
-
}
|
|
98
|
-
const remainder = Math.max(0, bytes.length - offset);
|
|
99
|
-
if (remainder % itemSize !== 0) {
|
|
100
|
-
throw new Error(
|
|
101
|
-
`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.`
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
return [remainder / itemSize, offset];
|
|
105
|
-
}
|
|
106
|
-
throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
|
|
107
|
-
}
|
|
108
92
|
function computeArrayLikeCodecSize(size, itemSize) {
|
|
109
93
|
if (typeof size !== "number")
|
|
110
94
|
return null;
|
|
@@ -166,12 +150,12 @@ function getBitArrayCodec(size, config = {}) {
|
|
|
166
150
|
}
|
|
167
151
|
function getBooleanEncoder(config = {}) {
|
|
168
152
|
const size = config.size ?? getU8Encoder();
|
|
169
|
-
assertIsFixedSize(size
|
|
153
|
+
assertIsFixedSize(size);
|
|
170
154
|
return mapEncoder(size, (value) => value ? 1 : 0);
|
|
171
155
|
}
|
|
172
156
|
function getBooleanDecoder(config = {}) {
|
|
173
157
|
const size = config.size ?? getU8Decoder();
|
|
174
|
-
assertIsFixedSize(size
|
|
158
|
+
assertIsFixedSize(size);
|
|
175
159
|
return mapDecoder(size, (value) => Number(value) === 1);
|
|
176
160
|
}
|
|
177
161
|
function getBooleanCodec(config = {}) {
|
|
@@ -262,9 +246,11 @@ function getDataEnumDecoder(variants, config = {}) {
|
|
|
262
246
|
offset = dOffset;
|
|
263
247
|
const variantField = variants[Number(discriminator)] ?? null;
|
|
264
248
|
if (!variantField) {
|
|
265
|
-
throw new
|
|
266
|
-
|
|
267
|
-
|
|
249
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
250
|
+
discriminator,
|
|
251
|
+
maxRange: variants.length - 1,
|
|
252
|
+
minRange: 0
|
|
253
|
+
});
|
|
268
254
|
}
|
|
269
255
|
const [variant, vOffset] = variantField[1].read(bytes, offset);
|
|
270
256
|
offset = vOffset;
|
|
@@ -273,7 +259,10 @@ function getDataEnumDecoder(variants, config = {}) {
|
|
|
273
259
|
});
|
|
274
260
|
}
|
|
275
261
|
function getDataEnumCodec(variants, config = {}) {
|
|
276
|
-
return combineCodec(
|
|
262
|
+
return combineCodec(
|
|
263
|
+
getDataEnumEncoder(variants, config),
|
|
264
|
+
getDataEnumDecoder(variants, config)
|
|
265
|
+
);
|
|
277
266
|
}
|
|
278
267
|
function getDataEnumFixedSize(variants, prefix) {
|
|
279
268
|
if (variants.length === 0)
|
|
@@ -295,9 +284,10 @@ function getDataEnumMaxSize(variants, prefix) {
|
|
|
295
284
|
function getVariantDiscriminator(variants, variant) {
|
|
296
285
|
const discriminator = variants.findIndex(([key]) => variant.__kind === key);
|
|
297
286
|
if (discriminator < 0) {
|
|
298
|
-
throw new
|
|
299
|
-
|
|
300
|
-
|
|
287
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_DATA_ENUM_VARIANT, {
|
|
288
|
+
value: variant.__kind,
|
|
289
|
+
variants: variants.map(([key]) => key)
|
|
290
|
+
});
|
|
301
291
|
}
|
|
302
292
|
return discriminator;
|
|
303
293
|
}
|
|
@@ -362,8 +352,8 @@ function getNullableEncoder(item, config = {}) {
|
|
|
362
352
|
const fixed = config.fixed ?? false;
|
|
363
353
|
const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;
|
|
364
354
|
if (fixed || isZeroSizeItem) {
|
|
365
|
-
assertIsFixedSize(item
|
|
366
|
-
assertIsFixedSize(prefix
|
|
355
|
+
assertIsFixedSize(item);
|
|
356
|
+
assertIsFixedSize(prefix);
|
|
367
357
|
const fixedSize = prefix.fixedSize + item.fixedSize;
|
|
368
358
|
return createEncoder({
|
|
369
359
|
fixedSize,
|
|
@@ -394,8 +384,8 @@ function getNullableDecoder(item, config = {}) {
|
|
|
394
384
|
let fixedSize = null;
|
|
395
385
|
const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;
|
|
396
386
|
if (fixed || isZeroSizeItem) {
|
|
397
|
-
assertIsFixedSize(item
|
|
398
|
-
assertIsFixedSize(prefix
|
|
387
|
+
assertIsFixedSize(item);
|
|
388
|
+
assertIsFixedSize(prefix);
|
|
399
389
|
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
400
390
|
}
|
|
401
391
|
return createDecoder({
|
|
@@ -419,14 +409,17 @@ function getNullableCodec(item, config = {}) {
|
|
|
419
409
|
}
|
|
420
410
|
function getScalarEnumEncoder(constructor, config = {}) {
|
|
421
411
|
const prefix = config.size ?? getU8Encoder();
|
|
422
|
-
const { minRange, maxRange,
|
|
412
|
+
const { minRange, maxRange, allStringInputs, enumKeys, enumValues } = getScalarEnumStats(constructor);
|
|
423
413
|
return mapEncoder(prefix, (value) => {
|
|
424
414
|
const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
|
|
425
|
-
const isInvalidString = typeof value === "string" && !
|
|
415
|
+
const isInvalidString = typeof value === "string" && !allStringInputs.includes(value);
|
|
426
416
|
if (isInvalidNumber || isInvalidString) {
|
|
427
|
-
throw new
|
|
428
|
-
|
|
429
|
-
|
|
417
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_SCALAR_ENUM_VARIANT, {
|
|
418
|
+
maxRange,
|
|
419
|
+
minRange,
|
|
420
|
+
value,
|
|
421
|
+
variants: allStringInputs
|
|
422
|
+
});
|
|
430
423
|
}
|
|
431
424
|
if (typeof value === "number")
|
|
432
425
|
return value;
|
|
@@ -438,34 +431,40 @@ function getScalarEnumEncoder(constructor, config = {}) {
|
|
|
438
431
|
}
|
|
439
432
|
function getScalarEnumDecoder(constructor, config = {}) {
|
|
440
433
|
const prefix = config.size ?? getU8Decoder();
|
|
441
|
-
const { minRange, maxRange,
|
|
434
|
+
const { minRange, maxRange, enumKeys } = getScalarEnumStats(constructor);
|
|
442
435
|
return mapDecoder(prefix, (value) => {
|
|
443
436
|
const valueAsNumber = Number(value);
|
|
444
437
|
if (valueAsNumber < minRange || valueAsNumber > maxRange) {
|
|
445
|
-
throw new
|
|
446
|
-
|
|
447
|
-
|
|
438
|
+
throw new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
|
|
439
|
+
discriminator: valueAsNumber,
|
|
440
|
+
maxRange,
|
|
441
|
+
minRange
|
|
442
|
+
});
|
|
448
443
|
}
|
|
449
|
-
return
|
|
444
|
+
return constructor[enumKeys[valueAsNumber]];
|
|
450
445
|
});
|
|
451
446
|
}
|
|
452
447
|
function getScalarEnumCodec(constructor, config = {}) {
|
|
453
448
|
return combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
|
|
454
449
|
}
|
|
455
450
|
function getScalarEnumStats(constructor) {
|
|
456
|
-
const
|
|
457
|
-
const
|
|
458
|
-
|
|
451
|
+
const numericValues = Object.values(constructor).filter((v) => typeof v === "number");
|
|
452
|
+
const deduplicatedConstructor = Object.fromEntries(
|
|
453
|
+
Object.entries(constructor).slice(numericValues.length)
|
|
454
|
+
);
|
|
455
|
+
const enumKeys = Object.keys(deduplicatedConstructor);
|
|
456
|
+
const enumValues = Object.values(deduplicatedConstructor);
|
|
459
457
|
const minRange = 0;
|
|
460
|
-
const maxRange =
|
|
461
|
-
const
|
|
458
|
+
const maxRange = enumValues.length - 1;
|
|
459
|
+
const allStringInputs = [
|
|
460
|
+
.../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
|
|
461
|
+
];
|
|
462
462
|
return {
|
|
463
|
+
allStringInputs,
|
|
463
464
|
enumKeys,
|
|
464
465
|
enumValues,
|
|
465
|
-
isNumericEnum,
|
|
466
466
|
maxRange,
|
|
467
|
-
minRange
|
|
468
|
-
stringValues
|
|
467
|
+
minRange
|
|
469
468
|
};
|
|
470
469
|
}
|
|
471
470
|
function getSetEncoder(item, config = {}) {
|
|
@@ -512,7 +511,10 @@ function getStructDecoder(fields) {
|
|
|
512
511
|
});
|
|
513
512
|
}
|
|
514
513
|
function getStructCodec(fields) {
|
|
515
|
-
return combineCodec(
|
|
514
|
+
return combineCodec(
|
|
515
|
+
getStructEncoder(fields),
|
|
516
|
+
getStructDecoder(fields)
|
|
517
|
+
);
|
|
516
518
|
}
|
|
517
519
|
function getUnitEncoder() {
|
|
518
520
|
return createEncoder({
|