@solana/codecs-data-structures 2.0.0-experimental.efe6f4d → 2.0.0-experimental.f054d90

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.
Files changed (46) hide show
  1. package/README.md +482 -4
  2. package/dist/index.browser.cjs +401 -436
  3. package/dist/index.browser.cjs.map +1 -1
  4. package/dist/index.browser.js +403 -434
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.native.js +403 -434
  7. package/dist/index.native.js.map +1 -1
  8. package/dist/index.node.cjs +401 -436
  9. package/dist/index.node.cjs.map +1 -1
  10. package/dist/index.node.js +403 -434
  11. package/dist/index.node.js.map +1 -1
  12. package/dist/types/array.d.ts +35 -6
  13. package/dist/types/array.d.ts.map +1 -1
  14. package/dist/types/assertions.d.ts.map +1 -1
  15. package/dist/types/bit-array.d.ts +5 -5
  16. package/dist/types/bit-array.d.ts.map +1 -1
  17. package/dist/types/boolean.d.ts +18 -6
  18. package/dist/types/boolean.d.ts.map +1 -1
  19. package/dist/types/bytes.d.ts +14 -5
  20. package/dist/types/bytes.d.ts.map +1 -1
  21. package/dist/types/data-enum.d.ts +18 -20
  22. package/dist/types/data-enum.d.ts.map +1 -1
  23. package/dist/types/index.d.ts +13 -14
  24. package/dist/types/index.d.ts.map +1 -1
  25. package/dist/types/map.d.ts +24 -6
  26. package/dist/types/map.d.ts.map +1 -1
  27. package/dist/types/nullable.d.ts +24 -6
  28. package/dist/types/nullable.d.ts.map +1 -1
  29. package/dist/types/scalar-enum.d.ts +42 -11
  30. package/dist/types/scalar-enum.d.ts.map +1 -1
  31. package/dist/types/set.d.ts +24 -6
  32. package/dist/types/set.d.ts.map +1 -1
  33. package/dist/types/struct.d.ts +16 -21
  34. package/dist/types/struct.d.ts.map +1 -1
  35. package/dist/types/tuple.d.ts +22 -15
  36. package/dist/types/tuple.d.ts.map +1 -1
  37. package/dist/types/unit.d.ts +4 -12
  38. package/dist/types/unit.d.ts.map +1 -1
  39. package/dist/types/utils.d.ts +10 -2
  40. package/dist/types/utils.d.ts.map +1 -1
  41. package/package.json +13 -34
  42. package/dist/index.development.js +0 -865
  43. package/dist/index.development.js.map +0 -1
  44. package/dist/index.production.min.js +0 -51
  45. package/dist/types/array-like-codec-size.d.ts +0 -20
  46. package/dist/types/array-like-codec-size.d.ts.map +0 -1
@@ -2,10 +2,18 @@
2
2
 
3
3
  var codecsCore = require('@solana/codecs-core');
4
4
  var codecsNumbers = require('@solana/codecs-numbers');
5
+ var errors = require('@solana/errors');
5
6
 
6
7
  // src/array.ts
7
-
8
- // src/utils.ts
8
+ function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
9
+ if (expected !== actual) {
10
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_WRONG_NUMBER_OF_ITEMS, {
11
+ actual,
12
+ codecDescription,
13
+ expected
14
+ });
15
+ }
16
+ }
9
17
  function maxCodecSizes(sizes) {
10
18
  return sizes.reduce(
11
19
  (all, size) => all === null || size === null ? null : Math.max(all, size),
@@ -15,106 +23,88 @@ function maxCodecSizes(sizes) {
15
23
  function sumCodecSizes(sizes) {
16
24
  return sizes.reduce((all, size) => all === null || size === null ? null : all + size, 0);
17
25
  }
18
-
19
- // src/array-like-codec-size.ts
20
- function decodeArrayLikeCodecSize(size, childrenSizes, bytes, offset) {
21
- if (typeof size === "number") {
22
- return [size, offset];
23
- }
24
- if (typeof size === "object") {
25
- return size.decode(bytes, offset);
26
- }
27
- if (size === "remainder") {
28
- const childrenSize = sumCodecSizes(childrenSizes);
29
- if (childrenSize === null) {
30
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
31
- }
32
- const remainder = bytes.slice(offset).length;
33
- if (remainder % childrenSize !== 0) {
34
- throw new Error(
35
- `The remainder of the byte array (${remainder} bytes) cannot be split into chunks of ${childrenSize} bytes. Codecs of "remainder" size must have a remainder that is a multiple of its item size. In other words, ${remainder} modulo ${childrenSize} should be equal to zero.`
36
- );
37
- }
38
- return [remainder / childrenSize, offset];
39
- }
40
- throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
41
- }
42
- function getArrayLikeCodecSizeDescription(size) {
43
- return typeof size === "object" ? size.description : `${size}`;
44
- }
45
- function getArrayLikeCodecSizeFromChildren(size, childrenSizes) {
46
- if (typeof size !== "number")
47
- return null;
48
- if (size === 0)
49
- return 0;
50
- const childrenSize = sumCodecSizes(childrenSizes);
51
- return childrenSize === null ? null : childrenSize * size;
26
+ function getFixedSize(codec) {
27
+ return codecsCore.isFixedSize(codec) ? codec.fixedSize : null;
52
28
  }
53
- function getArrayLikeCodecSizePrefix(size, realSize) {
54
- return typeof size === "object" ? size.encode(realSize) : new Uint8Array();
55
- }
56
-
57
- // src/assertions.ts
58
- function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
59
- if (expected !== actual) {
60
- throw new Error(`Expected [${codecDescription}] to have ${expected} items, got ${actual}.`);
61
- }
29
+ function getMaxSize(codec) {
30
+ return codecsCore.isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;
62
31
  }
63
32
 
64
33
  // src/array.ts
65
- function arrayCodecHelper(item, size, description) {
66
- if (size === "remainder" && item.fixedSize === null) {
67
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
68
- }
69
- return {
70
- description: description ?? `array(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`,
71
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]),
72
- maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize])
73
- };
74
- }
75
34
  function getArrayEncoder(item, config = {}) {
76
35
  const size = config.size ?? codecsNumbers.getU32Encoder();
77
- return {
78
- ...arrayCodecHelper(item, size, config.description),
79
- encode: (value) => {
36
+ const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));
37
+ const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
38
+ return codecsCore.createEncoder({
39
+ ...fixedSize !== null ? { fixedSize } : {
40
+ getSizeFromValue: (array) => {
41
+ const prefixSize = typeof size === "object" ? codecsCore.getEncodedSize(array.length, size) : 0;
42
+ return prefixSize + [...array].reduce((all, value) => all + codecsCore.getEncodedSize(value, item), 0);
43
+ },
44
+ maxSize
45
+ },
46
+ write: (array, bytes, offset) => {
80
47
  if (typeof size === "number") {
81
- assertValidNumberOfItemsForCodec("array", size, value.length);
48
+ assertValidNumberOfItemsForCodec("array", size, array.length);
49
+ }
50
+ if (typeof size === "object") {
51
+ offset = size.write(array.length, bytes, offset);
82
52
  }
83
- return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, value.length), ...value.map((v) => item.encode(v))]);
53
+ array.forEach((value) => {
54
+ offset = item.write(value, bytes, offset);
55
+ });
56
+ return offset;
84
57
  }
