@solana/codecs-core 2.0.0-experimental.fb51adb → 2.0.0-experimental.fb655dd

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.
@@ -1,15 +1,23 @@
1
1
  'use strict';
2
2
 
3
+ var errors = require('@solana/errors');
4
+
3
5
  // src/assertions.ts
4
6
  function assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset = 0) {
5
7
  if (bytes.length - offset <= 0) {
6
- throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);
8
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY, {
9
+ codecDescription
10
+ });
7
11
  }
8
12
  }
9
13
  function assertByteArrayHasEnoughBytesForCodec(codecDescription, expected, bytes, offset = 0) {
10
14
  const bytesLength = bytes.length - offset;
11
15
  if (bytesLength < expected) {
12
- throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);
16
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES, {
17
+ bytesLength,
18
+ codecDescription,
19
+ expected
20
+ });
13
21
  }
14
22
  }
15
23
 
@@ -39,8 +47,6 @@ var padBytes = (bytes, length) => {
39
47
  return paddedBytes;
40
48
  };
41
49
  var fixBytes = (bytes, length) => padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);
42
-
43
- // src/codec.ts
44
50
  function getEncodedSize(value, encoder) {
45
51
  return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
46
52
  }
@@ -74,34 +80,34 @@ function createCodec(codec) {
74
80
  function isFixedSize(codec) {
75
81
  return "fixedSize" in codec && typeof codec.fixedSize === "number";
76
82
  }
77
- function assertIsFixedSize(codec, message) {
83
+ function assertIsFixedSize(codec) {
78
84
  if (!isFixedSize(codec)) {
79
- throw new Error(message ?? "Expected a fixed-size codec, got a variable-size one.");
85
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);
80
86
  }
81
87
  }
82
88
  function isVariableSize(codec) {
83
89
  return !isFixedSize(codec);
84
90
  }
85
- function assertIsVariableSize(codec, message) {
91
+ function assertIsVariableSize(codec) {
86
92
  if (!isVariableSize(codec)) {
87
- throw new Error(message ?? "Expected a variable-size codec, got a fixed-size one.");
93
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);
88
94
  }
89
95
  }
90
-
91
- // src/combine-codec.ts
92
96
  function combineCodec(encoder, decoder) {
93
97
  if (isFixedSize(encoder) !== isFixedSize(decoder)) {
94
- throw new Error(`Encoder and decoder must either both be fixed-size or variable-size.`);
98
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH);
95
99
  }
96
100
  if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {
97
- throw new Error(
98
- `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`
99
- );
101
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH, {
102
+ decoderFixedSize: decoder.fixedSize,
103
+ encoderFixedSize: encoder.fixedSize
104
+ });
100
105
  }
101
106
  if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {
102
- throw new Error(
103
- `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`
104
- );
107
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH, {
108
+ decoderMaxSize: decoder.maxSize,
109
+ encoderMaxSize: encoder.maxSize
110
+ });
105
111
  }
106
112
  return {
107
113
  ...decoder,
@@ -167,10 +173,16 @@ function mapCodec(codec, unmap, map) {
167
173
  read: map ? mapDecoder(codec, map).read : codec.read
168
174
  });
169
175
  }
