@solana/codecs-data-structures 2.0.0-experimental.85b7dfe → 2.0.0-experimental.8618508

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 (44) hide show
  1. package/dist/index.browser.cjs +341 -430
  2. package/dist/index.browser.cjs.map +1 -1
  3. package/dist/index.browser.js +343 -430
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.development.js +450 -539
  6. package/dist/index.development.js.map +1 -1
  7. package/dist/index.native.js +345 -428
  8. package/dist/index.native.js.map +1 -1
  9. package/dist/index.node.cjs +341 -430
  10. package/dist/index.node.cjs.map +1 -1
  11. package/dist/index.node.js +343 -428
  12. package/dist/index.node.js.map +1 -1
  13. package/dist/index.production.min.js +36 -40
  14. package/dist/types/array.d.ts +50 -6
  15. package/dist/types/array.d.ts.map +1 -1
  16. package/dist/types/bit-array.d.ts +5 -5
  17. package/dist/types/bit-array.d.ts.map +1 -1
  18. package/dist/types/boolean.d.ts +18 -6
  19. package/dist/types/boolean.d.ts.map +1 -1
  20. package/dist/types/bytes.d.ts +14 -5
  21. package/dist/types/bytes.d.ts.map +1 -1
  22. package/dist/types/data-enum.d.ts +14 -14
  23. package/dist/types/data-enum.d.ts.map +1 -1
  24. package/dist/types/index.d.ts +0 -1
  25. package/dist/types/index.d.ts.map +1 -1
  26. package/dist/types/map.d.ts +39 -6
  27. package/dist/types/map.d.ts.map +1 -1
  28. package/dist/types/nullable.d.ts +24 -6
  29. package/dist/types/nullable.d.ts.map +1 -1
  30. package/dist/types/scalar-enum.d.ts +18 -6
  31. package/dist/types/scalar-enum.d.ts.map +1 -1
  32. package/dist/types/set.d.ts +39 -6
  33. package/dist/types/set.d.ts.map +1 -1
  34. package/dist/types/struct.d.ts +28 -18
  35. package/dist/types/struct.d.ts.map +1 -1
  36. package/dist/types/tuple.d.ts +22 -15
  37. package/dist/types/tuple.d.ts.map +1 -1
  38. package/dist/types/unit.d.ts +4 -12
  39. package/dist/types/unit.d.ts.map +1 -1
  40. package/dist/types/utils.d.ts +10 -2
  41. package/dist/types/utils.d.ts.map +1 -1
  42. package/package.json +4 -4
  43. package/dist/types/array-like-codec-size.d.ts +0 -20
  44. package/dist/types/array-like-codec-size.d.ts.map +0 -1
@@ -14,28 +14,6 @@ this.globalThis.solanaWeb3 = (function (exports) {
14
14
  throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);
15
15
  }
16
16
  }