85
- };
58
+ });
86
59
  }
87
60
  function getArrayDecoder(item, config = {}) {
88
61
  const size = config.size ?? codecsNumbers.getU32Decoder();
89
- return {
90
- ...arrayCodecHelper(item, size, config.description),
91
- decode: (bytes, offset = 0) => {
62
+ const itemSize = getFixedSize(item);
63
+ const fixedSize = computeArrayLikeCodecSize(size, itemSize);
64
+ const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? void 0;
65
+ return codecsCore.createDecoder({
66
+ ...fixedSize !== null ? { fixedSize } : { maxSize },
67
+ read: (bytes, offset) => {
68
+ const array = [];
92
69
  if (typeof size === "object" && bytes.slice(offset).length === 0) {
93
- return [[], offset];
70
+ return [array, offset];
71
+ }
72
+ if (size === "remainder") {
73
+ while (offset < bytes.length) {
74
+ const [value, newOffset2] = item.read(bytes, offset);
75
+ offset = newOffset2;
76
+ array.push(value);
77
+ }
78
+ return [array, offset];
94
79
  }
95
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
80
+ const [resolvedSize, newOffset] = typeof size === "number" ? [size, offset] : size.read(bytes, offset);
96
81
  offset = newOffset;
97
- const values = [];
98
82
  for (let i = 0; i < resolvedSize; i += 1) {
99
- const [value, newOffset2] = item.decode(bytes, offset);
100
- values.push(value);
83
+ const [value, newOffset2] = item.read(bytes, offset);
101
84
  offset = newOffset2;
85
+ array.push(value);
102
86
  }
103
- return [values, offset];
87
+ return [array, offset];
104
88
  }
105
- };
89
+ });
106
90
  }
107
91
  function getArrayCodec(item, config = {}) {
108
92
  return codecsCore.combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
109
93
  }
110
- var getBitArrayEncoder = (size, config = {}) => {
94
+ function computeArrayLikeCodecSize(size, itemSize) {
95
+ if (typeof size !== "number")
96
+ return null;
97
+ if (size === 0)
98
+ return 0;
99
+ return itemSize === null ? null : itemSize * size;
100
+ }
101
+ function getBitArrayEncoder(size, config = {}) {
111
102
  const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
112
103
  const backward = parsedConfig.backward ?? false;
113
- const backwardSuffix = backward ? "; backward" : "";
114
- return {
115
- description: parsedConfig.description ?? `bitArray(${size}${backwardSuffix})`,
116
- encode(value) {
117
- const bytes = [];
104
+ return codecsCore.createEncoder({
105
+ fixedSize: size,
106
+ write(value, bytes, offset) {
107
+ const bytesToAdd = [];
118
108
  for (let i = 0; i < size; i += 1) {
119
109
  let byte = 0;
120
110
  for (let j = 0; j < 8; j += 1) {
@@ -122,23 +112,22 @@ var getBitArrayEncoder = (size, config = {}) => {
122
112
  byte |= feature << (backward ? j : 7 - j);
123
113
  }
124
114
  if (backward) {
125
- bytes.unshift(byte);
115
+ bytesToAdd.unshift(byte);
126
116
  } else {
127
- bytes.push(byte);
117
+ bytesToAdd.push(byte);
128
118
  }
129
119
  }
130
- return new Uint8Array(bytes);
131
- },
132
- fixedSize: size,
133
- maxSize: size
134
- };
135
- };
136
- var getBitArrayDecoder = (size, config = {}) => {
120
+ bytes.set(bytesToAdd, offset);
121
+ return size;
122
+ }
123
+ });
124
+ }
125
+ function getBitArrayDecoder(size, config = {}) {
137
126
  const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
138
127
  const backward = parsedConfig.backward ?? false;
139
- const backwardSuffix = backward ? "; backward" : "";
140
- return {
141
- decode(bytes, offset = 0) {
128
+ return codecsCore.createDecoder({
129
+ fixedSize: size,
130
+ read(bytes, offset) {
142
131
  codecsCore.assertByteArrayHasEnoughBytesForCodec("bitArray", size, bytes, offset);
143
132
  const booleans = [];
144
133
  let slice = bytes.slice(offset, offset + size);
@@ -155,476 +144,452 @@ var getBitArrayDecoder = (size, config = {}) => {
155
144
  }
156
145
  });
157
146
  return [booleans, offset + size];
158
- },
159
- description: parsedConfig.description ?? `bitArray(${size}${backwardSuffix})`,
160
- fixedSize: size,
161
- maxSize: size
162
- };
163
- };
164
- var getBitArrayCodec = (size, config = {}) => codecsCore.combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
147
+ }
148
+ });
149
+ }
150
+ function getBitArrayCodec(size, config = {}) {
151
+ return codecsCore.combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
152
+ }
165
153
  function getBooleanEncoder(config = {}) {
166
154
  const size = config.size ?? codecsNumbers.getU8Encoder();
167
- codecsCore.assertFixedSizeCodec(size, "Codec [bool] requires a fixed size.");
168
- return {
169
- description: config.description ?? `bool(${size.description})`,
170
- encode: (value) => size.encode(value ? 1 : 0),
171
- fixedSize: size.fixedSize,
172
- maxSize: size.fixedSize
173
- };
155
+ try {
156
+ codecsCore.assertIsFixedSize(size);
157
+ } catch (e) {
158
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
159
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
160
+ codecDescription: "bool"
161
+ });
162
+ } else {
163
+ throw e;
164
+ }
165
+ }
166
+ return codecsCore.mapEncoder(size, (value) => value ? 1 : 0);
174
167
  }