170
-
171
- // src/reverse-codec.ts
172
176
  function reverseEncoder(encoder) {
173
- assertIsFixedSize(encoder, "Cannot reverse a codec of variable size.");
177
+ try {
178
+ assertIsFixedSize(encoder);
179
+ } catch (e) {
180
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
181
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);
182
+ } else {
183
+ throw e;
184
+ }
185
+ }
174
186
  return createEncoder({
175
187
  ...encoder,
176
188
  write: (value, bytes, offset) => {
@@ -182,7 +194,15 @@ function reverseEncoder(encoder) {
182
194
  });
183
195
  }
184
196
  function reverseDecoder(decoder) {
185
- assertIsFixedSize(decoder, "Cannot reverse a codec of variable size.");
197
+ try {
198
+ assertIsFixedSize(decoder);
199
+ } catch (e) {
200
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
201
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);
202
+ } else {
203
+ throw e;
204
+ }
205
+ }
186
206
  return createDecoder({
187
207
  ...decoder,
188
208
  read: (bytes, offset) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/assertions.ts","../src/bytes.ts","../src/codec.ts","../src/combine-codec.ts","../src/fix-codec.ts","../src/map-codec.ts","../src/reverse-codec.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Asserts that a given byte array is not empty.\n */\nexport function assertByteArrayIsNotEmptyForCodec(codecDescription: string, bytes: Uint8Array, offset = 0) {\n if (bytes.length - offset <= 0) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);\n }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode.\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n codecDescription: string,\n expected: number,\n bytes: Uint8Array,\n offset = 0,\n) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);\n }\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n message?: string,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n message?: string,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n message?: string,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a fixed-size codec, got a variable-size one.');\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(\n encoder: Encoder<T>,\n message?: string,\n): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(\n decoder: Decoder<T>,\n message?: string,\n): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n message?: string,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a variable-size codec, got a fixed-size one.');\n }\n}\n","import {\n Codec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Combines an encoder and a decoder into a codec.\n * The encoder and decoder must have the same fixed size, max size and description.\n * If a description is provided, it will override the encoder and decoder descriptions.\n */\nexport function combineCodec<TFrom, TTo extends TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: VariableSizeEncoder<TFrom>,\n decoder: VariableSizeDecoder<TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo> {\n if (isFixedSize(encoder) !== isFixedSize(decoder)) {\n // TODO: Coded error.\n throw new Error(`Encoder and decoder must either both be fixed-size or variable-size.`);\n }\n\n if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`,\n );\n }\n\n if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`,\n );\n }\n\n return {\n ...decoder,\n ...encoder,\n decode: decoder.decode,\n encode: encoder.encode,\n read: decoder.read,\n write: encoder.write,\n };\n}\n","import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport { fixBytes } from './bytes';\nimport {\n Codec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n Offset,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Creates a fixed-size encoder from a given encoder.\n *\n * @param encoder - The encoder to wrap into a fixed-size encoder.\n * @param fixedBytes - The fixed number of bytes to write.\n */\nexport function fixEncoder<TFrom, TSize extends number>(\n encoder: Encoder<TFrom>,\n fixedBytes: TSize,\n): FixedSizeEncoder<TFrom, TSize> {\n return createEncoder({\n fixedSize: fixedBytes,\n write: (value: TFrom, bytes: Uint8Array, offset: Offset) => {\n // Here we exceptionally use the `encode` function instead of the `write`\n // function as using the nested `write` function on a fixed-sized byte\n // array may result in a out-of-bounds error on the nested encoder.\n const variableByteArray = encoder.encode(value);\n const fixedByteArray =\n variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;\n bytes.set(fixedByteArray, offset);\n return offset + fixedBytes;\n },\n });\n}\n\n/**\n * Creates a fixed-size decoder from a given decoder.\n *\n * @param decoder - The decoder to wrap into a fixed-size decoder.\n * @param fixedBytes - The fixed number of bytes to read.\n */\nexport function fixDecoder<TTo, TSize extends number>(\n decoder: Decoder<TTo>,\n fixedBytes: TSize,\n): FixedSizeDecoder<TTo, TSize> {\n return createDecoder({\n fixedSize: fixedBytes,\n read: (bytes: Uint8Array, offset: Offset) => {\n assertByteArrayHasEnoughBytesForCodec('fixCodec', fixedBytes, bytes, offset);\n // Slice the byte array to the fixed size if necessary.\n if (offset > 0 || bytes.length > fixedBytes) {\n bytes = bytes.slice(offset, offset + fixedBytes);\n }\n // If the nested decoder is fixed-size, pad and truncate the byte array accordingly.\n if (isFixedSize(decoder)) {\n bytes = fixBytes(bytes, decoder.fixedSize);\n }\n // Decode the value using the nested decoder.\n const [value] = decoder.read(bytes, 0);\n return [value, offset + fixedBytes];\n },\n });\n}\n\n/**\n * Creates a fixed-size codec from a given codec.\n *\n * @param codec - The codec to wrap into a fixed-size codec.\n * @param fixedBytes - The fixed number of bytes to read/write.\n */\nexport function fixCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: Codec<TFrom, TTo>,\n fixedBytes: TSize,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(fixEncoder(codec, fixedBytes), fixDecoder(codec, fixedBytes));\n}\n","import {\n Codec,\n createCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isVariableSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Converts an encoder A to a encoder B by mapping their values.\n */\nexport function mapEncoder<TOldFrom, TNewFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TOldFrom, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeEncoder<TNewFrom, TSize>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: VariableSizeEncoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeEncoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom> {\n return createEncoder({\n ...(isVariableSize(encoder)\n ? { ...encoder, getSizeFromValue: (value: TNewFrom) => encoder.getSizeFromValue(unmap(value)) }\n : encoder),\n write: (value: TNewFrom, bytes, offset) => encoder.write(unmap(value), bytes, offset),\n });\n}\n\n/**\n * Converts an decoder A to a decoder B by mapping their values.\n */\nexport function mapDecoder<TOldTo, TNewTo, TSize extends number>(\n decoder: FixedSizeDecoder<TOldTo, TSize>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeDecoder<TNewTo, TSize>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: VariableSizeDecoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeDecoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo> {\n return createDecoder({\n ...decoder,\n read: (bytes: Uint8Array, offset) => {\n const [value, newOffset] = decoder.read(bytes, offset);\n return [map(value, bytes, offset), newOffset];\n },\n });\n}\n\n/**\n * Converts a codec A to a codec B by mapping their values.\n */\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeCodec<TNewFrom, TTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: VariableSizeCodec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeCodec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: Codec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Codec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TOldTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeCodec<TNewFrom, TNewTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: VariableSizeCodec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeCodec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map?: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo> {\n return createCodec({\n ...mapEncoder(codec, unmap),\n read: map ? mapDecoder(codec, map).read : (codec.read as unknown as Decoder<TNewTo>['read']),\n });\n}\n","import {\n assertIsFixedSize,\n createDecoder,\n createEncoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Reverses the bytes of a fixed-size encoder.\n */\nexport function reverseEncoder<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n assertIsFixedSize(encoder, 'Cannot reverse a codec of variable size.');\n return createEncoder({\n ...encoder,\n write: (value: TFrom, bytes, offset) => {\n const newOffset = encoder.write(value, bytes, offset);\n const slice = bytes.slice(offset, offset + encoder.fixedSize).reverse();\n bytes.set(slice, offset);\n return newOffset;\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size decoder.\n */\nexport function reverseDecoder<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n assertIsFixedSize(decoder, 'Cannot reverse a codec of variable size.');\n return createDecoder({\n ...decoder,\n read: (bytes, offset) => {\n const reverseEnd = offset + decoder.fixedSize;\n if (offset === 0 && bytes.length === reverseEnd) {\n return decoder.read(bytes.reverse(), offset);\n }\n const reversedBytes = bytes.slice();\n reversedBytes.set(bytes.slice(offset, reverseEnd).reverse(), offset);\n return decoder.read(reversedBytes, offset);\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size codec.\n */\nexport function reverseCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n"]}
1
+ {"version":3,"sources":["../src/assertions.ts","../src/bytes.ts","../src/codec.ts","../src/combine-codec.ts","../src/fix-codec.ts","../src/map-codec.ts","../src/reverse-codec.ts"],"names":["SolanaError","SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH"],"mappings":"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","sourcesContent":["import {\n SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Asserts that a given byte array is not empty.\n */\nexport function assertByteArrayIsNotEmptyForCodec(codecDescription: string, bytes: Uint8Array, offset = 0) {\n if (bytes.length - offset <= 0) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY, {\n codecDescription,\n });\n }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode.\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n codecDescription: string,\n expected: number,\n bytes: Uint8Array,\n offset = 0,\n) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n throw new SolanaError(SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES, {\n bytesLength,\n codecDescription,\n expected,\n });\n }\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","import {\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(encoder: Encoder<T>): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(decoder: Decoder<T>): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);\n }\n}\n","import {\n SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH,\n SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH,\n SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH,\n SolanaError,\n} from '@solana/errors';\n\nimport {\n Codec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Combines an encoder and a decoder into a codec.\n * The encoder and decoder must have the same fixed size, max size and description.\n * If a description is provided, it will override the encoder and decoder descriptions.\n */\nexport function combineCodec<TFrom, TTo extends TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: VariableSizeEncoder<TFrom>,\n decoder: VariableSizeDecoder<TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo> {\n if (isFixedSize(encoder) !== isFixedSize(decoder)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH);\n }\n\n if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {\n throw new SolanaError(SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH, {\n decoderFixedSize: decoder.fixedSize,\n encoderFixedSize: encoder.fixedSize,\n });\n }\n\n if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {\n throw new SolanaError(SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH, {\n decoderMaxSize: decoder.maxSize,\n encoderMaxSize: encoder.maxSize,\n });\n }\n\n return {\n ...decoder,\n ...encoder,\n decode: decoder.decode,\n encode: encoder.encode,\n read: decoder.read,\n write: encoder.write,\n };\n}\n","import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport { fixBytes } from './bytes';\nimport {\n Codec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n Offset,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Creates a fixed-size encoder from a given encoder.\n *\n * @param encoder - The encoder to wrap into a fixed-size encoder.\n * @param fixedBytes - The fixed number of bytes to write.\n */\nexport function fixEncoder<TFrom, TSize extends number>(\n encoder: Encoder<TFrom>,\n fixedBytes: TSize,\n): FixedSizeEncoder<TFrom, TSize> {\n return createEncoder({\n fixedSize: fixedBytes,\n write: (value: TFrom, bytes: Uint8Array, offset: Offset) => {\n // Here we exceptionally use the `encode` function instead of the `write`\n // function as using the nested `write` function on a fixed-sized byte\n // array may result in a out-of-bounds error on the nested encoder.\n const variableByteArray = encoder.encode(value);\n const fixedByteArray =\n variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;\n bytes.set(fixedByteArray, offset);\n return offset + fixedBytes;\n },\n });\n}\n\n/**\n * Creates a fixed-size decoder from a given decoder.\n *\n * @param decoder - The decoder to wrap into a fixed-size decoder.\n * @param fixedBytes - The fixed number of bytes to read.\n */\nexport function fixDecoder<TTo, TSize extends number>(\n decoder: Decoder<TTo>,\n fixedBytes: TSize,\n): FixedSizeDecoder<TTo, TSize> {\n return createDecoder({\n fixedSize: fixedBytes,\n read: (bytes: Uint8Array, offset: Offset) => {\n assertByteArrayHasEnoughBytesForCodec('fixCodec', fixedBytes, bytes, offset);\n // Slice the byte array to the fixed size if necessary.\n if (offset > 0 || bytes.length > fixedBytes) {\n bytes = bytes.slice(offset, offset + fixedBytes);\n }\n // If the nested decoder is fixed-size, pad and truncate the byte array accordingly.\n if (isFixedSize(decoder)) {\n bytes = fixBytes(bytes, decoder.fixedSize);\n }\n // Decode the value using the nested decoder.\n const [value] = decoder.read(bytes, 0);\n return [value, offset + fixedBytes];\n },\n });\n}\n\n/**\n * Creates a fixed-size codec from a given codec.\n *\n * @param codec - The codec to wrap into a fixed-size codec.\n * @param fixedBytes - The fixed number of bytes to read/write.\n */\nexport function fixCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: Codec<TFrom, TTo>,\n fixedBytes: TSize,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(fixEncoder(codec, fixedBytes), fixDecoder(codec, fixedBytes));\n}\n","import {\n Codec,\n createCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isVariableSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Converts an encoder A to a encoder B by mapping their values.\n */\nexport function mapEncoder<TOldFrom, TNewFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TOldFrom, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeEncoder<TNewFrom, TSize>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: VariableSizeEncoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeEncoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom> {\n return createEncoder({\n ...(isVariableSize(encoder)\n ? { ...encoder, getSizeFromValue: (value: TNewFrom) => encoder.getSizeFromValue(unmap(value)) }\n : encoder),\n write: (value: TNewFrom, bytes, offset) => encoder.write(unmap(value), bytes, offset),\n });\n}\n\n/**\n * Converts an decoder A to a decoder B by mapping their values.\n */\nexport function mapDecoder<TOldTo, TNewTo, TSize extends number>(\n decoder: FixedSizeDecoder<TOldTo, TSize>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeDecoder<TNewTo, TSize>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: VariableSizeDecoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeDecoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo> {\n return createDecoder({\n ...decoder,\n read: (bytes: Uint8Array, offset) => {\n const [value, newOffset] = decoder.read(bytes, offset);\n return [map(value, bytes, offset), newOffset];\n },\n });\n}\n\n/**\n * Converts a codec A to a codec B by mapping their values.\n */\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeCodec<TNewFrom, TTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: VariableSizeCodec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeCodec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: Codec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Codec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TOldTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeCodec<TNewFrom, TNewTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: VariableSizeCodec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeCodec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map?: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo> {\n return createCodec({\n ...mapEncoder(codec, unmap),\n read: map ? mapDecoder(codec, map).read : (codec.read as unknown as Decoder<TNewTo>['read']),\n });\n}\n","import {\n isSolanaError,\n SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE,\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\nimport {\n assertIsFixedSize,\n createDecoder,\n createEncoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Reverses the bytes of a fixed-size encoder.\n */\nexport function reverseEncoder<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n try {\n assertIsFixedSize(encoder);\n } catch (e) {\n if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);\n } else {\n throw e;\n }\n }\n return createEncoder({\n ...encoder,\n write: (value: TFrom, bytes, offset) => {\n const newOffset = encoder.write(value, bytes, offset);\n const slice = bytes.slice(offset, offset + encoder.fixedSize).reverse();\n bytes.set(slice, offset);\n return newOffset;\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size decoder.\n */\nexport function reverseDecoder<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n try {\n assertIsFixedSize(decoder);\n } catch (e) {\n if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);\n } else {\n throw e;\n }\n }\n return createDecoder({\n ...decoder,\n read: (bytes, offset) => {\n const reverseEnd = offset + decoder.fixedSize;\n if (offset === 0 && bytes.length === reverseEnd) {\n return decoder.read(bytes.reverse(), offset);\n }\n const reversedBytes = bytes.slice();\n reversedBytes.set(bytes.slice(offset, reverseEnd).reverse(), offset);\n return decoder.read(reversedBytes, offset);\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size codec.\n */\nexport function reverseCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n"]}
@@ -1,13 +1,21 @@
1
+ import { SolanaError, SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY, SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH, SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH, SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH, SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH, SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH, isSolanaError, SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE } from '@solana/errors';
2
+
1
3
  // src/assertions.ts
2
4
  function assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset = 0) {
3
5
  if (bytes.length - offset <= 0) {
4
- throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);
6
+ throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY, {
7
+ codecDescription
8
+ });
5
9
  }
6
10
  }