17
- function assertFixedSizeCodec(data, message) {
18
- if (data.fixedSize === null) {
19
- throw new Error(message != null ? message : "Expected a fixed-size codec, got a variable-size one.");
20
- }
21
- }
22
- var mergeBytes = (byteArrays) => {
23
- const nonEmptyByteArrays = byteArrays.filter((arr) => arr.length);
24
- if (nonEmptyByteArrays.length === 0) {
25
- return byteArrays.length ? byteArrays[0] : new Uint8Array();
26
- }
27
- if (nonEmptyByteArrays.length === 1) {
28
- return nonEmptyByteArrays[0];
29
- }
30
- const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);
31
- const result = new Uint8Array(totalLength);
32
- let offset = 0;
33
- nonEmptyByteArrays.forEach((arr) => {
34
- result.set(arr, offset);
35
- offset += arr.length;
36
- });
37
- return result;
38
- };
39
17
  var padBytes = (bytes, length) => {
40
18
  if (bytes.length >= length)
41
19
  return bytes;
@@ -44,58 +22,100 @@ this.globalThis.solanaWeb3 = (function (exports) {
44
22
  return paddedBytes;
45
23
  };
46
24
  var fixBytes = (bytes, length) => padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);
47
- function combineCodec(encoder, decoder, description) {
48
- if (encoder.fixedSize !== decoder.fixedSize) {
25
+ function getEncodedSize(value, encoder) {
26
+ return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
27
+ }
28
+ function createEncoder(encoder) {
29
+ return Object.freeze({
30
+ ...encoder,
31
+ encode: (value) => {
32
+ const bytes = new Uint8Array(getEncodedSize(value, encoder));
33
+ encoder.write(value, bytes, 0);
34
+ return bytes;
35
+ }
36
+ });
37
+ }
38
+ function createDecoder(decoder) {
39
+ return Object.freeze({
40
+ ...decoder,
41
+ decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0]
42
+ });
43
+ }
44
+ function isFixedSize(codec) {
45
+ return "fixedSize" in codec && typeof codec.fixedSize === "number";
46
+ }
47
+ function assertIsFixedSize(codec, message) {
48
+ if (!isFixedSize(codec)) {
49
+ throw new Error(message != null ? message : "Expected a fixed-size codec, got a variable-size one.");
50
+ }
51
+ }
52
+ function isVariableSize(codec) {
53
+ return !isFixedSize(codec);
54
+ }
55
+ function combineCodec(encoder, decoder) {
56
+ if (isFixedSize(encoder) !== isFixedSize(decoder)) {
57
+ throw new Error(`Encoder and decoder must either both be fixed-size or variable-size.`);
58
+ }
59
+ if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {
49
60
  throw new Error(
50
61
  `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`
51
62
  );
52
63
  }
53
- if (encoder.maxSize !== decoder.maxSize) {
64
+ if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {
54
65
  throw new Error(
55
66
  `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`
56
67
  );
57
68
  }
58
- if (description === void 0 && encoder.description !== decoder.description) {
59
- throw new Error(
60
- `Encoder and decoder must have the same description, got [${encoder.description}] and [${decoder.description}]. Pass a custom description as a third argument if you want to override the description and bypass this error.`
61
- );
62
- }
63
69
  return {
70
+ ...decoder,
71
+ ...encoder,
64
72
  decode: decoder.decode,
65
- description: description != null ? description : encoder.description,
66
73
  encode: encoder.encode,
67
- fixedSize: encoder.fixedSize,
68
- maxSize: encoder.maxSize
74
+ read: decoder.read,
75
+ write: encoder.write
69
76
  };
70
77
  }
71
- function fixCodecHelper(data, fixedBytes, description) {
72
- return {
73
- description: description != null ? description : `fixed(${fixedBytes}, ${data.description})`,
78
+ function fixEncoder(encoder, fixedBytes) {
79
+ return createEncoder({
74
80
  fixedSize: fixedBytes,
75
- maxSize: fixedBytes
76
- };
77
- }
78
- function fixEncoder(encoder, fixedBytes, description) {
79
- return {
80
- ...fixCodecHelper(encoder, fixedBytes, description),
81
- encode: (value) => fixBytes(encoder.encode(value), fixedBytes)
82
- };
81
+ write: (value, bytes, offset) => {
82
+ const variableByteArray = encoder.encode(value);
83
+ const fixedByteArray = variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;
84
+ bytes.set(fixedByteArray, offset);
85
+ return offset + fixedBytes;
86
+ }
87
+ });
83
88
  }
84
- function fixDecoder(decoder, fixedBytes, description) {
85
- return {
86
- ...fixCodecHelper(decoder, fixedBytes, description),
87
- decode: (bytes, offset = 0) => {
89
+ function fixDecoder(decoder, fixedBytes) {
90
+ return createDecoder({
91
+ fixedSize: fixedBytes,
92
+ read: (bytes, offset) => {
88
93
  assertByteArrayHasEnoughBytesForCodec("fixCodec", fixedBytes, bytes, offset);
89
94
  if (offset > 0 || bytes.length > fixedBytes) {
90
95
  bytes = bytes.slice(offset, offset + fixedBytes);
91
96
  }
92
- if (decoder.fixedSize !== null) {
97
+ if (isFixedSize(decoder)) {
93
98
  bytes = fixBytes(bytes, decoder.fixedSize);
94
99
  }
95
- const [value] = decoder.decode(bytes, 0);
100
+ const [value] = decoder.read(bytes, 0);
96
101
  return [value, offset + fixedBytes];
97
102
  }
98
- };
103
+ });
104
+ }
105
+ function mapEncoder(encoder, unmap) {
106
+ return createEncoder({
107
+ ...isVariableSize(encoder) ? { ...encoder, getSizeFromValue: (value) => encoder.getSizeFromValue(unmap(value)) } : encoder,
108
+ write: (value, bytes, offset) => encoder.write(unmap(value), bytes, offset)
109
+ });
110
+ }
111
+ function mapDecoder(decoder, map) {
112
+ return createDecoder({
113
+ ...decoder,
114
+ read: (bytes, offset) => {
115
+ const [value, newOffset] = decoder.read(bytes, offset);
116
+ return [map(value, bytes, offset), newOffset];
117
+ }
118
+ });
99
119
  }
100
120
 
101
121
  // ../codecs-numbers/dist/index.browser.js
@@ -106,50 +126,33 @@ this.globalThis.solanaWeb3 = (function (exports) {
106
126
  );
107
127
  }
108
128
  }
109
- function sharedNumberFactory(input) {
110
- var _a;
111
- let littleEndian;
112
- let defaultDescription = input.name;
113
- if (input.size > 1) {
114
- littleEndian = !("endian" in input.config) || input.config.endian === 0;
115
- defaultDescription += littleEndian ? "(le)" : "(be)";
116
- }
117
- return {
118
- description: (_a = input.config.description) != null ? _a : defaultDescription,
119
- fixedSize: input.size,
120
- littleEndian,
121
- maxSize: input.size
122
- };
129
+ function isLittleEndian(config) {
130
+ return (config == null ? void 0 : config.endian) === 1 ? false : true;
123
131
  }
124
132
  function numberEncoderFactory(input) {
125
- const codecData = sharedNumberFactory(input);
126
- return {
127
- description: codecData.description,
128
- encode(value) {
133
+ return createEncoder({
134
+ fixedSize: input.size,
135
+ write(value, bytes, offset) {
129
136
  if (input.range) {
130
137
  assertNumberIsBetweenForCodec(input.name, input.range[0], input.range[1], value);
131
138
  }
132
139
  const arrayBuffer = new ArrayBuffer(input.size);
133
- input.set(new DataView(arrayBuffer), value, codecData.littleEndian);
134
- return new Uint8Array(arrayBuffer);
135
- },
136
- fixedSize: codecData.fixedSize,
137
- maxSize: codecData.maxSize
138
- };
140
+ input.set(new DataView(arrayBuffer), value, isLittleEndian(input.config));
141
+ bytes.set(new Uint8Array(arrayBuffer), offset);
142
+ return offset + input.size;
143
+ }
144
+ });
139
145
  }
140
146
  function numberDecoderFactory(input) {
141
- const codecData = sharedNumberFactory(input);
142
- return {
143
- decode(bytes, offset = 0) {
144
- assertByteArrayIsNotEmptyForCodec(codecData.description, bytes, offset);
145
- assertByteArrayHasEnoughBytesForCodec(codecData.description, input.size, bytes, offset);
147
+ return createDecoder({
148
+ fixedSize: input.size,
149
+ read(bytes, offset = 0) {
150
+ assertByteArrayIsNotEmptyForCodec(input.name, bytes, offset);
151
+ assertByteArrayHasEnoughBytesForCodec(input.name, input.size, bytes, offset);
146
152
  const view = new DataView(toArrayBuffer(bytes, offset, input.size));
147
- return [input.get(view, codecData.littleEndian), offset + input.size];
148
- },
149
- description: codecData.description,
150
- fixedSize: codecData.fixedSize,
151
- maxSize: codecData.maxSize
152
- };
153
+ return [input.get(view, isLittleEndian(input.config)), offset + input.size];
154
+ }
155
+ });
153
156
  }
154
157
  function toArrayBuffer(bytes, offset, length) {
155
158
  const bytesOffset = bytes.byteOffset + (offset != null ? offset : 0);
@@ -169,20 +172,25 @@ this.globalThis.solanaWeb3 = (function (exports) {
169
172
  name: "u32",
170
173
  size: 4
171
174
  });
172
- var getU8Encoder = (config = {}) => numberEncoderFactory({
173
- config,
175
+ var getU8Encoder = () => numberEncoderFactory({
174
176
  name: "u8",
175
177
  range: [0, Number("0xff")],
176
178
  set: (view, value) => view.setUint8(0, value),
177
179
  size: 1
178
180
  });
179
- var getU8Decoder = (config = {}) => numberDecoderFactory({
180
- config,
181
+ var getU8Decoder = () => numberDecoderFactory({
181
182
  get: (view) => view.getUint8(0),
182
183
  name: "u8",
183
184
  size: 1
184
185
  });
185
186
 
187
+ // src/assertions.ts
188
+ function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
189
+ if (expected !== actual) {
190
+ throw new Error(`Expected [${codecDescription}] to have ${expected} items, got ${actual}.`);
191
+ }
192
+ }
193
+
186
194
  // src/utils.ts
187
195
  function maxCodecSizes(sizes) {
188
196
  return sizes.reduce(
@@ -193,112 +201,114 @@ this.globalThis.solanaWeb3 = (function (exports) {
193
201
  function sumCodecSizes(sizes) {
194
202
  return sizes.reduce((all, size) => all === null || size === null ? null : all + size, 0);
195
203
  }
196
-
197
- // src/array-like-codec-size.ts
198
- function decodeArrayLikeCodecSize(size, childrenSizes, bytes, offset) {
199
- if (typeof size === "number") {
200
- return [size, offset];
201
- }
202
- if (typeof size === "object") {
203
- return size.decode(bytes, offset);
204
- }
205
- if (size === "remainder") {
206
- const childrenSize = sumCodecSizes(childrenSizes);
207
- if (childrenSize === null) {
208
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
209
- }
210
- const remainder = bytes.slice(offset).length;
211
- if (remainder % childrenSize !== 0) {
212
- throw new Error(
213
- `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.`
214
- );
215
- }
216
- return [remainder / childrenSize, offset];
217
- }
218
- throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
219
- }
220
- function getArrayLikeCodecSizeDescription(size) {
221
- return typeof size === "object" ? size.description : `${size}`;
204
+ function getFixedSize(codec) {
205
+ return isFixedSize(codec) ? codec.fixedSize : null;
222
206
  }
223
- function getArrayLikeCodecSizeFromChildren(size, childrenSizes) {
224
- if (typeof size !== "number")
225
- return null;
226
- if (size === 0)
227
- return 0;
228
- const childrenSize = sumCodecSizes(childrenSizes);
229
- return childrenSize === null ? null : childrenSize * size;
230
- }
231
- function getArrayLikeCodecSizePrefix(size, realSize) {
232
- return typeof size === "object" ? size.encode(realSize) : new Uint8Array();
233
- }
234
-
235
- // src/assertions.ts
236
- function assertValidNumberOfItemsForCodec(codecDescription, expected, actual) {
237
- if (expected !== actual) {
238
- throw new Error(`Expected [${codecDescription}] to have ${expected} items, got ${actual}.`);
239
- }
207
+ function getMaxSize(codec) {
208
+ var _a;
209
+ return isFixedSize(codec) ? codec.fixedSize : (_a = codec.maxSize) != null ? _a : null;
240
210
  }
241
211
 
242
212
  // src/array.ts
243
- function arrayCodecHelper(item, size, description) {
244
- if (size === "remainder" && item.fixedSize === null) {
245
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
246
- }
247
- return {
248
- description: description != null ? description : `array(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`,
249
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]),
250
- maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize])
251
- };
252
- }
253
213
  function getArrayEncoder(item, config = {}) {
254
- var _a;
214
+ var _a, _b;
255
215
  const size = (_a = config.size) != null ? _a : getU32Encoder();
256
- return {
257
- ...arrayCodecHelper(item, size, config.description),
258
- encode: (value) => {
216
+ if (size === "remainder") {
217
+ assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
218
+ }
219
+ const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));
220
+ const maxSize = (_b = computeArrayLikeCodecSize(size, getMaxSize(item))) != null ? _b : void 0;
221
+ return createEncoder({
222
+ ...fixedSize !== null ? { fixedSize } : {
223
+ getSizeFromValue: (array) => {
224
+ const prefixSize = typeof size === "object" ? getEncodedSize(array.length, size) : 0;
225
+ return prefixSize + [...array].reduce((all, value) => all + getEncodedSize(value, item), 0);
226
+ },
227
+ maxSize
228
+ },
229
+ write: (array, bytes, offset) => {
259
230
  if (typeof size === "number") {
260
- assertValidNumberOfItemsForCodec("array", size, value.length);
231
+ assertValidNumberOfItemsForCodec("array", size, array.length);
261
232
  }
262
- return mergeBytes([getArrayLikeCodecSizePrefix(size, value.length), ...value.map((v) => item.encode(v))]);
233
+ if (typeof size === "object") {
234
+ offset = size.write(array.length, bytes, offset);
235
+ }
236
+ array.forEach((value) => {
237
+ offset = item.write(value, bytes, offset);
238
+ });
239
+ return offset;
263
240
  }
264
- };
241
+ });
265
242
  }
266
243
  function getArrayDecoder(item, config = {}) {
267
- var _a;
244
+ var _a, _b;
268
245
  const size = (_a = config.size) != null ? _a : getU32Decoder();
269
- return {
270
- ...arrayCodecHelper(item, size, config.description),
271
- decode: (bytes, offset = 0) => {
246
+ if (size === "remainder") {
247
+ assertIsFixedSize(item, 'Codecs of "remainder" size must have fixed-size items.');
248
+ }
249
+ const itemSize = getFixedSize(item);
250
+ const fixedSize = computeArrayLikeCodecSize(size, itemSize);
251
+ const maxSize = (_b = computeArrayLikeCodecSize(size, getMaxSize(item))) != null ? _b : void 0;
252
+ return createDecoder({
253
+ ...fixedSize !== null ? { fixedSize } : { maxSize },
254
+ read: (bytes, offset) => {
255
+ const array = [];
272
256
  if (typeof size === "object" && bytes.slice(offset).length === 0) {
273
- return [[], offset];
257
+ return [array, offset];
274
258
  }
275
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
259
+ const [resolvedSize, newOffset] = readArrayLikeCodecSize(size, itemSize, bytes, offset);
276
260
  offset = newOffset;
277
- const values = [];
278
261
  for (let i = 0; i < resolvedSize; i += 1) {
279
- const [value, newOffset2] = item.decode(bytes, offset);
280
- values.push(value);
262
+ const [value, newOffset2] = item.read(bytes, offset);
281
263
  offset = newOffset2;
264
+ array.push(value);
282
265
  }
283
- return [values, offset];
266
+ return [array, offset];
284
267
  }
285
- };
268
+ });
286
269
  }
287
270
  function getArrayCodec(item, config = {}) {
288
271
  return combineCodec(getArrayEncoder(item, config), getArrayDecoder(item, config));
289
272
  }
273
+ function readArrayLikeCodecSize(size, itemSize, bytes, offset) {
274
+ if (typeof size === "number") {
275
+ return [size, offset];
276
+ }
277
+ if (typeof size === "object") {
278
+ return size.read(bytes, offset);
279
+ }
280
+ if (size === "remainder") {
281
+ if (itemSize === null) {
282
+ throw new Error('Codecs of "remainder" size must have fixed-size items.');
283
+ }
284
+ const remainder = Math.max(0, bytes.length - offset);
285
+ if (remainder % itemSize !== 0) {
286
+ throw new Error(
287
+ `The remainder of the byte array (${remainder} bytes) cannot be split into chunks of ${itemSize} bytes. Codecs of "remainder" size must have a remainder that is a multiple of its item size. In other words, ${remainder} modulo ${itemSize} should be equal to zero.`
288
+ );
289
+ }
290
+ return [remainder / itemSize, offset];
291
+ }
292
+ throw new Error(`Unrecognized array-like codec size: ${JSON.stringify(size)}`);
293
+ }
294
+ function computeArrayLikeCodecSize(size, itemSize) {
295
+ if (typeof size !== "number")
296
+ return null;
297
+ if (size === 0)
298
+ return 0;
299
+ return itemSize === null ? null : itemSize * size;
300
+ }
290
301
 
291
302
  // src/bit-array.ts
292
- var getBitArrayEncoder = (size, config = {}) => {
293
- var _a, _b;
303
+ function getBitArrayEncoder(size, config = {}) {
304
+ var _a;
294
305
  const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
295
306
  const backward = (_a = parsedConfig.backward) != null ? _a : false;
296
- const backwardSuffix = backward ? "; backward" : "";
297
- return {
298
- description: (_b = parsedConfig.description) != null ? _b : `bitArray(${size}${backwardSuffix})`,
299
- encode(value) {
307
+ return createEncoder({
308
+ fixedSize: size,
309
+ write(value, bytes, offset) {
300
310
  var _a2;
301
- const bytes = [];
311
+ const bytesToAdd = [];
302
312
  for (let i = 0; i < size; i += 1) {
303
313
  let byte = 0;
304
314
  for (let j = 0; j < 8; j += 1) {
@@ -306,24 +316,23 @@ this.globalThis.solanaWeb3 = (function (exports) {
306
316
  byte |= feature << (backward ? j : 7 - j);
307
317
  }
308
318
  if (backward) {
309
- bytes.unshift(byte);
319
+ bytesToAdd.unshift(byte);
310
320
  } else {
311
- bytes.push(byte);
321
+ bytesToAdd.push(byte);
312
322
  }
313
323
  }
314
- return new Uint8Array(bytes);
315
- },
316
- fixedSize: size,
317
- maxSize: size
318
- };
319
- };
320
- var getBitArrayDecoder = (size, config = {}) => {
321
- var _a, _b;
324
+ bytes.set(bytesToAdd, offset);
325
+ return size;
326
+ }
327
+ });
328
+ }
329
+ function getBitArrayDecoder(size, config = {}) {
330
+ var _a;
322
331
  const parsedConfig = typeof config === "boolean" ? { backward: config } : config;
323
332
  const backward = (_a = parsedConfig.backward) != null ? _a : false;
324
- const backwardSuffix = backward ? "; backward" : "";
325
- return {
326
- decode(bytes, offset = 0) {
333
+ return createDecoder({
334
+ fixedSize: size,
335
+ read(bytes, offset) {
327
336
  assertByteArrayHasEnoughBytesForCodec("bitArray", size, bytes, offset);
328
337
  const booleans = [];
329
338
  let slice = bytes.slice(offset, offset + size);
@@ -340,40 +349,25 @@ this.globalThis.solanaWeb3 = (function (exports) {
340
349
  }
341
350
  });
342
351
  return [booleans, offset + size];
343
- },
344
- description: (_b = parsedConfig.description) != null ? _b : `bitArray(${size}${backwardSuffix})`,
345
- fixedSize: size,
346
- maxSize: size
347
- };
348
- };
349
- var getBitArrayCodec = (size, config = {}) => combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
352
+ }
353
+ });
354
+ }
355
+ function getBitArrayCodec(size, config = {}) {
356
+ return combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));
357
+ }
350
358
 
351
359
  // src/boolean.ts
352
360
  function getBooleanEncoder(config = {}) {
353
- var _a, _b;
361
+ var _a;
354
362
  const size = (_a = config.size) != null ? _a : getU8Encoder();
355
- assertFixedSizeCodec(size, "Codec [bool] requires a fixed size.");
356
- return {
357
- description: (_b = config.description) != null ? _b : `bool(${size.description})`,
358
- encode: (value) => size.encode(value ? 1 : 0),
359
- fixedSize: size.fixedSize,
360
- maxSize: size.fixedSize
361
- };
363
+ assertIsFixedSize(size, "Codec [bool] requires a fixed size.");
364
+ return mapEncoder(size, (value) => value ? 1 : 0);
362
365
  }
363
366
  function getBooleanDecoder(config = {}) {
364
- var _a, _b;
367
+ var _a;
365
368
  const size = (_a = config.size) != null ? _a : getU8Decoder();
366
- assertFixedSizeCodec(size, "Codec [bool] requires a fixed size.");
367
- return {
368
- decode: (bytes, offset = 0) => {
369
- assertByteArrayIsNotEmptyForCodec("bool", bytes, offset);
370
- const [value, vOffset] = size.decode(bytes, offset);
371
- return [value === 1, vOffset];
372
- },
373
- description: (_b = config.description) != null ? _b : `bool(${size.description})`,
374
- fixedSize: size.fixedSize,
375
- maxSize: size.fixedSize
376
- };
369
+ assertIsFixedSize(size, "Codec [bool] requires a fixed size.");
370
+ return mapDecoder(size, (value) => Number(value) === 1);
377
371
  }
378
372
  function getBooleanCodec(config = {}) {
379
373
  return combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));
@@ -381,110 +375,94 @@ this.globalThis.solanaWeb3 = (function (exports) {
381
375
 
382
376
  // src/bytes.ts
383
377
  function getBytesEncoder(config = {}) {
384
- var _a, _b;
378
+ var _a;
385
379
  const size = (_a = config.size) != null ? _a : "variable";
386
- const sizeDescription = typeof size === "object" ? size.description : `${size}`;
387
- const description = (_b = config.description) != null ? _b : `bytes(${sizeDescription})`;
388
- const byteEncoder = {
389
- description,
390
- encode: (value) => value,
391
- fixedSize: null,
392
- maxSize: null
393
- };
380
+ const byteEncoder = createEncoder({
381
+ getSizeFromValue: (value) => value.length,
382
+ write: (value, bytes, offset) => {
383
+ bytes.set(value, offset);
384
+ return offset + value.length;
385
+ }
386
+ });
394
387
  if (size === "variable") {
395
388
  return byteEncoder;
396
389
  }
397
390
  if (typeof size === "number") {
398
- return fixEncoder(byteEncoder, size, description);
391
+ return fixEncoder(byteEncoder, size);
399
392
  }
400
- return {
401
- ...byteEncoder,
402
- encode: (value) => {
403
- const contentBytes = byteEncoder.encode(value);
404
- const lengthBytes = size.encode(contentBytes.length);
405
- return mergeBytes([lengthBytes, contentBytes]);
393
+ return createEncoder({
394
+ getSizeFromValue: (value) => getEncodedSize(value.length, size) + value.length,
395
+ write: (value, bytes, offset) => {
396
+ offset = size.write(value.length, bytes, offset);
397
+ return byteEncoder.write(value, bytes, offset);
406
398
  }
407
- };
399
+ });
408
400
  }
409
401
  function getBytesDecoder(config = {}) {
410
- var _a, _b;
402
+ var _a;
411
403
  const size = (_a = config.size) != null ? _a : "variable";
412
- const sizeDescription = typeof size === "object" ? size.description : `${size}`;
413
- const description = (_b = config.description) != null ? _b : `bytes(${sizeDescription})`;
414
- const byteDecoder = {
415
- decode: (bytes, offset = 0) => {
404
+ const byteDecoder = createDecoder({
405
+ read: (bytes, offset) => {
416
406
  const slice = bytes.slice(offset);
417
407
  return [slice, offset + slice.length];
418
- },
419
- description,
420
- fixedSize: null,
421
- maxSize: null
422
- };
408
+ }
409
+ });
423
410
  if (size === "variable") {
424
411
  return byteDecoder;
425
412
  }
426
413
  if (typeof size === "number") {
427
- return fixDecoder(byteDecoder, size, description);
414
+ return fixDecoder(byteDecoder, size);
428
415
  }
429
- return {
430
- ...byteDecoder,
431
- decode: (bytes, offset = 0) => {
416
+ return createDecoder({
417
+ read: (bytes, offset) => {
432
418
  assertByteArrayIsNotEmptyForCodec("bytes", bytes, offset);
433
- const [lengthBigInt, lengthOffset] = size.decode(bytes, offset);
419
+ const [lengthBigInt, lengthOffset] = size.read(bytes, offset);
434
420
  const length = Number(lengthBigInt);
435
421
  offset = lengthOffset;
436
422
  const contentBytes = bytes.slice(offset, offset + length);
437
423
  assertByteArrayHasEnoughBytesForCodec("bytes", length, contentBytes);
438
- const [value, contentOffset] = byteDecoder.decode(contentBytes);
424
+ const [value, contentOffset] = byteDecoder.read(contentBytes, 0);
439
425
  offset += contentOffset;
440
426
  return [value, offset];
441
427
  }
442
- };
428
+ });
443
429
  }
444
430
  function getBytesCodec(config = {}) {
445
431
  return combineCodec(getBytesEncoder(config), getBytesDecoder(config));
446
432
  }
447
433
 
448
434
  // src/data-enum.ts
449
- function dataEnumCodecHelper(variants, prefix, description) {
450
- const fieldDescriptions = variants.map(([name, codec]) => `${String(name)}${codec ? `: ${codec.description}` : ""}`).join(", ");
451
- const allVariantHaveTheSameFixedSize = variants.every((one, _i, all) => one[1].fixedSize === all[0][1].fixedSize);
452
- const fixedVariantSize = allVariantHaveTheSameFixedSize ? variants[0][1].fixedSize : null;
453
- const maxVariantSize = maxCodecSizes(variants.map(([, field]) => field.maxSize));
454
- return {
455
- description: description != null ? description : `dataEnum(${fieldDescriptions}; ${prefix.description})`,
456
- fixedSize: variants.length === 0 ? prefix.fixedSize : sumCodecSizes([prefix.fixedSize, fixedVariantSize]),
457
- maxSize: variants.length === 0 ? prefix.maxSize : sumCodecSizes([prefix.maxSize, maxVariantSize])
458
- };
459
- }
460
435
  function getDataEnumEncoder(variants, config = {}) {
461
436
  var _a;
462
437
  const prefix = (_a = config.size) != null ? _a : getU8Encoder();
463
- return {
464
- ...dataEnumCodecHelper(variants, prefix, config.description),
465
- encode: (variant) => {
466
- const discriminator = variants.findIndex(([key]) => variant.__kind === key);
467
- if (discriminator < 0) {
468
- throw new Error(
469
- `Invalid data enum variant. Expected one of [${variants.map(([key]) => key).join(", ")}], got "${variant.__kind}".`
470
- );
471
- }
472
- const variantPrefix = prefix.encode(discriminator);
473
- const variantSerializer = variants[discriminator][1];
474
- const variantBytes = variantSerializer.encode(variant);
475
- return mergeBytes([variantPrefix, variantBytes]);
438
+ const fixedSize = getDataEnumFixedSize(variants, prefix);
439
+ return createEncoder({
440
+ ...fixedSize !== null ? { fixedSize } : {
441
+ getSizeFromValue: (variant) => {
442
+ const discriminator = getVariantDiscriminator(variants, variant);
443
+ const variantEncoder = variants[discriminator][1];
444
+ return getEncodedSize(discriminator, prefix) + getEncodedSize(variant, variantEncoder);
445
+ },
446
+ maxSize: getDataEnumMaxSize(variants, prefix)
447
+ },
448
+ write: (variant, bytes, offset) => {
449
+ const discriminator = getVariantDiscriminator(variants, variant);
450
+ offset = prefix.write(discriminator, bytes, offset);
451
+ const variantEncoder = variants[discriminator][1];
452
+ return variantEncoder.write(variant, bytes, offset);
476
453
  }
477
- };
454
+ });
478
455
  }
479
456
  function getDataEnumDecoder(variants, config = {}) {
480
457
  var _a;
481
458
  const prefix = (_a = config.size) != null ? _a : getU8Decoder();
482
- return {
483
- ...dataEnumCodecHelper(variants, prefix, config.description),
484
- decode: (bytes, offset = 0) => {
459
+ const fixedSize = getDataEnumFixedSize(variants, prefix);
460
+ return createDecoder({
461
+ ...fixedSize !== null ? { fixedSize } : { maxSize: getDataEnumMaxSize(variants, prefix) },
462
+ read: (bytes, offset) => {
485
463
  var _a2;
486
464
  assertByteArrayIsNotEmptyForCodec("dataEnum", bytes, offset);
487
- const [discriminator, dOffset] = prefix.decode(bytes, offset);
465
+ const [discriminator, dOffset] = prefix.read(bytes, offset);
488
466
  offset = dOffset;
489
467
  const variantField = (_a2 = variants[Number(discriminator)]) != null ? _a2 : null;
490
468
  if (!variantField) {
@@ -492,362 +470,295 @@ this.globalThis.solanaWeb3 = (function (exports) {
492
470
  `Enum discriminator out of range. Expected a number between 0 and ${variants.length - 1}, got ${discriminator}.`
493
471
  );
494
472
  }
495
- const [variant, vOffset] = variantField[1].decode(bytes, offset);
473
+ const [variant, vOffset] = variantField[1].read(bytes, offset);
496
474
  offset = vOffset;
497
475
  return [{ __kind: variantField[0], ...variant != null ? variant : {} }, offset];
498
476
  }
499
- };
477
+ });
500
478
  }
501
479
  function getDataEnumCodec(variants, config = {}) {
502
480
  return combineCodec(getDataEnumEncoder(variants, config), getDataEnumDecoder(variants, config));
503
481
  }
504
-
505
- // src/map.ts
506
- function mapCodecHelper(key, value, size, description) {
507
- if (size === "remainder" && (key.fixedSize === null || value.fixedSize === null)) {
508
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
482
+ function getDataEnumFixedSize(variants, prefix) {
483
+ if (variants.length === 0)
484
+ return isFixedSize(prefix) ? prefix.fixedSize : null;
485
+ if (!isFixedSize(variants[0][1]))
486
+ return null;
487
+ const variantSize = variants[0][1].fixedSize;
488
+ const sameSizedVariants = variants.every(
489
+ (variant) => isFixedSize(variant[1]) && variant[1].fixedSize === variantSize
490
+ );
491
+ if (!sameSizedVariants)
492
+ return null;
493
+ return isFixedSize(prefix) ? prefix.fixedSize + variantSize : null;
494
+ }
495
+ function getDataEnumMaxSize(variants, prefix) {
496
+ var _a;
497
+ const maxVariantSize = maxCodecSizes(variants.map(([, codec]) => getMaxSize(codec)));
498
+ return (_a = sumCodecSizes([getMaxSize(prefix), maxVariantSize])) != null ? _a : void 0;
499
+ }
500
+ function getVariantDiscriminator(variants, variant) {
501
+ const discriminator = variants.findIndex(([key]) => variant.__kind === key);
502
+ if (discriminator < 0) {
503
+ throw new Error(
504
+ `Invalid data enum variant. Expected one of [${variants.map(([key]) => key).join(", ")}], got "${variant.__kind}".`
505
+ );
509
506
  }
510
- return {
511
- description: description != null ? description : `map(${key.description}, ${value.description}; ${getArrayLikeCodecSizeDescription(size)})`,
512
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [key.fixedSize, value.fixedSize]),
513
- maxSize: getArrayLikeCodecSizeFromChildren(size, [key.maxSize, value.maxSize])
514
- };
507
+ return discriminator;
515
508
  }
516
- function getMapEncoder(key, value, config = {}) {
509
+
510
+ // src/tuple.ts
511
+ function getTupleEncoder(items) {
517
512
  var _a;
518
- const size = (_a = config.size) != null ? _a : getU32Encoder();
519
- return {
520
- ...mapCodecHelper(key, value, size, config.description),
521
- encode: (map) => {
522
- if (typeof size === "number") {
523
- assertValidNumberOfItemsForCodec("map", size, map.size);
524
- }
525
- const itemBytes = Array.from(map, ([k, v]) => mergeBytes([key.encode(k), value.encode(v)]));
526
- return mergeBytes([getArrayLikeCodecSizePrefix(size, map.size), ...itemBytes]);
513
+ const fixedSize = sumCodecSizes(items.map(getFixedSize));
514
+ const maxSize = (_a = sumCodecSizes(items.map(getMaxSize))) != null ? _a : void 0;
515
+ return createEncoder({
516
+ ...fixedSize === null ? {
517
+ getSizeFromValue: (value) => items.map((item, index) => getEncodedSize(value[index], item)).reduce((all, one) => all + one, 0),
518
+ maxSize
519
+ } : { fixedSize },
520
+ write: (value, bytes, offset) => {
521
+ assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
522
+ items.forEach((item, index) => {
523
+ offset = item.write(value[index], bytes, offset);
524
+ });
525
+ return offset;
527
526
  }
528
- };
527
+ });
529
528
  }
530
- function getMapDecoder(key, value, config = {}) {
529
+ function getTupleDecoder(items) {
531
530
  var _a;
532
- const size = (_a = config.size) != null ? _a : getU32Decoder();
533
- return {
534
- ...mapCodecHelper(key, value, size, config.description),
535
- decode: (bytes, offset = 0) => {
536
- const map = /* @__PURE__ */ new Map();
537
- if (typeof size === "object" && bytes.slice(offset).length === 0) {
538
- return [map, offset];
539
- }
540
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(
541
- size,
542
- [key.fixedSize, value.fixedSize],
543
- bytes,
544
- offset
545
- );
546
- offset = newOffset;
547
- for (let i = 0; i < resolvedSize; i += 1) {
548
- const [decodedKey, kOffset] = key.decode(bytes, offset);
549
- offset = kOffset;
550
- const [decodedValue, vOffset] = value.decode(bytes, offset);
551
- offset = vOffset;
552
- map.set(decodedKey, decodedValue);
553
- }
554
- return [map, offset];
531
+ const fixedSize = sumCodecSizes(items.map(getFixedSize));
532
+ const maxSize = (_a = sumCodecSizes(items.map(getMaxSize))) != null ? _a : void 0;
533
+ return createDecoder({
534
+ ...fixedSize === null ? { maxSize } : { fixedSize },
535
+ read: (bytes, offset) => {
536
+ const values = [];
537
+ items.forEach((item) => {
538
+ const [newValue, newOffset] = item.read(bytes, offset);
539
+ values.push(newValue);
540
+ offset = newOffset;
541
+ });
542
+ return [values, offset];
555
543
  }
556
- };
544
+ });
545
+ }
546
+ function getTupleCodec(items) {
547
+ return combineCodec(
548
+ getTupleEncoder(items),
549
+ getTupleDecoder(items)
550
+ );
551
+ }
552
+
553
+ // src/map.ts
554
+ function getMapEncoder(key, value, config = {}) {
555
+ return mapEncoder(
556
+ getArrayEncoder(getTupleEncoder([key, value]), config),
557
+ (map) => [...map.entries()]
558
+ );
559
+ }
560
+ function getMapDecoder(key, value, config = {}) {
561
+ return mapDecoder(
562
+ getArrayDecoder(getTupleDecoder([key, value]), config),
563
+ (entries) => new Map(entries)
564
+ );
557
565
  }
558
566
  function getMapCodec(key, value, config = {}) {
559
567
  return combineCodec(getMapEncoder(key, value, config), getMapDecoder(key, value, config));
560
568
  }
561
569
 
562
570
  // src/nullable.ts
563
- function nullableCodecHelper(item, prefix, fixed, description) {
564
- let descriptionSuffix = `; ${prefix.description}`;
565
- let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;
566
- if (fixed) {
567
- assertFixedSizeCodec(item, "Fixed nullables can only be used with fixed-size codecs.");
568
- assertFixedSizeCodec(prefix, "Fixed nullables can only be used with fixed-size prefix.");
569
- descriptionSuffix += "; fixed";
570
- fixedSize = prefix.fixedSize + item.fixedSize;
571
- }
572
- return {
573
- description: description != null ? description : `nullable(${item.description + descriptionSuffix})`,
574
- fixedSize,
575
- maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
576
- };
577
- }
578
571
  function getNullableEncoder(item, config = {}) {
579
- var _a, _b;
572
+ var _a, _b, _c;
580
573
  const prefix = (_a = config.prefix) != null ? _a : getU8Encoder();
581
574
  const fixed = (_b = config.fixed) != null ? _b : false;
582
- return {
583
- ...nullableCodecHelper(item, prefix, fixed, config.description),
584
- encode: (option) => {
585
- const prefixByte = prefix.encode(Number(option !== null));
586
- let itemBytes = option !== null ? item.encode(option) : new Uint8Array();
587
- itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize) : itemBytes;
588
- return mergeBytes([prefixByte, itemBytes]);
575
+ const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;
576
+ if (fixed || isZeroSizeItem) {
577
+ assertIsFixedSize(item, "Fixed nullables can only be used with fixed-size codecs.");
578
+ assertIsFixedSize(prefix, "Fixed nullables can only be used with fixed-size prefix.");
579
+ const fixedSize = prefix.fixedSize + item.fixedSize;
580
+ return createEncoder({
581
+ fixedSize,
582
+ write: (option, bytes, offset) => {
583
+ const prefixOffset = prefix.write(Number(option !== null), bytes, offset);
584
+ if (option !== null) {
585
+ item.write(option, bytes, prefixOffset);
586
+ }
587
+ return offset + fixedSize;
588
+ }
589
+ });
590
+ }
591
+ return createEncoder({
592
+ getSizeFromValue: (option) => getEncodedSize(Number(option !== null), prefix) + (option !== null ? getEncodedSize(option, item) : 0),
593
+ maxSize: (_c = sumCodecSizes([prefix, item].map(getMaxSize))) != null ? _c : void 0,
594
+ write: (option, bytes, offset) => {
595
+ offset = prefix.write(Number(option !== null), bytes, offset);
596
+ if (option !== null) {
597
+ offset = item.write(option, bytes, offset);
598
+ }
599
+ return offset;
589
600
  }
590
- };
601
+ });
591
602
  }
592
603
  function getNullableDecoder(item, config = {}) {
593
- var _a, _b;
604
+ var _a, _b, _c;
594
605
  const prefix = (_a = config.prefix) != null ? _a : getU8Decoder();
595
606
  const fixed = (_b = config.fixed) != null ? _b : false;
596
- return {
597
- ...nullableCodecHelper(item, prefix, fixed, config.description),
598
- decode: (bytes, offset = 0) => {
599
- var _a2, _b2;
607
+ let fixedSize = null;
608
+ const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;
609
+ if (fixed || isZeroSizeItem) {
610
+ assertIsFixedSize(item, "Fixed nullables can only be used with fixed-size codecs.");
611
+ assertIsFixedSize(prefix, "Fixed nullables can only be used with fixed-size prefix.");
612
+ fixedSize = prefix.fixedSize + item.fixedSize;
613
+ }
614
+ return createDecoder({
615
+ ...fixedSize === null ? { maxSize: (_c = sumCodecSizes([prefix, item].map(getMaxSize))) != null ? _c : void 0 } : { fixedSize },
616
+ read: (bytes, offset) => {
600
617
  if (bytes.length - offset <= 0) {
601
618
  return [null, offset];
602
619
  }
603
- const fixedOffset = offset + ((_a2 = prefix.fixedSize) != null ? _a2 : 0) + ((_b2 = item.fixedSize) != null ? _b2 : 0);
604
- const [isSome, prefixOffset] = prefix.decode(bytes, offset);
605
- offset = prefixOffset;
620
+ const [isSome, prefixOffset] = prefix.read(bytes, offset);
606
621
  if (isSome === 0) {
607
- return [null, fixed ? fixedOffset : offset];
622
+ return [null, fixedSize !== null ? offset + fixedSize : prefixOffset];
608
623
  }
609
- const [value, newOffset] = item.decode(bytes, offset);
610
- offset = newOffset;
611
- return [value, fixed ? fixedOffset : offset];
624
+ const [value, newOffset] = item.read(bytes, prefixOffset);
625
+ return [value, fixedSize !== null ? offset + fixedSize : newOffset];
612
626
  }
613
- };
627
+ });
614
628
  }
615
629
  function getNullableCodec(item, config = {}) {
616
- return combineCodec(getNullableEncoder(item, config), getNullableDecoder(item, config));
630
+ const configCast = config;
631
+ return combineCodec(getNullableEncoder(item, configCast), getNullableDecoder(item, configCast));
617
632
  }
618
633
 
619
634
  // src/scalar-enum.ts
620
- function scalarEnumCoderHelper(constructor, prefix, description) {
635
+ function getScalarEnumEncoder(constructor, config = {}) {
636
+ var _a;
637
+ const prefix = (_a = config.size) != null ? _a : getU8Encoder();
638
+ const { minRange, maxRange, stringValues, enumKeys, enumValues } = getScalarEnumStats(constructor);
639
+ return mapEncoder(prefix, (value) => {
640
+ const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
641
+ const isInvalidString = typeof value === "string" && !stringValues.includes(value);
642
+ if (isInvalidNumber || isInvalidString) {
643
+ throw new Error(
644
+ `Invalid scalar enum variant. Expected one of [${stringValues.join(", ")}] or a number between ${minRange} and ${maxRange}, got "${value}".`
645
+ );
646
+ }
647
+ if (typeof value === "number")
648
+ return value;
649
+ const valueIndex = enumValues.indexOf(value);
650
+ if (valueIndex >= 0)
651
+ return valueIndex;
652
+ return enumKeys.indexOf(value);
653
+ });
654
+ }
655
+ function getScalarEnumDecoder(constructor, config = {}) {
656
+ var _a;
657
+ const prefix = (_a = config.size) != null ? _a : getU8Decoder();
658
+ const { minRange, maxRange, isNumericEnum, enumValues } = getScalarEnumStats(constructor);
659
+ return mapDecoder(prefix, (value) => {
660
+ const valueAsNumber = Number(value);
661
+ if (valueAsNumber < minRange || valueAsNumber > maxRange) {
662
+ throw new Error(
663
+ `Enum discriminator out of range. Expected a number between ${minRange} and ${maxRange}, got ${valueAsNumber}.`
664
+ );
665
+ }
666
+ return isNumericEnum ? valueAsNumber : enumValues[valueAsNumber];
667
+ });
668
+ }
669
+ function getScalarEnumCodec(constructor, config = {}) {
670
+ return combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
671
+ }
672
+ function getScalarEnumStats(constructor) {
621
673
  const enumKeys = Object.keys(constructor);
622
674
  const enumValues = Object.values(constructor);
623
675
  const isNumericEnum = enumValues.some((v) => typeof v === "number");
624
- const valueDescriptions = enumValues.filter((v) => typeof v === "string").join(", ");
625
676
  const minRange = 0;
626
677
  const maxRange = isNumericEnum ? enumValues.length / 2 - 1 : enumValues.length - 1;
627
678
  const stringValues = isNumericEnum ? [...enumKeys] : [.../* @__PURE__ */ new Set([...enumKeys, ...enumValues])];
628
679
  return {
629
- description: description != null ? description : `enum(${valueDescriptions}; ${prefix.description})`,
630
680
  enumKeys,
631
681
  enumValues,
632
- fixedSize: prefix.fixedSize,
633
682
  isNumericEnum,
634
683
  maxRange,
635
- maxSize: prefix.maxSize,
636
684
  minRange,
637
685
  stringValues
638
686
  };
639
687
  }
640
- function getScalarEnumEncoder(constructor, config = {}) {
641
- var _a;
642
- const prefix = (_a = config.size) != null ? _a : getU8Encoder();
643
- const { description, fixedSize, maxSize, minRange, maxRange, stringValues, enumKeys, enumValues } = scalarEnumCoderHelper(constructor, prefix, config.description);
644
- return {
645
- description,
646
- encode: (value) => {
647
- const isInvalidNumber = typeof value === "number" && (value < minRange || value > maxRange);
648
- const isInvalidString = typeof value === "string" && !stringValues.includes(value);
649
- if (isInvalidNumber || isInvalidString) {
650
- throw new Error(
651
- `Invalid scalar enum variant. Expected one of [${stringValues.join(", ")}] or a number between ${minRange} and ${maxRange}, got "${value}".`
652
- );
653
- }
654
- if (typeof value === "number")
655
- return prefix.encode(value);
656
- const valueIndex = enumValues.indexOf(value);
657
- if (valueIndex >= 0)
658
- return prefix.encode(valueIndex);
659
- return prefix.encode(enumKeys.indexOf(value));
660
- },
661
- fixedSize,
662
- maxSize
663
- };
664
- }
665
- function getScalarEnumDecoder(constructor, config = {}) {
666
- var _a;
667
- const prefix = (_a = config.size) != null ? _a : getU8Decoder();
668
- const { description, fixedSize, maxSize, minRange, maxRange, isNumericEnum, enumValues } = scalarEnumCoderHelper(
669
- constructor,
670
- prefix,
671
- config.description
672
- );
673
- return {
674
- decode: (bytes, offset = 0) => {
675
- assertByteArrayIsNotEmptyForCodec("enum", bytes, offset);
676
- const [value, newOffset] = prefix.decode(bytes, offset);
677
- const valueAsNumber = Number(value);
678
- offset = newOffset;
679
- if (valueAsNumber < minRange || valueAsNumber > maxRange) {
680
- throw new Error(
681
- `Enum discriminator out of range. Expected a number between ${minRange} and ${maxRange}, got ${valueAsNumber}.`
682
- );
683
- }
684
- return [isNumericEnum ? valueAsNumber : enumValues[valueAsNumber], offset];
685
- },
686
- description,
687
- fixedSize,
688
- maxSize
689
- };
690
- }
691
- function getScalarEnumCodec(constructor, config = {}) {
692
- return combineCodec(getScalarEnumEncoder(constructor, config), getScalarEnumDecoder(constructor, config));
693
- }
694
688
 
695
689
  // src/set.ts
696
- function setCodecHelper(item, size, description) {
697
- if (size === "remainder" && item.fixedSize === null) {
698
- throw new Error('Codecs of "remainder" size must have fixed-size items.');
699
- }
700
- return {
701
- description: description != null ? description : `set(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`,
702
- fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]),
703
- maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize])
704
- };
705
- }
706
690
  function getSetEncoder(item, config = {}) {
707
- var _a;
708
- const size = (_a = config.size) != null ? _a : getU32Encoder();
709
- return {
710
- ...setCodecHelper(item, size, config.description),
711
- encode: (set) => {
712
- if (typeof size === "number" && set.size !== size) {
713
- assertValidNumberOfItemsForCodec("set", size, set.size);
714
- }
715
- const itemBytes = Array.from(set, (value) => item.encode(value));
716
- return mergeBytes([getArrayLikeCodecSizePrefix(size, set.size), ...itemBytes]);
717
- }
718
- };
691
+ return mapEncoder(getArrayEncoder(item, config), (set) => [...set]);
719
692
  }
720
693
  function getSetDecoder(item, config = {}) {
721
- var _a;
722
- const size = (_a = config.size) != null ? _a : getU32Decoder();
723
- return {
724
- ...setCodecHelper(item, size, config.description),
725
- decode: (bytes, offset = 0) => {
726
- const set = /* @__PURE__ */ new Set();
727
- if (typeof size === "object" && bytes.slice(offset).length === 0) {
728
- return [set, offset];
729
- }
730
- const [resolvedSize, newOffset] = decodeArrayLikeCodecSize(size, [item.fixedSize], bytes, offset);
731
- offset = newOffset;
732
- for (let i = 0; i < resolvedSize; i += 1) {
733
- const [value, newOffset2] = item.decode(bytes, offset);
734
- offset = newOffset2;
735
- set.add(value);
736
- }
737
- return [set, offset];
738
- }
739
- };
694
+ return mapDecoder(getArrayDecoder(item, config), (entries) => new Set(entries));
740
695
  }
741
696
  function getSetCodec(item, config = {}) {
742
697
  return combineCodec(getSetEncoder(item, config), getSetDecoder(item, config));
743
698
  }
744
699
 
745
700
  // src/struct.ts
746
- function structCodecHelper(fields, description) {
747
- const fieldDescriptions = fields.map(([name, codec]) => `${String(name)}: ${codec.description}`).join(", ");
748
- return {
749
- description: description != null ? description : `struct(${fieldDescriptions})`,
750
- fixedSize: sumCodecSizes(fields.map(([, field]) => field.fixedSize)),
751
- maxSize: sumCodecSizes(fields.map(([, field]) => field.maxSize))
752
- };
753
- }
754
- function getStructEncoder(fields, config = {}) {
755
- return {
756
- ...structCodecHelper(fields, config.description),
757
- encode: (struct) => {
758
- const fieldBytes = fields.map(([key, codec]) => codec.encode(struct[key]));
759
- return mergeBytes(fieldBytes);
701
+ function getStructEncoder(fields) {
702
+ var _a;
703
+ const fieldCodecs = fields.map(([, codec]) => codec);
704
+ const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
705
+ const maxSize = (_a = sumCodecSizes(fieldCodecs.map(getMaxSize))) != null ? _a : void 0;
706
+ return createEncoder({
707
+ ...fixedSize === null ? {
708
+ getSizeFromValue: (value) => fields.map(([key, codec]) => getEncodedSize(value[key], codec)).reduce((all, one) => all + one, 0),
709
+ maxSize
710
+ } : { fixedSize },
711
+ write: (struct, bytes, offset) => {
712
+ fields.forEach(([key, codec]) => {
713
+ offset = codec.write(struct[key], bytes, offset);
714
+ });
715
+ return offset;
760
716
  }
761
- };
717
+ });
762
718
  }
763
- function getStructDecoder(fields, config = {}) {
764
- return {
765
- ...structCodecHelper(fields, config.description),
766
- decode: (bytes, offset = 0) => {
719
+ function getStructDecoder(fields) {
720
+ var _a;
721
+ const fieldCodecs = fields.map(([, codec]) => codec);
722
+ const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));
723
+ const maxSize = (_a = sumCodecSizes(fieldCodecs.map(getMaxSize))) != null ? _a : void 0;
724
+ return createDecoder({
725
+ ...fixedSize === null ? { maxSize } : { fixedSize },
726
+ read: (bytes, offset) => {
767
727
  const struct = {};
768
728
  fields.forEach(([key, codec]) => {
769
- const [value, newOffset] = codec.decode(bytes, offset);
729
+ const [value, newOffset] = codec.read(bytes, offset);
770
730
  offset = newOffset;
771
731
  struct[key] = value;
772
732
  });
773
733
  return [struct, offset];
774
734
  }
775
- };
776
- }
777
- function getStructCodec(fields, config = {}) {
778
- return combineCodec(getStructEncoder(fields, config), getStructDecoder(fields, config));
779
- }
780
-
781
- // src/tuple.ts
782
- function tupleCodecHelper(items, description) {
783
- const itemDescriptions = items.map((item) => item.description).join(", ");
784
- return {
785
- description: description != null ? description : `tuple(${itemDescriptions})`,
786
- fixedSize: sumCodecSizes(items.map((item) => item.fixedSize)),
787
- maxSize: sumCodecSizes(items.map((item) => item.maxSize))
788
- };
789
- }
790
- function getTupleEncoder(items, config = {}) {
791
- return {
792
- ...tupleCodecHelper(items, config.description),
793
- encode: (value) => {
794
- assertValidNumberOfItemsForCodec("tuple", items.length, value.length);
795
- return mergeBytes(items.map((item, index) => item.encode(value[index])));
796
- }
797
- };
798
- }
799
- function getTupleDecoder(items, config = {}) {
800
- return {
801
- ...tupleCodecHelper(items, config.description),
802
- decode: (bytes, offset = 0) => {
803
- const values = [];
804
- items.forEach((codec) => {
805
- const [newValue, newOffset] = codec.decode(bytes, offset);
806
- values.push(newValue);
807
- offset = newOffset;
808
- });
809
- return [values, offset];
810
- }
811
- };
735
+ });
812
736
  }
813
- function getTupleCodec(items, config = {}) {
814
- return combineCodec(
815
- getTupleEncoder(items, config),
816
- getTupleDecoder(items, config)
817
- );
737
+ function getStructCodec(fields) {
738
+ return combineCodec(getStructEncoder(fields), getStructDecoder(fields));
818
739
  }
819
740
 
820
741
  // src/unit.ts
821
- function getUnitEncoder(config = {}) {
822
- var _a;
823
- return {
824
- description: (_a = config.description) != null ? _a : "unit",
825
- encode: () => new Uint8Array(),
742
+ function getUnitEncoder() {
743
+ return createEncoder({
826
744
  fixedSize: 0,
827
- maxSize: 0
828
- };
745
+ write: (_value, _bytes, offset) => offset
746
+ });
829
747
  }
830
- function getUnitDecoder(config = {}) {
831
- var _a;
832
- return {
833
- decode: (_bytes, offset = 0) => [void 0, offset],
834
- description: (_a = config.description) != null ? _a : "unit",
748
+ function getUnitDecoder() {
749
+ return createDecoder({
835
750
  fixedSize: 0,
836
- maxSize: 0
837
- };
751
+ read: (_bytes, offset) => [void 0, offset]
752
+ });
838
753
  }
839
- function getUnitCodec(config = {}) {
840
- return combineCodec(getUnitEncoder(config), getUnitDecoder(config));
754
+ function getUnitCodec() {
755
+ return combineCodec(getUnitEncoder(), getUnitDecoder());
841
756
  }
842
757
 
843
758
  exports.assertValidNumberOfItemsForCodec = assertValidNumberOfItemsForCodec;
844
- exports.decodeArrayLikeCodecSize = decodeArrayLikeCodecSize;
845
759
  exports.getArrayCodec = getArrayCodec;
846
760
  exports.getArrayDecoder = getArrayDecoder;
847
761
  exports.getArrayEncoder = getArrayEncoder;
848
- exports.getArrayLikeCodecSizeDescription = getArrayLikeCodecSizeDescription;
849
- exports.getArrayLikeCodecSizeFromChildren = getArrayLikeCodecSizeFromChildren;
850
- exports.getArrayLikeCodecSizePrefix = getArrayLikeCodecSizePrefix;
851
762
  exports.getBitArrayCodec = getBitArrayCodec;
852
763
  exports.getBitArrayDecoder = getBitArrayDecoder;
853
764
  exports.getBitArrayEncoder = getBitArrayEncoder;