175
168
  function getBooleanDecoder(config = {}) {
176
169
  const size = config.size ?? codecsNumbers.getU8Decoder();
177
- codecsCore.assertFixedSizeCodec(size, "Codec [bool] requires a fixed size.");
178
- return {
179
- decode: (bytes, offset = 0) => {
180
- codecsCore.assertByteArrayIsNotEmptyForCodec("bool", bytes, offset);
181
- const [value, vOffset] = size.decode(bytes, offset);
182
- return [value === 1, vOffset];
183
- },
184
- description: config.description ?? `bool(${size.description})`,
185
- fixedSize: size.fixedSize,
186
- maxSize: size.fixedSize
187
- };
170
+ try {
171
+ codecsCore.assertIsFixedSize(size);
172
+ } catch (e) {
173
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
174
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_CODEC_REQUIRES_FIXED_SIZE, {
175
+ codecDescription: "bool"
176
+ });
177
+ } else {
178
+ throw e;
179
+ }
180
+ }
181
+ return codecsCore.mapDecoder(size, (value) => Number(value) === 1);
188
182
  }
189
183
  function getBooleanCodec(config = {}) {
190
184
  return codecsCore.combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
191
185
  }
192
186
  function getBytesEncoder(config = {}) {
193
187
  const size = config.size ?? "variable";
194
- const sizeDescription = typeof size === "object" ? size.description : `${size}`;
195
- const description = config.description ?? `bytes(${sizeDescription})`;
196
- const byteEncoder = {
197
- description,
198
- encode: (value) => value,
199
- fixedSize: null,
200
- maxSize: null
201
- };
188
+ const byteEncoder = codecsCore.createEncoder({
189
+ getSizeFromValue: (value) => value.length,
190
+ write: (value, bytes, offset) => {
191
+ bytes.set(value, offset);
192
+ return offset + value.length;
193
+ }
194
+ });
202
195
  if (size === "variable") {
203
196
  return byteEncoder;
204
197
  }
205
198
  if (typeof size === "number") {
206
- return codecsCore.fixEncoder(byteEncoder, size, description);
199
+ return codecsCore.fixEncoder(byteEncoder, size);
207
200
  }
208
- return {
209
- ...byteEncoder,
210
- encode: (value) => {
211
- const contentBytes = byteEncoder.encode(value);
212
- const lengthBytes = size.encode(contentBytes.length);
213
- return codecsCore.mergeBytes([lengthBytes, contentBytes]);
201
+ return codecsCore.createEncoder({
202
+ getSizeFromValue: (value) => codecsCore.getEncodedSize(value.length, size) + value.length,
203
+ write: (value, bytes, offset) => {
204
+ offset = size.write(value.length, bytes, offset);
205
+ return byteEncoder.write(value, bytes, offset);
214
206
  }
215
- };
207
+ });
216
208
  }
217
209
  function getBytesDecoder(config = {}) {
218
210
  const size = config.size ?? "variable";
219
- const sizeDescription = typeof size === "object" ? size.description : `${size}`;
220
- const description = config.description ?? `bytes(${sizeDescription})`;
221
- const byteDecoder = {
222
- decode: (bytes, offset = 0) => {
211
+ const byteDecoder = codecsCore.createDecoder({
212
+ read: (bytes, offset) => {
223
213
  const slice = bytes.slice(offset);
224
214
  return [slice, offset + slice.length];
225
- },
226
- description,
227
- fixedSize: null,
228
- maxSize: null
229
- };
215
+ }
216
+ });
230
217
  if (size === "variable") {
231
218
  return byteDecoder;
232
219
  }
233
220
  if (typeof size === "number") {
234
- return codecsCore.fixDecoder(byteDecoder, size, description);
221
+ return codecsCore.fixDecoder(byteDecoder, size);
235
222
  }
236
- return {
237
- ...byteDecoder,
238
- decode: (bytes, offset = 0) => {
223
+ return codecsCore.createDecoder({
224
+ read: (bytes, offset) => {
239
225
  codecsCore.assertByteArrayIsNotEmptyForCodec("bytes", bytes, offset);
240
- const [lengthBigInt, lengthOffset] = size.decode(bytes, offset);
226
+ const [lengthBigInt, lengthOffset] = size.read(bytes, offset);
241
227
  const length = Number(lengthBigInt);
242
228
  offset = lengthOffset;
243
229
  const contentBytes = bytes.slice(offset, offset + length);
244
230
  codecsCore.assertByteArrayHasEnoughBytesForCodec("bytes", length, contentBytes);
245
- const [value, contentOffset] = byteDecoder.decode(contentBytes);
231
+ const [value, contentOffset] = byteDecoder.read(contentBytes, 0);
246
232
  offset += contentOffset;
247
233
  return [value, offset];
248
234
  }
249
- };
235
+ });
250
236
  }
251
237
  function getBytesCodec(config = {}) {
252
238
  return codecsCore.combineCodec(getBytesEncoder(config), getBytesDecoder(config));
253
239
  }
254
- function dataEnumCodecHelper(variants, prefix, description) {
255
- const fieldDescriptions = variants.map(([name, codec]) => `${String(name)}${codec ? `: ${codec.description}` : ""}`).join(", ");
256
- const allVariantHaveTheSameFixedSize = variants.every((one, _i, all) => one[1].fixedSize === all[0][1].fixedSize);
257
- const fixedVariantSize = allVariantHaveTheSameFixedSize ? variants[0][1].fixedSize : null;
258
- const maxVariantSize = maxCodecSizes(variants.map(([, field]) => field.maxSize));
259
- return {
260
- description: description ?? `dataEnum(${fieldDescriptions}; ${prefix.description})`,
261
- fixedSize: variants.length === 0 ? prefix.fixedSize : sumCodecSizes([prefix.fixedSize, fixedVariantSize]),
262
- maxSize: variants.length === 0 ? prefix.maxSize : sumCodecSizes([prefix.maxSize, maxVariantSize])
263
- };
264
- }
265
240
  function getDataEnumEncoder(variants, config = {}) {
266
241
  const prefix = config.size ?? codecsNumbers.getU8Encoder();
267
- return {
268
- ...dataEnumCodecHelper(variants, prefix, config.description),
269
- encode: (variant) => {
270
- const discriminator = variants.findIndex(([key]) => variant.__kind === key);
271
- if (discriminator < 0) {
272
- throw new Error(
273
- `Invalid data enum variant. Expected one of [${variants.map(([key]) => key).join(", ")}], got "${variant.__kind}".`
274
- );
275
- }
276
- const variantPrefix = prefix.encode(discriminator);
277
- const variantSerializer = variants[discriminator][1];
278
- const variantBytes = variantSerializer.encode(variant);
279
- return codecsCore.mergeBytes([variantPrefix, variantBytes]);
242
+ const fixedSize = getDataEnumFixedSize(variants, prefix);
243
+ return codecsCore.createEncoder({
244
+ ...fixedSize !== null ? { fixedSize } : {
245
+ getSizeFromValue: (variant) => {
246
+ const discriminator = getVariantDiscriminator(variants, variant);
247
+ const variantEncoder = variants[discriminator][1];
248
+ return codecsCore.getEncodedSize(discriminator, prefix) + codecsCore.getEncodedSize(variant, variantEncoder);
249
+ },
250
+ maxSize: getDataEnumMaxSize(variants, prefix)
251
+ },
252
+ write: (variant, bytes, offset) => {
253
+ const discriminator = getVariantDiscriminator(variants, variant);
254
+ offset = prefix.write(discriminator, bytes, offset);
255
+ const variantEncoder = variants[discriminator][1];
256
+ return variantEncoder.write(variant, bytes, offset);
280
257
  }
281
- };
258
+ });
282
259
  }
283
260
  function getDataEnumDecoder(variants, config = {}) {
284
261
  const prefix = config.size ?? codecsNumbers.getU8Decoder();
285
- return {
286
- ...dataEnumCodecHelper(variants, prefix, config.description),
287
- decode: (bytes, offset = 0) => {
262
+ const fixedSize = getDataEnumFixedSize(variants, prefix);
263
+ return codecsCore.createDecoder({
264
+ ...fixedSize !== null ? { fixedSize } : { maxSize: getDataEnumMaxSize(variants, prefix) },
265
+ read: (bytes, offset) => {
288
266
  codecsCore.assertByteArrayIsNotEmptyForCodec("dataEnum", bytes, offset);
289
- const [discriminator, dOffset] = prefix.decode(bytes, offset);
267
+ const [discriminator, dOffset] = prefix.read(bytes, offset);
290
268
  offset = dOffset;
291
269
  const variantField = variants[Number(discriminator)] ?? null;
292
270
  if (!variantField) {
293
- throw new Error(
294
- `Enum discriminator out of range. Expected a number between 0 and ${variants.length - 1}, got ${discriminator}.`
295
- );
271
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
272
+ discriminator,
273
+ maxRange: variants.length - 1,
274
+ minRange: 0
275
+ });
296
276
  }
297
- const [variant, vOffset] = variantField[1].decode(bytes, offset);
277
+ const [variant, vOffset] = variantField[1].read(bytes, offset);
298
278
  offset = vOffset;
299
279
  return [{ __kind: variantField[0], ...variant ?? {} }, offset];
300
280
  }
301
- };
281
+ });
302
282
  }
303
283
  function getDataEnumCodec(variants, config = {}) {
304
- return codecsCore.combineCodec(getDataEnumEncoder(variants, config), getDataEnumDecoder(variants, config));
284
+ return codecsCore.combineCodec(
285
+ getDataEnumEncoder(variants, config),
286
+ getDataEnumDecoder(variants, config)
287
+ );
305
288
  }
306
- function mapCodecHelper(key, value, size, description) {
307
- if (size === "remainder" && (key.fixedSize === null || value.fixedSize === null)) {
308
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
289
+ function getDataEnumFixedSize(variants, prefix) {
290
+ if (variants.length === 0)
291
+ return codecsCore.isFixedSize(prefix) ? prefix.fixedSize : null;
292
+ if (!codecsCore.isFixedSize(variants[0][1]))
293
+ return null;
294
+ const variantSize = variants[0][1].fixedSize;
295
+ const sameSizedVariants = variants.every(
296
+ (variant) => codecsCore.isFixedSize(variant[1]) && variant[1].fixedSize === variantSize
297
+ );
298
+ if (!sameSizedVariants)
299
+ return null;
300
+ return codecsCore.isFixedSize(prefix) ? prefix.fixedSize + variantSize : null;
301
+ }
302
+ function getDataEnumMaxSize(variants, prefix) {
303
+ const maxVariantSize = maxCodecSizes(variants.map(([, codec]) => getMaxSize(codec)));
304
+ return sumCodecSizes([getMaxSize(prefix), maxVariantSize]) ?? void 0;
305
+ }
306
+ function getVariantDiscriminator(variants, variant) {
307
+ const discriminator = variants.findIndex(([key]) => variant.__kind === key);
308
+ if (discriminator < 0) {
309
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_DATA_ENUM_VARIANT, {
310
+ value: variant.__kind,
311
+ variants: variants.map(([key]) => key)
312
+ });
309
313
  }
310
- return {
311
- description: description ?? `map(${key.description}, ${value.description}; ${getArrayLikeCodecSizeDescription(size)})`,
312
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [key.fixedSize, value.fixedSize]),
313
- maxSize: getArrayLikeCodecSizeFromChildren(size, [key.maxSize, value.maxSize])
314
- };
314
+ return discriminator;
315
+ }
316
+ function getTupleEncoder(items) {
317
+ const fixedSize = sumCodecSizes(items.map(getFixedSize));
318
+ const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
319
+ return codecsCore.createEncoder({
320
+ ...fixedSize === null ? {
321
+ getSizeFromValue: (value) => items.map((item, index) => codecsCore.getEncodedSize(value[index], item)).reduce((all, one) => all + one, 0),
322
+ maxSize
323
+ } : { fixedSize },
324
+ write: (value, bytes, offset) => {
325
+ assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
326
+ items.forEach((item, index) => {
327
+ offset = item.write(value[index], bytes, offset);
328
+ });
329
+ return offset;
330
+ }
331
+ });
332
+ }
333
+ function getTupleDecoder(items) {
334
+ const fixedSize = sumCodecSizes(items.map(getFixedSize));
335
+ const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? void 0;
336
+ return codecsCore.createDecoder({
337
+ ...fixedSize === null ? { maxSize } : { fixedSize },
338
+ read: (bytes, offset) => {
339
+ const values = [];
340
+ items.forEach((item) => {
341
+ const [newValue, newOffset] = item.read(bytes, offset);
342
+ values.push(newValue);
343
+ offset = newOffset;
344
+ });
345
+ return [values, offset];
346
+ }
347
+ });
315
348
  }
349
+ function getTupleCodec(items) {
350
+ return codecsCore.combineCodec(
351
+ getTupleEncoder(items),
352
+ getTupleDecoder(items)
353
+ );
354
+ }
355
+
356
+ // src/map.ts
316
357
  function getMapEncoder(key, value, config = {}) {
317
- const size = config.size ?? codecsNumbers.getU32Encoder();
318
- return {
319
- ...mapCodecHelper(key, value, size, config.description),
320
- encode: (map) => {
321
- if (typeof size === "number") {
322
- assertValidNumberOfItemsForCodec("map", size, map.size);
323
- }
324
- const itemBytes = Array.from(map, ([k, v]) => codecsCore.mergeBytes([key.encode(k), value.encode(v)]));
325
- return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, map.size), ...itemBytes]);
326
- }
327
- };
358
+ return codecsCore.mapEncoder(
359
+ getArrayEncoder(getTupleEncoder([key, value]), config),
360
+ (map) => [...map.entries()]
361
+ );
328
362
  }