7
11
  function assertByteArrayHasEnoughBytesForCodec(codecDescription, expected, bytes, offset = 0) {
8
12
  const bytesLength = bytes.length - offset;
9
13
  if (bytesLength < expected) {
10
- throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);
14
+ throw new SolanaError(SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES, {
15
+ bytesLength,
16
+ codecDescription,
17
+ expected
18
+ });
11
19
  }
12
20
  }
13
21
 
@@ -37,8 +45,6 @@ var padBytes = (bytes, length) => {
37
45
  return paddedBytes;
38
46
  };
39
47
  var fixBytes = (bytes, length) => padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);
40
-
41
- // src/codec.ts
42
48
  function getEncodedSize(value, encoder) {
43
49
  return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
44
50
  }
@@ -72,34 +78,34 @@ function createCodec(codec) {
72
78
  function isFixedSize(codec) {
73
79
  return "fixedSize" in codec && typeof codec.fixedSize === "number";
74
80
  }
75
- function assertIsFixedSize(codec, message) {
81
+ function assertIsFixedSize(codec) {
76
82
  if (!isFixedSize(codec)) {
77
- throw new Error(message ?? "Expected a fixed-size codec, got a variable-size one.");
83
+ throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);
78
84
  }
79
85
  }
80
86
  function isVariableSize(codec) {
81
87
  return !isFixedSize(codec);
82
88
  }
83
- function assertIsVariableSize(codec, message) {
89
+ function assertIsVariableSize(codec) {
84
90
  if (!isVariableSize(codec)) {
85
- throw new Error(message ?? "Expected a variable-size codec, got a fixed-size one.");
91
+ throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);
86
92
  }
87
93
  }
88
-
89
- // src/combine-codec.ts
90
94
  function combineCodec(encoder, decoder) {
91
95
  if (isFixedSize(encoder) !== isFixedSize(decoder)) {
92
- throw new Error(`Encoder and decoder must either both be fixed-size or variable-size.`);
96
+ throw new SolanaError(SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH);
93
97
  }
94
98
  if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {
95
- throw new Error(
96
- `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`
97
- );
99
+ throw new SolanaError(SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH, {
100
+ decoderFixedSize: decoder.fixedSize,
101
+ encoderFixedSize: encoder.fixedSize
102
+ });
98
103
  }
99
104
  if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {
100
- throw new Error(
101
- `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`
102
- );
105
+ throw new SolanaError(SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH, {
106
+ decoderMaxSize: decoder.maxSize,
107
+ encoderMaxSize: encoder.maxSize
108
+ });
103
109
  }
104
110
  return {
105
111
  ...decoder,
@@ -165,10 +171,16 @@ function mapCodec(codec, unmap, map) {
165
171
  read: map ? mapDecoder(codec, map).read : codec.read
166
172
  });
167
173
  }
168
-
169
- // src/reverse-codec.ts
170
174
  function reverseEncoder(encoder) {
171
- assertIsFixedSize(encoder, "Cannot reverse a codec of variable size.");
175
+ try {
176
+ assertIsFixedSize(encoder);
177
+ } catch (e) {
178
+ if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
179
+ throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);
180
+ } else {
181
+ throw e;
182
+ }
183
+ }
172
184
  return createEncoder({
173
185
  ...encoder,
174
186
  write: (value, bytes, offset) => {
@@ -180,7 +192,15 @@ function reverseEncoder(encoder) {
180
192
  });
181
193
  }
182
194
  function reverseDecoder(decoder) {
183
- assertIsFixedSize(decoder, "Cannot reverse a codec of variable size.");
195
+ try {
196
+ assertIsFixedSize(decoder);
197
+ } catch (e) {
198
+ if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
199
+ throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);
200
+ } else {
201
+ throw e;
202
+ }
203
+ }
184
204
  return createDecoder({
185
205
  ...decoder,
186
206
  read: (bytes, offset) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/assertions.ts","../src/bytes.ts","../src/codec.ts","../src/combine-codec.ts","../src/fix-codec.ts","../src/map-codec.ts","../src/reverse-codec.ts"],"names":[],"mappings":";AAGO,SAAS,kCAAkC,kBAA0B,OAAmB,SAAS,GAAG;AACvG,MAAI,MAAM,SAAS,UAAU,GAAG;AAE5B,UAAM,IAAI,MAAM,UAAU,gBAAgB,oCAAoC;AAAA,EAClF;AACJ;AAKO,SAAS,sCACZ,kBACA,UACA,OACA,SAAS,GACX;AACE,QAAM,cAAc,MAAM,SAAS;AACnC,MAAI,cAAc,UAAU;AAExB,UAAM,IAAI,MAAM,UAAU,gBAAgB,cAAc,QAAQ,eAAe,WAAW,GAAG;AAAA,EACjG;AACJ;;;ACpBO,IAAM,aAAa,CAAC,eAAyC;AAChE,QAAM,qBAAqB,WAAW,OAAO,SAAO,IAAI,MAAM;AAC9D,MAAI,mBAAmB,WAAW,GAAG;AACjC,WAAO,WAAW,SAAS,WAAW,CAAC,IAAI,IAAI,WAAW;AAAA,EAC9D;AAEA,MAAI,mBAAmB,WAAW,GAAG;AACjC,WAAO,mBAAmB,CAAC;AAAA,EAC/B;AAEA,QAAM,cAAc,mBAAmB,OAAO,CAAC,OAAO,QAAQ,QAAQ,IAAI,QAAQ,CAAC;AACnF,QAAM,SAAS,IAAI,WAAW,WAAW;AACzC,MAAI,SAAS;AACb,qBAAmB,QAAQ,SAAO;AAC9B,WAAO,IAAI,KAAK,MAAM;AACtB,cAAU,IAAI;AAAA,EAClB,CAAC;AACD,SAAO;AACX;AAMO,IAAM,WAAW,CAAC,OAAmB,WAA+B;AACvE,MAAI,MAAM,UAAU;AAAQ,WAAO;AACnC,QAAM,cAAc,IAAI,WAAW,MAAM,EAAE,KAAK,CAAC;AACjD,cAAY,IAAI,KAAK;AACrB,SAAO;AACX;AAOO,IAAM,WAAW,CAAC,OAAmB,WACxC,SAAS,MAAM,UAAU,SAAS,QAAQ,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM;;;ACsCrE,SAAS,eACZ,OACA,SACM;AACN,SAAO,eAAe,UAAU,QAAQ,YAAY,QAAQ,iBAAiB,KAAK;AACtF;AAUO,SAAS,cACZ,SACc;AACd,SAAO,OAAO,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,QAAQ,WAAS;AACb,YAAM,QAAQ,IAAI,WAAW,eAAe,OAAO,OAAO,CAAC;AAC3D,cAAQ,MAAM,OAAO,OAAO,CAAC;AAC7B,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACL;AAUO,SAAS,cACZ,SACY;AACZ,SAAO,OAAO,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,QAAQ,CAAC,OAAO,SAAS,MAAM,QAAQ,KAAK,OAAO,MAAM,EAAE,CAAC;AAAA,EAChE,CAAC;AACL;AAcO,SAAS,YACZ,OAGiB;AACjB,SAAO,OAAO,OAAO;AAAA,IACjB,GAAG;AAAA,IACH,QAAQ,CAAC,OAAO,SAAS,MAAM,MAAM,KAAK,OAAO,MAAM,EAAE,CAAC;AAAA,IAC1D,QAAQ,WAAS;AACb,YAAM,QAAQ,IAAI,WAAW,eAAe,OAAO,KAAK,CAAC;AACzD,YAAM,MAAM,OAAO,OAAO,CAAC;AAC3B,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACL;AAcO,SAAS,YAAY,OAAqF;AAC7G,SAAO,eAAe,SAAS,OAAO,MAAM,cAAc;AAC9D;AAkBO,SAAS,kBACZ,OACA,SACsC;AACtC,MAAI,CAAC,YAAY,KAAK,GAAG;AAErB,UAAM,IAAI,MAAM,WAAW,uDAAuD;AAAA,EACtF;AACJ;AAQO,SAAS,eAAe,OAAoF;AAC/G,SAAO,CAAC,YAAY,KAAK;AAC7B;AAkBO,SAAS,qBACZ,OACA,SACqC;AACrC,MAAI,CAAC,eAAe,KAAK,GAAG;AAExB,UAAM,IAAI,MAAM,WAAW,uDAAuD;AAAA,EACtF;AACJ;;;ACtMO,SAAS,aACZ,SACA,SACiB;AACjB,MAAI,YAAY,OAAO,MAAM,YAAY,OAAO,GAAG;AAE/C,UAAM,IAAI,MAAM,sEAAsE;AAAA,EAC1F;AAEA,MAAI,YAAY,OAAO,KAAK,YAAY,OAAO,KAAK,QAAQ,cAAc,QAAQ,WAAW;AAEzF,UAAM,IAAI;AAAA,MACN,2DAA2D,QAAQ,SAAS,UAAU,QAAQ,SAAS;AAAA,IAC3G;AAAA,EACJ;AAEA,MAAI,CAAC,YAAY,OAAO,KAAK,CAAC,YAAY,OAAO,KAAK,QAAQ,YAAY,QAAQ,SAAS;AAEvF,UAAM,IAAI;AAAA,MACN,yDAAyD,QAAQ,OAAO,UAAU,QAAQ,OAAO;AAAA,IACrG;AAAA,EACJ;AAEA,SAAO;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,MAAM,QAAQ;AAAA,IACd,OAAO,QAAQ;AAAA,EACnB;AACJ;;;ACvCO,SAAS,WACZ,SACA,YAC8B;AAC9B,SAAO,cAAc;AAAA,IACjB,WAAW;AAAA,IACX,OAAO,CAAC,OAAc,OAAmB,WAAmB;AAIxD,YAAM,oBAAoB,QAAQ,OAAO,KAAK;AAC9C,YAAM,iBACF,kBAAkB,SAAS,aAAa,kBAAkB,MAAM,GAAG,UAAU,IAAI;AACrF,YAAM,IAAI,gBAAgB,MAAM;AAChC,aAAO,SAAS;AAAA,IACpB;AAAA,EACJ,CAAC;AACL;AAQO,SAAS,WACZ,SACA,YAC4B;AAC5B,SAAO,cAAc;AAAA,IACjB,WAAW;AAAA,IACX,MAAM,CAAC,OAAmB,WAAmB;AACzC,4CAAsC,YAAY,YAAY,OAAO,MAAM;AAE3E,UAAI,SAAS,KAAK,MAAM,SAAS,YAAY;AACzC,gBAAQ,MAAM,MAAM,QAAQ,SAAS,UAAU;AAAA,MACnD;AAEA,UAAI,YAAY,OAAO,GAAG;AACtB,gBAAQ,SAAS,OAAO,QAAQ,SAAS;AAAA,MAC7C;AAEA,YAAM,CAAC,KAAK,IAAI,QAAQ,KAAK,OAAO,CAAC;AACrC,aAAO,CAAC,OAAO,SAAS,UAAU;AAAA,IACtC;AAAA,EACJ,CAAC;AACL;AAQO,SAAS,SACZ,OACA,YACiC;AACjC,SAAO,aAAa,WAAW,OAAO,UAAU,GAAG,WAAW,OAAO,UAAU,CAAC;AACpF;;;AClDO,SAAS,WACZ,SACA,OACiB;AACjB,SAAO,cAAc;AAAA,IACjB,GAAI,eAAe,OAAO,IACpB,EAAE,GAAG,SAAS,kBAAkB,CAAC,UAAoB,QAAQ,iBAAiB,MAAM,KAAK,CAAC,EAAE,IAC5F;AAAA,IACN,OAAO,CAAC,OAAiB,OAAO,WAAW,QAAQ,MAAM,MAAM,KAAK,GAAG,OAAO,MAAM;AAAA,EACxF,CAAC;AACL;AAiBO,SAAS,WACZ,SACA,KACe;AACf,SAAO,cAAc;AAAA,IACjB,GAAG;AAAA,IACH,MAAM,CAAC,OAAmB,WAAW;AACjC,YAAM,CAAC,OAAO,SAAS,IAAI,QAAQ,KAAK,OAAO,MAAM;AACrD,aAAO,CAAC,IAAI,OAAO,OAAO,MAAM,GAAG,SAAS;AAAA,IAChD;AAAA,EACJ,CAAC;AACL;AAgCO,SAAS,SACZ,OACA,OACA,KACuB;AACvB,SAAO,YAAY;AAAA,IACf,GAAG,WAAW,OAAO,KAAK;AAAA,IAC1B,MAAM,MAAM,WAAW,OAAO,GAAG,EAAE,OAAQ,MAAM;AAAA,EACrD,CAAC;AACL;;;ACjGO,SAAS,eACZ,SAC8B;AAC9B,oBAAkB,SAAS,0CAA0C;AACrE,SAAO,cAAc;AAAA,IACjB,GAAG;AAAA,IACH,OAAO,CAAC,OAAc,OAAO,WAAW;AACpC,YAAM,YAAY,QAAQ,MAAM,OAAO,OAAO,MAAM;AACpD,YAAM,QAAQ,MAAM,MAAM,QAAQ,SAAS,QAAQ,SAAS,EAAE,QAAQ;AACtE,YAAM,IAAI,OAAO,MAAM;AACvB,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACL;AAKO,SAAS,eACZ,SAC4B;AAC5B,oBAAkB,SAAS,0CAA0C;AACrE,SAAO,cAAc;AAAA,IACjB,GAAG;AAAA,IACH,MAAM,CAAC,OAAO,WAAW;AACrB,YAAM,aAAa,SAAS,QAAQ;AACpC,UAAI,WAAW,KAAK,MAAM,WAAW,YAAY;AAC7C,eAAO,QAAQ,KAAK,MAAM,QAAQ,GAAG,MAAM;AAAA,MAC/C;AACA,YAAM,gBAAgB,MAAM,MAAM;AAClC,oBAAc,IAAI,MAAM,MAAM,QAAQ,UAAU,EAAE,QAAQ,GAAG,MAAM;AACnE,aAAO,QAAQ,KAAK,eAAe,MAAM;AAAA,IAC7C;AAAA,EACJ,CAAC;AACL;AAKO,SAAS,aACZ,OACiC;AACjC,SAAO,aAAa,eAAe,KAAK,GAAG,eAAe,KAAK,CAAC;AACpE","sourcesContent":["/**\n * Asserts that a given byte array is not empty.\n */\nexport function assertByteArrayIsNotEmptyForCodec(codecDescription: string, bytes: Uint8Array, offset = 0) {\n if (bytes.length - offset <= 0) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);\n }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode.\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n codecDescription: string,\n expected: number,\n bytes: Uint8Array,\n offset = 0,\n) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);\n }\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n message?: string,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n message?: string,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n message?: string,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a fixed-size codec, got a variable-size one.');\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(\n encoder: Encoder<T>,\n message?: string,\n): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(\n decoder: Decoder<T>,\n message?: string,\n): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n message?: string,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a variable-size codec, got a fixed-size one.');\n }\n}\n","import {\n Codec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Combines an encoder and a decoder into a codec.\n * The encoder and decoder must have the same fixed size, max size and description.\n * If a description is provided, it will override the encoder and decoder descriptions.\n */\nexport function combineCodec<TFrom, TTo extends TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: VariableSizeEncoder<TFrom>,\n decoder: VariableSizeDecoder<TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo> {\n if (isFixedSize(encoder) !== isFixedSize(decoder)) {\n // TODO: Coded error.\n throw new Error(`Encoder and decoder must either both be fixed-size or variable-size.`);\n }\n\n if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`,\n );\n }\n\n if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`,\n );\n }\n\n return {\n ...decoder,\n ...encoder,\n decode: decoder.decode,\n encode: encoder.encode,\n read: decoder.read,\n write: encoder.write,\n };\n}\n","import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport { fixBytes } from './bytes';\nimport {\n Codec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n Offset,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Creates a fixed-size encoder from a given encoder.\n *\n * @param encoder - The encoder to wrap into a fixed-size encoder.\n * @param fixedBytes - The fixed number of bytes to write.\n */\nexport function fixEncoder<TFrom, TSize extends number>(\n encoder: Encoder<TFrom>,\n fixedBytes: TSize,\n): FixedSizeEncoder<TFrom, TSize> {\n return createEncoder({\n fixedSize: fixedBytes,\n write: (value: TFrom, bytes: Uint8Array, offset: Offset) => {\n // Here we exceptionally use the `encode` function instead of the `write`\n // function as using the nested `write` function on a fixed-sized byte\n // array may result in a out-of-bounds error on the nested encoder.\n const variableByteArray = encoder.encode(value);\n const fixedByteArray =\n variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;\n bytes.set(fixedByteArray, offset);\n return offset + fixedBytes;\n },\n });\n}\n\n/**\n * Creates a fixed-size decoder from a given decoder.\n *\n * @param decoder - The decoder to wrap into a fixed-size decoder.\n * @param fixedBytes - The fixed number of bytes to read.\n */\nexport function fixDecoder<TTo, TSize extends number>(\n decoder: Decoder<TTo>,\n fixedBytes: TSize,\n): FixedSizeDecoder<TTo, TSize> {\n return createDecoder({\n fixedSize: fixedBytes,\n read: (bytes: Uint8Array, offset: Offset) => {\n assertByteArrayHasEnoughBytesForCodec('fixCodec', fixedBytes, bytes, offset);\n // Slice the byte array to the fixed size if necessary.\n if (offset > 0 || bytes.length > fixedBytes) {\n bytes = bytes.slice(offset, offset + fixedBytes);\n }\n // If the nested decoder is fixed-size, pad and truncate the byte array accordingly.\n if (isFixedSize(decoder)) {\n bytes = fixBytes(bytes, decoder.fixedSize);\n }\n // Decode the value using the nested decoder.\n const [value] = decoder.read(bytes, 0);\n return [value, offset + fixedBytes];\n },\n });\n}\n\n/**\n * Creates a fixed-size codec from a given codec.\n *\n * @param codec - The codec to wrap into a fixed-size codec.\n * @param fixedBytes - The fixed number of bytes to read/write.\n */\nexport function fixCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: Codec<TFrom, TTo>,\n fixedBytes: TSize,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(fixEncoder(codec, fixedBytes), fixDecoder(codec, fixedBytes));\n}\n","import {\n Codec,\n createCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isVariableSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Converts an encoder A to a encoder B by mapping their values.\n */\nexport function mapEncoder<TOldFrom, TNewFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TOldFrom, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeEncoder<TNewFrom, TSize>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: VariableSizeEncoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeEncoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom> {\n return createEncoder({\n ...(isVariableSize(encoder)\n ? { ...encoder, getSizeFromValue: (value: TNewFrom) => encoder.getSizeFromValue(unmap(value)) }\n : encoder),\n write: (value: TNewFrom, bytes, offset) => encoder.write(unmap(value), bytes, offset),\n });\n}\n\n/**\n * Converts an decoder A to a decoder B by mapping their values.\n */\nexport function mapDecoder<TOldTo, TNewTo, TSize extends number>(\n decoder: FixedSizeDecoder<TOldTo, TSize>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeDecoder<TNewTo, TSize>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: VariableSizeDecoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeDecoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo> {\n return createDecoder({\n ...decoder,\n read: (bytes: Uint8Array, offset) => {\n const [value, newOffset] = decoder.read(bytes, offset);\n return [map(value, bytes, offset), newOffset];\n },\n });\n}\n\n/**\n * Converts a codec A to a codec B by mapping their values.\n */\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeCodec<TNewFrom, TTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: VariableSizeCodec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeCodec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: Codec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Codec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TOldTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeCodec<TNewFrom, TNewTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: VariableSizeCodec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeCodec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map?: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo> {\n return createCodec({\n ...mapEncoder(codec, unmap),\n read: map ? mapDecoder(codec, map).read : (codec.read as unknown as Decoder<TNewTo>['read']),\n });\n}\n","import {\n assertIsFixedSize,\n createDecoder,\n createEncoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Reverses the bytes of a fixed-size encoder.\n */\nexport function reverseEncoder<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n assertIsFixedSize(encoder, 'Cannot reverse a codec of variable size.');\n return createEncoder({\n ...encoder,\n write: (value: TFrom, bytes, offset) => {\n const newOffset = encoder.write(value, bytes, offset);\n const slice = bytes.slice(offset, offset + encoder.fixedSize).reverse();\n bytes.set(slice, offset);\n return newOffset;\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size decoder.\n */\nexport function reverseDecoder<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n assertIsFixedSize(decoder, 'Cannot reverse a codec of variable size.');\n return createDecoder({\n ...decoder,\n read: (bytes, offset) => {\n const reverseEnd = offset + decoder.fixedSize;\n if (offset === 0 && bytes.length === reverseEnd) {\n return decoder.read(bytes.reverse(), offset);\n }\n const reversedBytes = bytes.slice();\n reversedBytes.set(bytes.slice(offset, reverseEnd).reverse(), offset);\n return decoder.read(reversedBytes, offset);\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size codec.\n */\nexport function reverseCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n"]}
1
+ {"version":3,"sources":["../src/assertions.ts","../src/bytes.ts","../src/codec.ts","../src/combine-codec.ts","../src/fix-codec.ts","../src/map-codec.ts","../src/reverse-codec.ts"],"names":["SolanaError","SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH"],"mappings":"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","sourcesContent":["import {\n SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Asserts that a given byte array is not empty.\n */\nexport function assertByteArrayIsNotEmptyForCodec(codecDescription: string, bytes: Uint8Array, offset = 0) {\n if (bytes.length - offset <= 0) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_DECODE_EMPTY_BYTE_ARRAY, {\n codecDescription,\n });\n }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode.\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n codecDescription: string,\n expected: number,\n bytes: Uint8Array,\n offset = 0,\n) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n throw new SolanaError(SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_BYTES, {\n bytesLength,\n codecDescription,\n expected,\n });\n }\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","import {\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(encoder: Encoder<T>): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(decoder: Decoder<T>): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);\n }\n}\n","import {\n SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH,\n SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH,\n SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH,\n SolanaError,\n} from '@solana/errors';\n\nimport {\n Codec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Combines an encoder and a decoder into a codec.\n * The encoder and decoder must have the same fixed size, max size and description.\n * If a description is provided, it will override the encoder and decoder descriptions.\n */\nexport function combineCodec<TFrom, TTo extends TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: VariableSizeEncoder<TFrom>,\n decoder: VariableSizeDecoder<TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n encoder: Encoder<TFrom>,\n decoder: Decoder<TTo>,\n): Codec<TFrom, TTo> {\n if (isFixedSize(encoder) !== isFixedSize(decoder)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH);\n }\n\n if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {\n throw new SolanaError(SOLANA_ERROR__CODECS_FIXED_SIZE_ENCODER_DECODER_SIZE_MISMATCH, {\n decoderFixedSize: decoder.fixedSize,\n encoderFixedSize: encoder.fixedSize,\n });\n }\n\n if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {\n throw new SolanaError(SOLANA_ERROR__CODECS_VARIABLE_SIZE_ENCODER_DECODER_MAX_SIZE_MISMATCH, {\n decoderMaxSize: decoder.maxSize,\n encoderMaxSize: encoder.maxSize,\n });\n }\n\n return {\n ...decoder,\n ...encoder,\n decode: decoder.decode,\n encode: encoder.encode,\n read: decoder.read,\n write: encoder.write,\n };\n}\n","import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport { fixBytes } from './bytes';\nimport {\n Codec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isFixedSize,\n Offset,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Creates a fixed-size encoder from a given encoder.\n *\n * @param encoder - The encoder to wrap into a fixed-size encoder.\n * @param fixedBytes - The fixed number of bytes to write.\n */\nexport function fixEncoder<TFrom, TSize extends number>(\n encoder: Encoder<TFrom>,\n fixedBytes: TSize,\n): FixedSizeEncoder<TFrom, TSize> {\n return createEncoder({\n fixedSize: fixedBytes,\n write: (value: TFrom, bytes: Uint8Array, offset: Offset) => {\n // Here we exceptionally use the `encode` function instead of the `write`\n // function as using the nested `write` function on a fixed-sized byte\n // array may result in a out-of-bounds error on the nested encoder.\n const variableByteArray = encoder.encode(value);\n const fixedByteArray =\n variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;\n bytes.set(fixedByteArray, offset);\n return offset + fixedBytes;\n },\n });\n}\n\n/**\n * Creates a fixed-size decoder from a given decoder.\n *\n * @param decoder - The decoder to wrap into a fixed-size decoder.\n * @param fixedBytes - The fixed number of bytes to read.\n */\nexport function fixDecoder<TTo, TSize extends number>(\n decoder: Decoder<TTo>,\n fixedBytes: TSize,\n): FixedSizeDecoder<TTo, TSize> {\n return createDecoder({\n fixedSize: fixedBytes,\n read: (bytes: Uint8Array, offset: Offset) => {\n assertByteArrayHasEnoughBytesForCodec('fixCodec', fixedBytes, bytes, offset);\n // Slice the byte array to the fixed size if necessary.\n if (offset > 0 || bytes.length > fixedBytes) {\n bytes = bytes.slice(offset, offset + fixedBytes);\n }\n // If the nested decoder is fixed-size, pad and truncate the byte array accordingly.\n if (isFixedSize(decoder)) {\n bytes = fixBytes(bytes, decoder.fixedSize);\n }\n // Decode the value using the nested decoder.\n const [value] = decoder.read(bytes, 0);\n return [value, offset + fixedBytes];\n },\n });\n}\n\n/**\n * Creates a fixed-size codec from a given codec.\n *\n * @param codec - The codec to wrap into a fixed-size codec.\n * @param fixedBytes - The fixed number of bytes to read/write.\n */\nexport function fixCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: Codec<TFrom, TTo>,\n fixedBytes: TSize,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(fixEncoder(codec, fixedBytes), fixDecoder(codec, fixedBytes));\n}\n","import {\n Codec,\n createCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n isVariableSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from './codec';\n\n/**\n * Converts an encoder A to a encoder B by mapping their values.\n */\nexport function mapEncoder<TOldFrom, TNewFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TOldFrom, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeEncoder<TNewFrom, TSize>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: VariableSizeEncoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeEncoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom>;\nexport function mapEncoder<TOldFrom, TNewFrom>(\n encoder: Encoder<TOldFrom>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom> {\n return createEncoder({\n ...(isVariableSize(encoder)\n ? { ...encoder, getSizeFromValue: (value: TNewFrom) => encoder.getSizeFromValue(unmap(value)) }\n : encoder),\n write: (value: TNewFrom, bytes, offset) => encoder.write(unmap(value), bytes, offset),\n });\n}\n\n/**\n * Converts an decoder A to a decoder B by mapping their values.\n */\nexport function mapDecoder<TOldTo, TNewTo, TSize extends number>(\n decoder: FixedSizeDecoder<TOldTo, TSize>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeDecoder<TNewTo, TSize>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: VariableSizeDecoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeDecoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo>;\nexport function mapDecoder<TOldTo, TNewTo>(\n decoder: Decoder<TOldTo>,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo> {\n return createDecoder({\n ...decoder,\n read: (bytes: Uint8Array, offset) => {\n const [value, newOffset] = decoder.read(bytes, offset);\n return [map(value, bytes, offset), newOffset];\n },\n });\n}\n\n/**\n * Converts a codec A to a codec B by mapping their values.\n */\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeCodec<TNewFrom, TTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: VariableSizeCodec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeCodec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n codec: Codec<TOldFrom, TTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n): Codec<TNewFrom, TTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom, TSize extends number>(\n codec: FixedSizeCodec<TOldFrom, TOldTo, TSize>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): FixedSizeCodec<TNewFrom, TNewTo, TSize>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: VariableSizeCodec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): VariableSizeCodec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo>;\nexport function mapCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n codec: Codec<TOldFrom, TOldTo>,\n unmap: (value: TNewFrom) => TOldFrom,\n map?: (value: TOldTo, bytes: Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo> {\n return createCodec({\n ...mapEncoder(codec, unmap),\n read: map ? mapDecoder(codec, map).read : (codec.read as unknown as Decoder<TNewTo>['read']),\n });\n}\n","import {\n isSolanaError,\n SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE,\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\nimport {\n assertIsFixedSize,\n createDecoder,\n createEncoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Reverses the bytes of a fixed-size encoder.\n */\nexport function reverseEncoder<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n try {\n assertIsFixedSize(encoder);\n } catch (e) {\n if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);\n } else {\n throw e;\n }\n }\n return createEncoder({\n ...encoder,\n write: (value: TFrom, bytes, offset) => {\n const newOffset = encoder.write(value, bytes, offset);\n const slice = bytes.slice(offset, offset + encoder.fixedSize).reverse();\n bytes.set(slice, offset);\n return newOffset;\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size decoder.\n */\nexport function reverseDecoder<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n try {\n assertIsFixedSize(decoder);\n } catch (e) {\n if (isSolanaError(e, SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_CANNOT_REVERSE_CODEC_OF_VARIABLE_SIZE);\n } else {\n throw e;\n }\n }\n return createDecoder({\n ...decoder,\n read: (bytes, offset) => {\n const reverseEnd = offset + decoder.fixedSize;\n if (offset === 0 && bytes.length === reverseEnd) {\n return decoder.read(bytes.reverse(), offset);\n }\n const reversedBytes = bytes.slice();\n reversedBytes.set(bytes.slice(offset, reverseEnd).reverse(), offset);\n return decoder.read(reversedBytes, offset);\n },\n });\n}\n\n/**\n * Reverses the bytes of a fixed-size codec.\n */\nexport function reverseCodec<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n"]}