@solana/codecs-data-structures 6.3.1 → 6.3.2-canary-20260313143218

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/src/boolean.ts ADDED
@@ -0,0 +1,163 @@
1
+ import {
2
+ Codec,
3
+ combineCodec,
4
+ Decoder,
5
+ Encoder,
6
+ FixedSizeCodec,
7
+ FixedSizeDecoder,
8
+ FixedSizeEncoder,
9
+ transformDecoder,
10
+ transformEncoder,
11
+ VariableSizeCodec,
12
+ VariableSizeDecoder,
13
+ VariableSizeEncoder,
14
+ } from '@solana/codecs-core';
15
+ import {
16
+ FixedSizeNumberCodec,
17
+ FixedSizeNumberDecoder,
18
+ FixedSizeNumberEncoder,
19
+ getU8Decoder,
20
+ getU8Encoder,
21
+ NumberCodec,
22
+ NumberDecoder,
23
+ NumberEncoder,
24
+ } from '@solana/codecs-numbers';
25
+
26
+ /**
27
+ * Defines the configuration options for boolean codecs.
28
+ *
29
+ * A boolean codec encodes `true` as `1` and `false` as `0`.
30
+ * The `size` option allows customizing the number codec used for storage.
31
+ *
32
+ * @typeParam TSize - A number codec, encoder, or decoder used for boolean representation.
33
+ *
34
+ * @see {@link getBooleanEncoder}
35
+ * @see {@link getBooleanDecoder}
36
+ * @see {@link getBooleanCodec}
37
+ */
38
+ export type BooleanCodecConfig<TSize extends NumberCodec | NumberDecoder | NumberEncoder> = {
39
+ /**
40
+ * The number codec used to store boolean values.
41
+ *
42
+ * - By default, booleans are stored as a `u8` (`1` for `true`, `0` for `false`).
43
+ * - A custom number codec can be provided to change the storage size.
44
+ *
45
+ * @defaultValue `u8`
46
+ */
47
+ size?: TSize;
48
+ };
49
+
50
+ /**
51
+ * Returns an encoder for boolean values.
52
+ *
53
+ * This encoder converts `true` into `1` and `false` into `0`.
54
+ * The `size` option allows customizing the number codec used for storage.
55
+ *
56
+ * For more details, see {@link getBooleanCodec}.
57
+ *
58
+ * @param config - Configuration options for encoding booleans.
59
+ * @returns A `FixedSizeEncoder<boolean, N>` where `N` is the size of the number codec.
60
+ *
61
+ * @example
62
+ * Encoding booleans.
63
+ * ```ts
64
+ * const encoder = getBooleanEncoder();
65
+ *
66
+ * encoder.encode(false); // 0x00
67
+ * encoder.encode(true); // 0x01
68
+ * ```
69
+ *
70
+ * @see {@link getBooleanCodec}
71
+ */
72
+ export function getBooleanEncoder(): FixedSizeEncoder<boolean, 1>;
73
+ export function getBooleanEncoder<TSize extends number>(
74
+ config: BooleanCodecConfig<NumberEncoder> & { size: FixedSizeNumberEncoder<TSize> },
75
+ ): FixedSizeEncoder<boolean, TSize>;
76
+ export function getBooleanEncoder(config: BooleanCodecConfig<NumberEncoder>): VariableSizeEncoder<boolean>;
77
+ export function getBooleanEncoder(config: BooleanCodecConfig<NumberEncoder> = {}): Encoder<boolean> {
78
+ return transformEncoder(config.size ?? getU8Encoder(), (value: boolean) => (value ? 1 : 0));
79
+ }
80
+
81
+ /**
82
+ * Returns a decoder for boolean values.
83
+ *
84
+ * This decoder reads a number and interprets `1` as `true` and `0` as `false`.
85
+ * The `size` option allows customizing the number codec used for storage.
86
+ *
87
+ * For more details, see {@link getBooleanCodec}.
88
+ *
89
+ * @param config - Configuration options for decoding booleans.
90
+ * @returns A `FixedSizeDecoder<boolean, N>` where `N` is the size of the number codec.
91
+ *
92
+ * @example
93
+ * Decoding booleans.
94
+ * ```ts
95
+ * const decoder = getBooleanDecoder();
96
+ *
97
+ * decoder.decode(new Uint8Array([0x00])); // false
98
+ * decoder.decode(new Uint8Array([0x01])); // true
99
+ * ```
100
+ *
101
+ * @see {@link getBooleanCodec}
102
+ */
103
+ export function getBooleanDecoder(): FixedSizeDecoder<boolean, 1>;
104
+ export function getBooleanDecoder<TSize extends number>(
105
+ config: BooleanCodecConfig<NumberDecoder> & { size: FixedSizeNumberDecoder<TSize> },
106
+ ): FixedSizeDecoder<boolean, TSize>;
107
+ export function getBooleanDecoder(config: BooleanCodecConfig<NumberDecoder>): VariableSizeDecoder<boolean>;
108
+ export function getBooleanDecoder(config: BooleanCodecConfig<NumberDecoder> = {}): Decoder<boolean> {
109
+ return transformDecoder(config.size ?? getU8Decoder(), (value: bigint | number): boolean => Number(value) === 1);
110
+ }
111
+
112
+ /**
113
+ * Returns a codec for encoding and decoding boolean values.
114
+ *
115
+ * By default, booleans are stored as a `u8` (`1` for `true`, `0` for `false`).
116
+ * The `size` option allows customizing the number codec used for storage.
117
+ *
118
+ * @param config - Configuration options for encoding and decoding booleans.
119
+ * @returns A `FixedSizeCodec<boolean, boolean, N>` where `N` is the size of the number codec.
120
+ *
121
+ * @example
122
+ * Encoding and decoding booleans using a `u8` (default).
123
+ * ```ts
124
+ * const codec = getBooleanCodec();
125
+ *
126
+ * codec.encode(false); // 0x00
127
+ * codec.encode(true); // 0x01
128
+ *
129
+ * codec.decode(new Uint8Array([0x00])); // false
130
+ * codec.decode(new Uint8Array([0x01])); // true
131
+ * ```
132
+ *
133
+ * @example
134
+ * Encoding and decoding booleans using a custom number codec.
135
+ * ```ts
136
+ * const codec = getBooleanCodec({ size: getU16Codec() });
137
+ *
138
+ * codec.encode(false); // 0x0000
139
+ * codec.encode(true); // 0x0100
140
+ *
141
+ * codec.decode(new Uint8Array([0x00, 0x00])); // false
142
+ * codec.decode(new Uint8Array([0x01, 0x00])); // true
143
+ * ```
144
+ *
145
+ * @remarks
146
+ * Separate {@link getBooleanEncoder} and {@link getBooleanDecoder} functions are available.
147
+ *
148
+ * ```ts
149
+ * const bytes = getBooleanEncoder().encode(true);
150
+ * const value = getBooleanDecoder().decode(bytes);
151
+ * ```
152
+ *
153
+ * @see {@link getBooleanEncoder}
154
+ * @see {@link getBooleanDecoder}
155
+ */
156
+ export function getBooleanCodec(): FixedSizeCodec<boolean, boolean, 1>;
157
+ export function getBooleanCodec<TSize extends number>(
158
+ config: BooleanCodecConfig<NumberCodec> & { size: FixedSizeNumberCodec<TSize> },
159
+ ): FixedSizeCodec<boolean, boolean, TSize>;
160
+ export function getBooleanCodec(config: BooleanCodecConfig<NumberCodec>): VariableSizeCodec<boolean>;
161
+ export function getBooleanCodec(config: BooleanCodecConfig<NumberCodec> = {}): Codec<boolean> {
162
+ return combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
163
+ }
package/src/bytes.ts ADDED
@@ -0,0 +1,115 @@
1
+ import {
2
+ combineCodec,
3
+ createDecoder,
4
+ createEncoder,
5
+ ReadonlyUint8Array,
6
+ VariableSizeCodec,
7
+ VariableSizeDecoder,
8
+ VariableSizeEncoder,
9
+ } from '@solana/codecs-core';
10
+
11
+ /**
12
+ * Returns an encoder for raw byte arrays.
13
+ *
14
+ * This encoder writes byte arrays exactly as provided without modification.
15
+ *
16
+ * The size of the encoded byte array is determined by the length of the input.
17
+ * - To enforce a fixed size, consider using {@link fixEncoderSize}.
18
+ * - To add a size prefix, use {@link addEncoderSizePrefix}.
19
+ * - To add a sentinel value, use {@link addEncoderSentinel}.
20
+ *
21
+ * For more details, see {@link getBytesCodec}.
22
+ *
23
+ * @returns A `VariableSizeEncoder<ReadonlyUint8Array | Uint8Array>`.
24
+ *
25
+ * @example
26
+ * Encoding a byte array as-is.
27
+ * ```ts
28
+ * const encoder = getBytesEncoder();
29
+ *
30
+ * encoder.encode(new Uint8Array([1, 2, 3])); // 0x010203
31
+ * encoder.encode(new Uint8Array([255, 0, 127])); // 0xff007f
32
+ * ```
33
+ *
34
+ * @see {@link getBytesCodec}
35
+ */
36
+ export function getBytesEncoder(): VariableSizeEncoder<ReadonlyUint8Array | Uint8Array> {
37
+ return createEncoder({
38
+ getSizeFromValue: value => value.length,
39
+ write: (value, bytes, offset) => {
40
+ bytes.set(value, offset);
41
+ return offset + value.length;
42
+ },
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Returns a decoder for raw byte arrays.
48
+ *
49
+ * This decoder reads byte arrays exactly as provided without modification.
50
+ *
51
+ * The decoded byte array extends from the provided offset to the end of the input.
52
+ * - To enforce a fixed size, consider using {@link fixDecoderSize}.
53
+ * - To add a size prefix, use {@link addDecoderSizePrefix}.
54
+ * - To add a sentinel value, use {@link addDecoderSentinel}.
55
+ *
56
+ * For more details, see {@link getBytesCodec}.
57
+ *
58
+ * @returns A `VariableSizeDecoder<ReadonlyUint8Array>`.
59
+ *
60
+ * @example
61
+ * Decoding a byte array as-is.
62
+ * ```ts
63
+ * const decoder = getBytesDecoder();
64
+ *
65
+ * decoder.decode(new Uint8Array([1, 2, 3])); // Uint8Array([1, 2, 3])
66
+ * decoder.decode(new Uint8Array([255, 0, 127])); // Uint8Array([255, 0, 127])
67
+ * ```
68
+ *
69
+ * @see {@link getBytesCodec}
70
+ */
71
+ export function getBytesDecoder(): VariableSizeDecoder<ReadonlyUint8Array> {
72
+ return createDecoder({
73
+ read: (bytes, offset) => {
74
+ const slice = bytes.slice(offset);
75
+ return [slice, offset + slice.length];
76
+ },
77
+ });
78
+ }
79
+
80
+ /**
81
+ * Returns a codec for encoding and decoding raw byte arrays.
82
+ *
83
+ * This codec serializes and deserializes byte arrays without modification.
84
+ *
85
+ * The size of the encoded and decoded byte array is determined dynamically.
86
+ * This means, when reading, the codec will consume all remaining bytes in the input.
87
+ * - To enforce a fixed size, consider using {@link fixCodecSize}.
88
+ * - To add a size prefix, use {@link addCodecSizePrefix}.
89
+ * - To add a sentinel value, use {@link addCodecSentinel}.
90
+ *
91
+ * @returns A `VariableSizeCodec<ReadonlyUint8Array | Uint8Array, ReadonlyUint8Array>`.
92
+ *
93
+ * @example
94
+ * Encoding and decoding a byte array.
95
+ * ```ts
96
+ * const codec = getBytesCodec();
97
+ *
98
+ * codec.encode(new Uint8Array([1, 2, 3])); // 0x010203
99
+ * codec.decode(new Uint8Array([255, 0, 127])); // Uint8Array([255, 0, 127])
100
+ * ```
101
+ *
102
+ * @remarks
103
+ * Separate {@link getBytesEncoder} and {@link getBytesDecoder} functions are available.
104
+ *
105
+ * ```ts
106
+ * const bytes = getBytesEncoder().encode(new Uint8Array([1, 2, 3]));
107
+ * const value = getBytesDecoder().decode(bytes);
108
+ * ```
109
+ *
110
+ * @see {@link getBytesEncoder}
111
+ * @see {@link getBytesDecoder}
112
+ */
113
+ export function getBytesCodec(): VariableSizeCodec<ReadonlyUint8Array | Uint8Array, ReadonlyUint8Array> {
114
+ return combineCodec(getBytesEncoder(), getBytesDecoder());
115
+ }
@@ -0,0 +1,135 @@
1
+ import {
2
+ combineCodec,
3
+ containsBytes,
4
+ createDecoder,
5
+ createEncoder,
6
+ FixedSizeCodec,
7
+ FixedSizeDecoder,
8
+ FixedSizeEncoder,
9
+ ReadonlyUint8Array,
10
+ } from '@solana/codecs-core';
11
+ import { getBase16Decoder } from '@solana/codecs-strings';
12
+ import { SOLANA_ERROR__CODECS__INVALID_CONSTANT, SolanaError } from '@solana/errors';
13
+
14
+ /**
15
+ * Returns an encoder that always writes a predefined constant byte sequence.
16
+ *
17
+ * This encoder ensures that encoding always produces the specified byte array,
18
+ * ignoring any input values.
19
+ *
20
+ * For more details, see {@link getConstantCodec}.
21
+ *
22
+ * @typeParam TConstant - The fixed byte sequence that will be written during encoding.
23
+ *
24
+ * @param constant - The predefined byte array to encode.
25
+ * @returns A `FixedSizeEncoder<void, N>` where `N` is the length of the constant.
26
+ *
27
+ * @example
28
+ * Encoding a constant magic number.
29
+ * ```ts
30
+ * const encoder = getConstantEncoder(new Uint8Array([1, 2, 3, 4]));
31
+ *
32
+ * const bytes = encoder.encode();
33
+ * // 0x01020304
34
+ * // └──────┘ The predefined 4-byte constant.
35
+ * ```
36
+ *
37
+ * @see {@link getConstantCodec}
38
+ */
39
+ export function getConstantEncoder<TConstant extends ReadonlyUint8Array>(
40
+ constant: TConstant,
41
+ ): FixedSizeEncoder<void, TConstant['length']> {
42
+ return createEncoder({
43
+ fixedSize: constant.length,
44
+ write: (_, bytes, offset) => {
45
+ bytes.set(constant, offset);
46
+ return offset + constant.length;
47
+ },
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Returns a decoder that verifies a predefined constant byte sequence.
53
+ *
54
+ * This decoder reads the next bytes and checks that they match the provided constant.
55
+ * If the bytes differ, it throws an error.
56
+ *
57
+ * For more details, see {@link getConstantCodec}.
58
+ *
59
+ * @typeParam TConstant - The fixed byte sequence expected during decoding.
60
+ *
61
+ * @param constant - The predefined byte array to verify.
62
+ * @returns A `FixedSizeDecoder<void, N>` where `N` is the length of the constant.
63
+ *
64
+ * @example
65
+ * Decoding a constant magic number.
66
+ * ```ts
67
+ * const decoder = getConstantDecoder(new Uint8Array([1, 2, 3]));
68
+ *
69
+ * decoder.decode(new Uint8Array([1, 2, 3])); // Passes
70
+ * decoder.decode(new Uint8Array([1, 2, 4])); // Throws an error
71
+ * ```
72
+ *
73
+ * @see {@link getConstantCodec}
74
+ */
75
+ export function getConstantDecoder<TConstant extends ReadonlyUint8Array>(
76
+ constant: TConstant,
77
+ ): FixedSizeDecoder<void, TConstant['length']> {
78
+ return createDecoder({
79
+ fixedSize: constant.length,
80
+ read: (bytes, offset) => {
81
+ const base16 = getBase16Decoder();
82
+ if (!containsBytes(bytes, constant, offset)) {
83
+ throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {
84
+ constant,
85
+ data: bytes,
86
+ hexConstant: base16.decode(constant),
87
+ hexData: base16.decode(bytes),
88
+ offset,
89
+ });
90
+ }
91
+ return [undefined, offset + constant.length];
92
+ },
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Returns a codec that encodes and decodes a predefined constant byte sequence.
98
+ *
99
+ * - **Encoding:** Always writes the specified byte array.
100
+ * - **Decoding:** Asserts that the next bytes match the constant, throwing an error if they do not.
101
+ *
102
+ * This is useful for encoding fixed byte patterns required in a binary format or to use in
103
+ * conjunction with other codecs such as {@link getHiddenPrefixCodec} or {@link getHiddenSuffixCodec}.
104
+ *
105
+ * @typeParam TConstant - The fixed byte sequence to encode and verify during decoding.
106
+ *
107
+ * @param constant - The predefined byte array to encode and assert during decoding.
108
+ * @returns A `FixedSizeCodec<void, void, N>` where `N` is the length of the constant.
109
+ *
110
+ * @example
111
+ * Encoding and decoding a constant magic number.
112
+ * ```ts
113
+ * const codec = getConstantCodec(new Uint8Array([1, 2, 3]));
114
+ *
115
+ * codec.encode(); // 0x010203
116
+ * codec.decode(new Uint8Array([1, 2, 3])); // Passes
117
+ * codec.decode(new Uint8Array([1, 2, 4])); // Throws an error
118
+ * ```
119
+ *
120
+ * @remarks
121
+ * Separate {@link getConstantEncoder} and {@link getConstantDecoder} functions are available.
122
+ *
123
+ * ```ts
124
+ * const bytes = getConstantEncoder(new Uint8Array([1, 2, 3])).encode();
125
+ * getConstantDecoder(new Uint8Array([1, 2, 3])).decode(bytes);
126
+ * ```
127
+ *
128
+ * @see {@link getConstantEncoder}
129
+ * @see {@link getConstantDecoder}
130
+ */
131
+ export function getConstantCodec<TConstant extends ReadonlyUint8Array>(
132
+ constant: TConstant,
133
+ ): FixedSizeCodec<void, void, TConstant['length']> {
134
+ return combineCodec(getConstantEncoder(constant), getConstantDecoder(constant));
135
+ }