329
363
  function getMapDecoder(key, value, config = {}) {
330
- const size = config.size ?? codecsNumbers.getU32Decoder();
331
- return {
332
- ...mapCodecHelper(key, value, size, config.description),
333
- decode: (bytes, offset = 0) => {
334
- const map = /* @__PURE__ */ new Map();
335
- if (typeof size === "object" && bytes.slice(offset).length === 0) {
336
- return [map, offset];
337
- }
338
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(
339
- size,
340
- [key.fixedSize, value.fixedSize],
341
- bytes,
342
- offset
343
- );
344
- offset = newOffset;
345
- for (let i = 0; i < resolvedSize; i += 1) {
346
- const [decodedKey, kOffset] = key.decode(bytes, offset);
347
- offset = kOffset;
348
- const [decodedValue, vOffset] = value.decode(bytes, offset);
349
- offset = vOffset;
350
- map.set(decodedKey, decodedValue);
351
- }
352
- return [map, offset];
353
- }
354
- };
364
+ return codecsCore.mapDecoder(
365
+ getArrayDecoder(getTupleDecoder([key, value]), config),
366
+ (entries) => new Map(entries)
367
+ );
355
368
  }
356
369
  function getMapCodec(key, value, config = {}) {
357
370
  return codecsCore.combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
358
371
  }
359
- function nullableCodecHelper(item, prefix, fixed, description) {
360
- let descriptionSuffix = `; ${prefix.description}`;
361
- let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;
362
- if (fixed) {
363
- codecsCore.assertFixedSizeCodec(item, "Fixed nullables can only be used with fixed-size codecs.");
364
- codecsCore.assertFixedSizeCodec(prefix, "Fixed nullables can only be used with fixed-size prefix.");
365
- descriptionSuffix += "; fixed";
366
- fixedSize = prefix.fixedSize + item.fixedSize;
367
- }
368
- return {
369
- description: description ?? `nullable(${item.description + descriptionSuffix})`,
370
- fixedSize,
371
- maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
372
- };
373
- }
374
372
  function getNullableEncoder(item, config = {}) {
375
373
  const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
376
374
  const fixed = config.fixed ?? false;
377
- return {
378
- ...nullableCodecHelper(item, prefix, fixed, config.description),
379
- encode: (option) => {
380
- const prefixByte = prefix.encode(Number(option !== null));
381
- let itemBytes = option !== null ? item.encode(option) : new Uint8Array();
382
- itemBytes = fixed ? codecsCore.fixBytes(itemBytes, item.fixedSize) : itemBytes;
383
- return codecsCore.mergeBytes([prefixByte, itemBytes]);
375
+ const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
376
+ if (fixed || isZeroSizeItem) {
377
+ try {
378
+ codecsCore.assertIsFixedSize(item);
379
+ } catch (e) {
380
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
381
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
382
+ } else {
383
+ throw e;
384
+ }
384
385
  }
385
- };
386
+ try {
387
+ codecsCore.assertIsFixedSize(prefix);
388
+ } catch (e) {
389
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
390
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
391
+ } else {
392
+ throw e;
393
+ }
394
+ }
395
+ const fixedSize = prefix.fixedSize + item.fixedSize;
396
+ return codecsCore.createEncoder({
397
+ fixedSize,
398
+ write: (option, bytes, offset) => {
399
+ const prefixOffset = prefix.write(Number(option !== null), bytes, offset);
400
+ if (option !== null) {
401
+ item.write(option, bytes, prefixOffset);
402
+ }
403
+ return offset + fixedSize;
404
+ }
405
+ });
406
+ }
407
+ return codecsCore.createEncoder({
408
+ getSizeFromValue: (option) => codecsCore.getEncodedSize(Number(option !== null), prefix) + (option !== null ? codecsCore.getEncodedSize(option, item) : 0),
409
+ maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? void 0,
410
+ write: (option, bytes, offset) => {
411
+ offset = prefix.write(Number(option !== null), bytes, offset);
412
+ if (option !== null) {
413
+ offset = item.write(option, bytes, offset);
414
+ }
415
+ return offset;
416
+ }
417
+ });
386
418
  }
387
419
  function getNullableDecoder(item, config = {}) {
388
420
  const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
389
421
  const fixed = config.fixed ?? false;
390
- return {
391
- ...nullableCodecHelper(item, prefix, fixed, config.description),
392
- decode: (bytes, offset = 0) => {
422
+ let fixedSize = null;
423
+ const isZeroSizeItem = codecsCore.isFixedSize(item) && codecsCore.isFixedSize(prefix) && item.fixedSize === 0;
424
+ if (fixed || isZeroSizeItem) {
425
+ try {
426
+ codecsCore.assertIsFixedSize(item);
427
+ } catch (e) {
428
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
429
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_CODEC);
430
+ } else {
431
+ throw e;
432
+ }
433
+ }
434
+ try {
435
+ codecsCore.assertIsFixedSize(prefix);
436
+ } catch (e) {
437
+ if (errors.isSolanaError(e, errors.SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH)) {
438
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_FIXED_NULLABLE_WITH_VARIABLE_SIZE_PREFIX);
439
+ } else {
440
+ throw e;
441
+ }
442
+ }
443
+ fixedSize = prefix.fixedSize + item.fixedSize;
444
+ }
445
+ return codecsCore.createDecoder({
446
+ ...fixedSize === null ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? void 0 } : { fixedSize },
447
+ read: (bytes, offset) => {
393
448
  if (bytes.length - offset <= 0) {
394
449
  return [null, offset];
395
450
  }
396
- const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);
397
- const [isSome, prefixOffset] = prefix.decode(bytes, offset);
398
- offset = prefixOffset;
451
+ const [isSome, prefixOffset] = prefix.read(bytes, offset);
399
452
  if (isSome === 0) {
400
- return [null, fixed ? fixedOffset : offset];
453
+ return [null, fixedSize !== null ? offset + fixedSize : prefixOffset];
401
454
  }
402
- const [value, newOffset] = item.decode(bytes, offset);
403
- offset = newOffset;
404
- return [value, fixed ? fixedOffset : offset];
455
+ const [value, newOffset] = item.read(bytes, prefixOffset);
456
+ return [value, fixedSize !== null ? offset + fixedSize : newOffset];
405
457
  }
406
- };
458
+ });
407
459
  }
408
460
  function getNullableCodec(item, config = {}) {
409
- return codecsCore.combineCodec(getNullableEncoder(item, config), getNullableDecoder(item, config));
410
- }
411
- function scalarEnumCoderHelper(constructor, prefix, description) {
412
- const enumKeys = Object.keys(constructor);
413
- const enumValues = Object.values(constructor);
414
- const isNumericEnum = enumValues.some((v) => typeof v === "number");
415
- const valueDescriptions = enumValues.filter((v) => typeof v === "string").join(", ");
416
- const minRange = 0;
417
- const maxRange = isNumericEnum ? enumValues.length / 2 - 1 : enumValues.length - 1;
418
- const stringValues = isNumericEnum ? [...enumKeys] : [.../* @__PURE__ */ new Set([...enumKeys, ...enumValues])];
419
- return {
420
- description: description ?? `enum(${valueDescriptions}; ${prefix.description})`,
421
- enumKeys,
422
- enumValues,
423
- fixedSize: prefix.fixedSize,
424
- isNumericEnum,
425
- maxRange,
426
- maxSize: prefix.maxSize,
427
- minRange,
428
- stringValues
429
- };
461
+ const configCast = config;
462
+ return codecsCore.combineCodec(getNullableEncoder(item, configCast), getNullableDecoder(item, configCast));
430
463
  }
431
464
  function getScalarEnumEncoder(constructor, config = {}) {
432
465
  const prefix = config.size ?? codecsNumbers.getU8Encoder();
433
- const { description, fixedSize, maxSize, minRange, maxRange, stringValues, enumKeys, enumValues } = scalarEnumCoderHelper(constructor, prefix, config.description);
434
- return {
435
- description,
436
- encode: (value) => {
437
- const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
438
- const isInvalidString = typeof value === "string" && !stringValues.includes(value);
439
- if (isInvalidNumber || isInvalidString) {
440
- throw new Error(
441
- `Invalid scalar enum variant. Expected one of [${stringValues.join(", ")}] or a number between ${minRange} and ${maxRange}, got "${value}".`
442
- );
443
- }
444
- if (typeof value === "number")
445
- return prefix.encode(value);
446
- const valueIndex = enumValues.indexOf(value);
447
- if (valueIndex >= 0)
448
- return prefix.encode(valueIndex);
449
- return prefix.encode(enumKeys.indexOf(value));
450
- },
451
- fixedSize,
452
- maxSize
453
- };
466
+ const { minRange, maxRange, allStringInputs, enumKeys, enumValues } = getScalarEnumStats(constructor);
467
+ return codecsCore.mapEncoder(prefix, (value) => {
468
+ const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
469
+ const isInvalidString = typeof value === "string" && !allStringInputs.includes(value);
470
+ if (isInvalidNumber || isInvalidString) {
471
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_SCALAR_ENUM_VARIANT, {
472
+ maxRange,
473
+ minRange,
474
+ value,
475
+ variants: allStringInputs
476
+ });
477
+ }
478
+ if (typeof value === "number")
479
+ return value;
480
+ const valueIndex = enumValues.indexOf(value);
481
+ if (valueIndex >= 0)
482
+ return valueIndex;
483
+ return enumKeys.indexOf(value);
484
+ });
454
485
  }
455
486
  function getScalarEnumDecoder(constructor, config = {}) {
456
487
  const prefix = config.size ?? codecsNumbers.getU8Decoder();
457
- const { description, fixedSize, maxSize, minRange, maxRange, isNumericEnum, enumValues } = scalarEnumCoderHelper(
458
- constructor,
459
- prefix,
460
- config.description
461
- );
462
- return {
463
- decode: (bytes, offset = 0) => {
464
- codecsCore.assertByteArrayIsNotEmptyForCodec("enum", bytes, offset);
465
- const [value, newOffset] = prefix.decode(bytes, offset);
466
- const valueAsNumber = Number(value);
467
- offset = newOffset;
468
- if (valueAsNumber < minRange || valueAsNumber > maxRange) {
469
- throw new Error(
470
- `Enum discriminator out of range. Expected a number between ${minRange} and ${maxRange}, got ${valueAsNumber}.`
471
- );
472
- }
473
- return [isNumericEnum ? valueAsNumber : enumValues[valueAsNumber], offset];
474
- },
475
- description,
476
- fixedSize,
477
- maxSize
478
- };
488
+ const { minRange, maxRange, enumKeys } = getScalarEnumStats(constructor);
489
+ return codecsCore.mapDecoder(prefix, (value) => {
490
+ const valueAsNumber = Number(value);
491
+ if (valueAsNumber < minRange || valueAsNumber > maxRange) {
492
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_ENUM_DISCRIMINATOR_OUT_OF_RANGE, {
493
+ discriminator: valueAsNumber,
494
+ maxRange,
495
+ minRange
496
+ });
497
+ }
498
+ return constructor[enumKeys[valueAsNumber]];
499
+ });
479
500
  }
480
501
  function getScalarEnumCodec(constructor, config = {}) {
481
502
  return codecsCore.combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
482
503
  }
483
- function setCodecHelper(item, size, description) {
484
- if (size === "remainder" && item.fixedSize === null) {
485
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
486
- }
504
+ function getScalarEnumStats(constructor) {
505
+ const numericValues = Object.values(constructor).filter((v) => typeof v === "number");
506
+ const deduplicatedConstructor = Object.fromEntries(
507
+ Object.entries(constructor).slice(numericValues.length)
508
+ );
509
+ const enumKeys = Object.keys(deduplicatedConstructor);
510
+ const enumValues = Object.values(deduplicatedConstructor);
511
+ const minRange = 0;
512
+ const maxRange = enumValues.length - 1;
513
+ const allStringInputs = [
514
+ .../* @__PURE__ */ new Set([...enumKeys, ...enumValues.filter((v) => typeof v === "string")])
515
+ ];
487
516
  return {
488
- description: description ?? `set(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`,
489
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]),
490
- maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize])
517
+ allStringInputs,
518
+ enumKeys,
519
+ enumValues,
520
+ maxRange,
521
+ minRange
491
522
  };
492
523
  }
493
524
  function getSetEncoder(item, config = {}) {
494
- const size = config.size ?? codecsNumbers.getU32Encoder();
495
- return {
496
- ...setCodecHelper(item, size, config.description),
497
- encode: (set) => {
498
- if (typeof size === "number" && set.size !== size) {
499
- assertValidNumberOfItemsForCodec("set", size, set.size);
500
- }
501
- const itemBytes = Array.from(set, (value) => item.encode(value));
502
- return codecsCore.mergeBytes([getArrayLikeCodecSizePrefix(size, set.size), ...itemBytes]);
503
- }
504
- };
525
+ return codecsCore.mapEncoder(getArrayEncoder(item, config), (set) => [...set]);
505
526
  }
506
527
  function getSetDecoder(item, config = {}) {
507
- const size = config.size ?? codecsNumbers.getU32Decoder();
508
- return {
509
- ...setCodecHelper(item, size, config.description),
510
- decode: (bytes, offset = 0) => {
511
- const set = /* @__PURE__ */ new Set();
512
- if (typeof size === "object" && bytes.slice(offset).length === 0) {
513
- return [set, offset];
514
- }
515
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
516
- offset = newOffset;
517
- for (let i = 0; i < resolvedSize; i += 1) {
518
- const [value, newOffset2] = item.decode(bytes, offset);
519
- offset = newOffset2;
520
- set.add(value);
521
- }
522
- return [set, offset];
523
- }
524
- };
528
+ return codecsCore.mapDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
525
529
  }
526
530
  function getSetCodec(item, config = {}) {
527
531
  return codecsCore.combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
528
532
  }
529
- function structCodecHelper(fields, description) {
530
- const fieldDescriptions = fields.map(([name, codec]) => `${String(name)}: ${codec.description}`).join(", ");
531
- return {
532
- description: description ?? `struct(${fieldDescriptions})`,
533
- fixedSize: sumCodecSizes(fields.map(([, field]) => field.fixedSize)),
534
- maxSize: sumCodecSizes(fields.map(([, field]) => field.maxSize))
535
- };
536
- }
537
- function getStructEncoder(fields, config = {}) {
538
- return {
539
- ...structCodecHelper(fields, config.description),
540
- encode: (struct) => {
541
- const fieldBytes = fields.map(([key, codec]) => codec.encode(struct[key]));
542
- return codecsCore.mergeBytes(fieldBytes);
533
+ function getStructEncoder(fields) {
534
+ const fieldCodecs = fields.map(([, codec]) => codec);
535
+ const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
536
+ const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
537
+ return codecsCore.createEncoder({
538
+ ...fixedSize === null ? {
539
+ getSizeFromValue: (value) => fields.map(([key, codec]) => codecsCore.getEncodedSize(value[key], codec)).reduce((all, one) => all + one, 0),
540
+ maxSize
541
+ } : { fixedSize },
542
+ write: (struct, bytes, offset) => {
543
+ fields.forEach(([key, codec]) => {
544
+ offset = codec.write(struct[key], bytes, offset);
545
+ });
546
+ return offset;
543
547
  }
544
- };
545
- }
546
- function getStructDecoder(fields, config = {}) {
547
- return {
548
- ...structCodecHelper(fields, config.description),
549
- decode: (bytes, offset = 0) => {
548
+ });
549
+ }
550
+ function getStructDecoder(fields) {
551
+ const fieldCodecs = fields.map(([, codec]) => codec);
552
+ const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
553
+ const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? void 0;
554
+ return codecsCore.createDecoder({
555
+ ...fixedSize === null ? { maxSize } : { fixedSize },
556
+ read: (bytes, offset) => {
550
557
  const struct = {};
551
558
  fields.forEach(([key, codec]) => {
552
- const [value, newOffset] = codec.decode(bytes, offset);
559
+ const [value, newOffset] = codec.read(bytes, offset);
553
560
  offset = newOffset;
554
561
  struct[key] = value;
555
562
  });
556
563
  return [struct, offset];
557
564
  }
558
- };
559
- }
560
- function getStructCodec(fields, config = {}) {
561
- return codecsCore.combineCodec(getStructEncoder(fields, config), getStructDecoder(fields, config));
562
- }
563
- function tupleCodecHelper(items, description) {
564
- const itemDescriptions = items.map((item) => item.description).join(", ");
565
- return {
566
- description: description ?? `tuple(${itemDescriptions})`,
567
- fixedSize: sumCodecSizes(items.map((item) => item.fixedSize)),
568
- maxSize: sumCodecSizes(items.map((item) => item.maxSize))
569
- };
570
- }
571
- function getTupleEncoder(items, config = {}) {
572
- return {
573
- ...tupleCodecHelper(items, config.description),
574
- encode: (value) => {
575
- assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
576
- return codecsCore.mergeBytes(items.map((item, index) => item.encode(value[index])));
577
- }
578
- };
565
+ });
579
566
  }
580
- function getTupleDecoder(items, config = {}) {
581
- return {
582
- ...tupleCodecHelper(items, config.description),
583
- decode: (bytes, offset = 0) => {
584
- const values = [];
585
- items.forEach((codec) => {
586
- const [newValue, newOffset] = codec.decode(bytes, offset);
587
- values.push(newValue);
588
- offset = newOffset;
589
- });
590
- return [values, offset];
591
- }
592
- };
593
- }
594
- function getTupleCodec(items, config = {}) {
567
+ function getStructCodec(fields) {
595
568
  return codecsCore.combineCodec(
596
- getTupleEncoder(items, config),
597
- getTupleDecoder(items, config)
569
+ getStructEncoder(fields),
570
+ getStructDecoder(fields)
598
571
  );
599
572
  }
600
- function getUnitEncoder(config = {}) {
601
- return {
602
- description: config.description ?? "unit",
603
- encode: () => new Uint8Array(),
573
+ function getUnitEncoder() {
574
+ return codecsCore.createEncoder({
604
575
  fixedSize: 0,
605
- maxSize: 0
606
- };
576
+ write: (_value, _bytes, offset) => offset
577
+ });
607
578
  }
608
- function getUnitDecoder(config = {}) {
609
- return {
610
- decode: (_bytes, offset = 0) => [void 0, offset],
611
- description: config.description ?? "unit",
579
+ function getUnitDecoder() {
580
+ return codecsCore.createDecoder({
612
581
  fixedSize: 0,
613
- maxSize: 0
614
- };
582
+ read: (_bytes, offset) => [void 0, offset]
583
+ });
615
584
  }
616
- function getUnitCodec(config = {}) {
617
- return codecsCore.combineCodec(getUnitEncoder(config), getUnitDecoder(config));
585
+ function getUnitCodec() {
586
+ return codecsCore.combineCodec(getUnitEncoder(), getUnitDecoder());
618
587
  }
619
588
 
620
589
  exports.assertValidNumberOfItemsForCodec = assertValidNumberOfItemsForCodec;
621
- exports.decodeArrayLikeCodecSize = decodeArrayLikeCodecSize;
622
590
  exports.getArrayCodec = getArrayCodec;
623
591
  exports.getArrayDecoder = getArrayDecoder;
624
592
  exports.getArrayEncoder = getArrayEncoder;
625
- exports.getArrayLikeCodecSizeDescription = getArrayLikeCodecSizeDescription;
626
- exports.getArrayLikeCodecSizeFromChildren = getArrayLikeCodecSizeFromChildren;
627
- exports.getArrayLikeCodecSizePrefix = getArrayLikeCodecSizePrefix;
628
593
  exports.getBitArrayCodec = getBitArrayCodec;
629
594
  exports.getBitArrayDecoder = getBitArrayDecoder;
630
595
  exports.getBitArrayEncoder = getBitArrayEncoder;