@nnilky/structo 1.0.7 → 1.0.9

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 (91) hide show
  1. package/README.md +3 -3
  2. package/dist/datatypes/containers/array.d.ts +1 -1
  3. package/dist/datatypes/containers/array.js +9 -0
  4. package/dist/datatypes/containers/array.test.js +2 -2
  5. package/dist/datatypes/containers/exhuastiveArray.d.ts +2 -2
  6. package/dist/datatypes/containers/exhuastiveArray.js +13 -2
  7. package/dist/datatypes/containers/exhuastiveArray.test.js +2 -2
  8. package/dist/datatypes/containers/fastObject.d.ts +3 -3
  9. package/dist/datatypes/containers/fastObject.js +2 -2
  10. package/dist/datatypes/containers/fastObject.test.js +2 -2
  11. package/dist/datatypes/containers/list.d.ts +1 -1
  12. package/dist/datatypes/containers/list.js +14 -2
  13. package/dist/datatypes/containers/list.test.js +2 -2
  14. package/dist/datatypes/containers/object.d.ts +1 -1
  15. package/dist/datatypes/containers/object.js +8 -8
  16. package/dist/datatypes/containers/object.test.js +2 -2
  17. package/dist/datatypes/containers/taggedUnion.d.ts +1 -1
  18. package/dist/datatypes/containers/taggedUnion.test.js +2 -2
  19. package/dist/datatypes/index.d.ts +13 -13
  20. package/dist/datatypes/index.js +13 -13
  21. package/dist/datatypes/numbers/bigints.d.ts +1 -1
  22. package/dist/datatypes/numbers/bigints.test.js +2 -2
  23. package/dist/datatypes/numbers/floats.d.ts +1 -1
  24. package/dist/datatypes/numbers/floats.test.js +2 -2
  25. package/dist/datatypes/numbers/sints.d.ts +1 -1
  26. package/dist/datatypes/numbers/sints.test.js +2 -2
  27. package/dist/datatypes/numbers/uints.d.ts +1 -1
  28. package/dist/datatypes/numbers/uints.test.js +2 -2
  29. package/dist/datatypes/values/bytes.d.ts +1 -1
  30. package/dist/datatypes/values/bytes.test.js +2 -2
  31. package/dist/datatypes/values/sizedbytes.d.ts +1 -1
  32. package/dist/datatypes/values/sizedbytes.test.js +2 -2
  33. package/dist/datatypes/values/string.d.ts +1 -1
  34. package/dist/datatypes/values/string.test.js +5 -2
  35. package/dist/index.d.ts +6 -6
  36. package/dist/index.js +5 -5
  37. package/dist/read.d.ts +2 -6
  38. package/dist/read.js +9 -1
  39. package/dist/transforms/encode.d.ts +5 -2
  40. package/dist/transforms/encode.js +2 -1
  41. package/dist/transforms/enum.d.ts +1 -1
  42. package/dist/transforms/enum.js +12 -9
  43. package/dist/transforms/enum.test.js +2 -2
  44. package/dist/transforms/index.d.ts +11 -12
  45. package/dist/transforms/index.js +11 -12
  46. package/dist/transforms/literal.d.ts +1 -1
  47. package/dist/transforms/literal.js +12 -9
  48. package/dist/transforms/literal.test.js +2 -2
  49. package/dist/transforms/modify.d.ts +20 -2
  50. package/dist/transforms/modify.js +21 -1
  51. package/dist/transforms/modify.test.d.ts +1 -0
  52. package/dist/transforms/modify.test.js +17 -0
  53. package/dist/transforms/offset.d.ts +2 -0
  54. package/dist/transforms/offset.js +20 -0
  55. package/dist/transforms/offset.test.d.ts +1 -0
  56. package/dist/transforms/offset.test.js +39 -0
  57. package/dist/transforms/pipe.d.ts +1 -1
  58. package/dist/transforms/pipe.js +1 -1
  59. package/dist/transforms/toAscii.d.ts +1 -1
  60. package/dist/transforms/toAscii.js +7 -4
  61. package/dist/transforms/toAscii.test.js +2 -2
  62. package/dist/transforms/toBase64.d.ts +1 -1
  63. package/dist/transforms/toBase64.js +5 -2
  64. package/dist/transforms/toBase64.test.js +2 -2
  65. package/dist/transforms/toBytes.d.ts +1 -1
  66. package/dist/transforms/toBytes.js +5 -2
  67. package/dist/transforms/toBytes.test.js +2 -2
  68. package/dist/transforms/toHex.d.ts +1 -1
  69. package/dist/transforms/toHex.js +5 -2
  70. package/dist/transforms/toHex.test.js +2 -2
  71. package/dist/transforms/toTypedArray.d.ts +1 -1
  72. package/dist/transforms/toTypedArray.js +5 -2
  73. package/dist/transforms/toTypedArray.test.js +2 -2
  74. package/dist/types.d.ts +3 -0
  75. package/dist/utilities/index.d.ts +3 -2
  76. package/dist/utilities/index.js +3 -2
  77. package/dist/utilities/lazy.d.ts +1 -1
  78. package/dist/utilities/lazy.js +4 -4
  79. package/dist/utilities/lazy.test.js +2 -2
  80. package/dist/utilities/reference.d.ts +18 -0
  81. package/dist/utilities/reference.js +91 -0
  82. package/dist/utilities/reference.test.d.ts +1 -0
  83. package/dist/utilities/reference.test.js +63 -0
  84. package/dist/utilities/remember.d.ts +7 -6
  85. package/dist/utilities/remember.js +45 -8
  86. package/dist/utilities/remember.test.js +3 -7
  87. package/dist/utils.test.d.ts +1 -1
  88. package/dist/utils.test.js +1 -1
  89. package/dist/write.d.ts +1 -1
  90. package/dist/write.js +9 -1
  91. package/package.json +9 -9
package/README.md CHANGED
@@ -21,9 +21,9 @@ const Entity = st.object({
21
21
  ```
22
22
 
23
23
  - Lightweight, base size is <1KB and each datatype is a few hundred bytes
24
- - Fast, from [benchmarks](./benchmark) only 2-
25
- - Supports Web/Node.js compatible
26
- - Easily implemented
24
+ - Fast![benchmarks](./benchmark) show only 1.5-5x slower than ideal implementaiton
25
+ - Designed for both Web/Node.js compatible
26
+ - Easily implement your own serializers
27
27
 
28
28
  Each serializer is completely seperate from the base library, meaning you only pay for what you use.
29
29
 
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /**
3
3
  * `st.array` is a fixed length array, akin to a C array.
4
4
  *
@@ -7,6 +7,7 @@
7
7
  *
8
8
  */
9
9
  export function array(size, type) {
10
+ const SHOW_ERRORS = size < 4096;
10
11
  const { read: readType, write: writeType, size: typeSize } = type;
11
12
  return {
12
13
  size: type.size ? size * type.size : undefined,
@@ -16,13 +17,21 @@ export function array(size, type) {
16
17
  if (typeSize)
17
18
  ctx.alloc(size * typeSize);
18
19
  for (let i = 0; i < size; i++) {
20
+ if (SHOW_ERRORS)
21
+ ctx.stack.push(`[${i}]`);
19
22
  writeType(ctx, value[i]);
23
+ if (SHOW_ERRORS)
24
+ ctx.stack.pop();
20
25
  }
21
26
  },
22
27
  read: (ctx) => {
23
28
  const arr = new Array(size);
24
29
  for (let i = 0; i < size; i++) {
30
+ if (SHOW_ERRORS)
31
+ ctx.stack.push(`[${i}]`);
25
32
  arr[i] = readType(ctx);
33
+ if (SHOW_ERRORS)
34
+ ctx.stack.pop();
26
35
  }
27
36
  return arr;
28
37
  },
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { encodeTest, encodeFailTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeTest, encodeFailTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.array", () => {
5
5
  it("encode correctly", () => {
6
6
  encodeTest(st.array(4, st.u16()), [1, 2, 3, 4]);
@@ -1,9 +1,9 @@
1
- import * as st from "../..";
1
+ import * as st from "../../index.js";
2
2
  /**
3
3
  * exhuastiveArray is read until the end of the data
4
4
  *
5
5
  * ```py
6
- * exhuastiveArray(st.u32())
6
+ * exhuastiveArray(st.string(st.u8()))
7
7
  * ```
8
8
  */
9
9
  export declare function exhuastiveArray<T>(type: st.Serializer<T>): st.Serializer<T[]>;
@@ -1,23 +1,34 @@
1
- import * as st from "../..";
1
+ import * as st from "../../index.js";
2
2
  /**
3
3
  * exhuastiveArray is read until the end of the data
4
4
  *
5
5
  * ```py
6
- * exhuastiveArray(st.u32())
6
+ * exhuastiveArray(st.string(st.u8()))
7
7
  * ```
8
8
  */
9
9
  export function exhuastiveArray(type) {
10
10
  return {
11
11
  read(ctx) {
12
12
  let arr = [];
13
+ let i = 0;
13
14
  while (ctx.offset < ctx.view.byteLength) {
15
+ const TRACK_STACK = i++ < 4096;
16
+ if (TRACK_STACK)
17
+ ctx.stack.push(`[${arr.length - 1}]`);
14
18
  arr.push(type.read(ctx));
19
+ if (TRACK_STACK)
20
+ ctx.stack.pop();
15
21
  }
16
22
  return arr;
17
23
  },
18
24
  write(ctx, value) {
25
+ const TRACK_STACK = value.length < 4096;
19
26
  for (let i = 0; i < value.length; i++) {
27
+ if (TRACK_STACK)
28
+ ctx.stack.push(`[${i}]`);
20
29
  type.write(ctx, value[i]);
30
+ if (TRACK_STACK)
31
+ ctx.stack.pop();
21
32
  }
22
33
  },
23
34
  };
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { encodeTest, encodeSnapshotTest, encodeFailTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeTest, encodeSnapshotTest, encodeFailTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.exhuastiveArray", () => {
5
5
  it("encode correctly", () => {
6
6
  const spec = st.exhuastiveArray(st.u32());
@@ -1,9 +1,9 @@
1
- import type { InferInput, Serializer } from "../../types";
1
+ import type { InferInput, Serializer } from "../../types.js";
2
2
  type InferObject<T> = T extends Record<string, Serializer<any>> ? {
3
3
  [Key in keyof T]: InferInput<T[Key]>;
4
4
  } : never;
5
5
  /**
6
- * `fastObject` is equivelent to object but it uses eval to improve performance
6
+ * `fastObject` is equivelent to object but it uses eval to improve performance, additionally it omits error reporting
7
7
  *
8
8
  * This means that is should be avoided in scenarios where CSP is required (so can't be the default), but should be fine for all other cases
9
9
  *
@@ -15,7 +15,7 @@ type InferObject<T> = T extends Record<string, Serializer<any>> ? {
15
15
  * })
16
16
  * ```
17
17
  *
18
- * Note: Using st.lazy affects the performance of fastObject as it prevents discovery of subobjects, avoid when performance is a requirement
18
+ * Note: Using `st.lazy` affects the performance of fastObject as it prevents discovery of subobjects, avoid when performance is a requirement
19
19
  */
20
20
  export declare function fastObject<T extends Record<string, Serializer<any>>>(definition: T): Serializer<InferObject<T>>;
21
21
  export {};
@@ -1,6 +1,6 @@
1
1
  const definitionSymbol = Symbol();
2
2
  /**
3
- * `fastObject` is equivelent to object but it uses eval to improve performance
3
+ * `fastObject` is equivelent to object but it uses eval to improve performance, additionally it omits error reporting
4
4
  *
5
5
  * This means that is should be avoided in scenarios where CSP is required (so can't be the default), but should be fine for all other cases
6
6
  *
@@ -12,7 +12,7 @@ const definitionSymbol = Symbol();
12
12
  * })
13
13
  * ```
14
14
  *
15
- * Note: Using st.lazy affects the performance of fastObject as it prevents discovery of subobjects, avoid when performance is a requirement
15
+ * Note: Using `st.lazy` affects the performance of fastObject as it prevents discovery of subobjects, avoid when performance is a requirement
16
16
  */
17
17
  export function fastObject(definition) {
18
18
  let serializers = [];
@@ -1,7 +1,7 @@
1
1
  //@ts-ignore TODO
2
2
  import { describe, it, expect } from "bun:test";
3
- import { bytes, encodeTest, encodeSnapshotTest } from "../../utils.test";
4
- import * as st from "../../index";
3
+ import { bytes, encodeTest, encodeSnapshotTest } from "../../utils.test.js";
4
+ import * as st from "../../index.js";
5
5
  describe("st.fastObject", () => {
6
6
  const spec = st.fastObject({
7
7
  a: st.u8(),
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /**
3
3
  * `st.list` is a dynamically sized array
4
4
  *
@@ -12,17 +12,29 @@ export function list(length, type) {
12
12
  return {
13
13
  write: (ctx, value) => {
14
14
  length.write(ctx, value.length);
15
- if (type.size)
15
+ const TRACK_STACK = value.length < 4096;
16
+ if (type.size) {
16
17
  ctx.alloc(value.length * type.size);
17
- for (const v of value) {
18
+ }
19
+ for (let i = 0; i < value.length; i++) {
20
+ if (TRACK_STACK)
21
+ ctx.stack.push(`[${i}]`);
22
+ const v = value[i];
18
23
  type.write(ctx, v);
24
+ if (TRACK_STACK)
25
+ ctx.stack.pop();
19
26
  }
20
27
  },
21
28
  read: (ctx) => {
22
29
  const size = length.read(ctx);
30
+ const TRACK_STACK = size < 4096;
23
31
  const arr = new Array(size);
24
32
  for (let i = 0; i < size; i++) {
33
+ if (TRACK_STACK)
34
+ ctx.stack.push(`[${i}]`);
25
35
  arr[i] = type.read(ctx);
36
+ if (TRACK_STACK)
37
+ ctx.stack.pop();
26
38
  }
27
39
  return arr;
28
40
  },
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { encodeTest, encodeSnapshotTest, encodeFailTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeTest, encodeSnapshotTest, encodeFailTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.list", () => {
5
5
  it("encode correctly", () => {
6
6
  const spec = st.list(st.u8(), st.u32());
@@ -1,4 +1,4 @@
1
- import type { InferInput, InferOutput, Serializer } from "../../types";
1
+ import type { InferInput, InferOutput, Serializer } from "../../types.js";
2
2
  type InferObjectInfer<T> = T extends Record<string, Serializer<any>> ? {
3
3
  [Key in keyof T]: InferInput<T[Key]>;
4
4
  } : never;
@@ -21,19 +21,19 @@ export function object(definition) {
21
21
  if (size)
22
22
  ctx.alloc(size);
23
23
  for (let i = 0; i < entires.length; i++) {
24
- const key = entires[i][0];
25
- try {
26
- entires[i][1].write(ctx, value[key]);
27
- }
28
- catch (e) {
29
- throw new Error(`Failed to encode key '${key}'`, { cause: e });
30
- }
24
+ const [key, serializer] = entires[i];
25
+ ctx.stack.push(`.${key}`);
26
+ serializer.write(ctx, value[key]);
27
+ ctx.stack.pop();
31
28
  }
32
29
  },
33
30
  read: (ctx) => {
34
31
  const output = new Array(entires.length);
35
32
  for (let i = 0; i < entires.length; i++) {
36
- output[i] = [entires[i][0], entires[i][1].read(ctx)];
33
+ const [key, serializer] = entires[i];
34
+ ctx.stack.push(`.${key}`);
35
+ output[i] = [key, serializer.read(ctx)];
36
+ ctx.stack.pop();
37
37
  }
38
38
  return Object.fromEntries(output);
39
39
  },
@@ -1,7 +1,7 @@
1
1
  //@ts-ignore TODO
2
2
  import { describe, it, expect, expectTypeOf } from "bun:test";
3
- import { bytes, encodeTest, encodeSnapshotTest } from "../../utils.test";
4
- import * as st from "../../index";
3
+ import { bytes, encodeTest, encodeSnapshotTest } from "../../utils.test.js";
4
+ import * as st from "../../index.js";
5
5
  describe("st.object", () => {
6
6
  it("encodes correctly", () => {
7
7
  encodeTest(st.object({ a: st.u8(), b: st.u8() }), //
@@ -1,4 +1,4 @@
1
- import type { InferInput, InferOutput, Serializer } from "../../types";
1
+ import type { InferInput, InferOutput, Serializer } from "../../types.js";
2
2
  /**
3
3
  * `st.taggedUnion` is a union type with a kind
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import { describe, expectTypeOf, it } from "bun:test";
2
- import { encodeTest, expectEncodeSize, encodeSnapshotTest, encodeFailTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeTest, expectEncodeSize, encodeSnapshotTest, encodeFailTest, } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.taggedUnion", () => {
5
5
  it("encode correctly", () => {
6
6
  const spec = st.taggedUnion(st.u8(), {
@@ -1,13 +1,13 @@
1
- export { u64Bigint, s64Bigint } from "./numbers/bigints";
2
- export { f16, f32, f64 } from "./numbers/floats";
3
- export { s8, s16, s32, s64 } from "./numbers/sints";
4
- export { u8, u16, u32, u64 } from "./numbers/uints";
5
- export { array } from "./containers/array";
6
- export { fastObject } from "./containers/fastObject";
7
- export { object } from "./containers/object";
8
- export { list } from "./containers/list";
9
- export { taggedUnion } from "./containers/taggedUnion";
10
- export { exhuastiveArray } from "./containers/exhuastiveArray";
11
- export { bytes } from "./values/bytes";
12
- export { sizedBytes } from "./values/sizedbytes";
13
- export { string } from "./values/string";
1
+ export { u64Bigint, s64Bigint } from "./numbers/bigints.js";
2
+ export { f16, f32, f64 } from "./numbers/floats.js";
3
+ export { s8, s16, s32, s64 } from "./numbers/sints.js";
4
+ export { u8, u16, u32, u64 } from "./numbers/uints.js";
5
+ export { array } from "./containers/array.js";
6
+ export { fastObject } from "./containers/fastObject.js";
7
+ export { object } from "./containers/object.js";
8
+ export { list } from "./containers/list.js";
9
+ export { taggedUnion } from "./containers/taggedUnion.js";
10
+ export { exhuastiveArray } from "./containers/exhuastiveArray.js";
11
+ export { bytes } from "./values/bytes.js";
12
+ export { sizedBytes } from "./values/sizedbytes.js";
13
+ export { string } from "./values/string.js";
@@ -1,13 +1,13 @@
1
- export { u64Bigint, s64Bigint } from "./numbers/bigints";
2
- export { f16, f32, f64 } from "./numbers/floats";
3
- export { s8, s16, s32, s64 } from "./numbers/sints";
4
- export { u8, u16, u32, u64 } from "./numbers/uints";
5
- export { array } from "./containers/array";
6
- export { fastObject } from "./containers/fastObject";
7
- export { object } from "./containers/object";
8
- export { list } from "./containers/list";
9
- export { taggedUnion } from "./containers/taggedUnion";
10
- export { exhuastiveArray } from "./containers/exhuastiveArray";
11
- export { bytes } from "./values/bytes";
12
- export { sizedBytes } from "./values/sizedbytes";
13
- export { string } from "./values/string";
1
+ export { u64Bigint, s64Bigint } from "./numbers/bigints.js";
2
+ export { f16, f32, f64 } from "./numbers/floats.js";
3
+ export { s8, s16, s32, s64 } from "./numbers/sints.js";
4
+ export { u8, u16, u32, u64 } from "./numbers/uints.js";
5
+ export { array } from "./containers/array.js";
6
+ export { fastObject } from "./containers/fastObject.js";
7
+ export { object } from "./containers/object.js";
8
+ export { list } from "./containers/list.js";
9
+ export { taggedUnion } from "./containers/taggedUnion.js";
10
+ export { exhuastiveArray } from "./containers/exhuastiveArray.js";
11
+ export { bytes } from "./values/bytes.js";
12
+ export { sizedBytes } from "./values/sizedbytes.js";
13
+ export { string } from "./values/string.js";
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /**
3
3
  * 64bit unsigned interger
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from "bun:test";
2
- import { encodeTest, encodeSnapshotTest, randbigint, encodeFailTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeTest, encodeSnapshotTest, randbigint, encodeFailTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  function test_bigint(options) {
5
5
  const { name, range: [start, end], serializer, size, } = options;
6
6
  describe(name, () => {
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /** 16bit float */
3
3
  export declare function f16(endian?: "little" | "big"): Serializer<number>;
4
4
  /** 32bit float */
@@ -1,7 +1,7 @@
1
1
  //@ts-ignore TODO
2
2
  import { describe, it, expect } from "bun:test";
3
- import { encodeTest, expectEncodeSize } from "../../utils.test";
4
- import * as st from "../../index";
3
+ import { encodeTest, expectEncodeSize } from "../../utils.test.js";
4
+ import * as st from "../../index.js";
5
5
  function test_float(options) {
6
6
  const { name, serializer, size } = options;
7
7
  const expectEncodeApproximately = (value) => {
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /** 8bit signed integer */
3
3
  export declare function s8(): Serializer<number>;
4
4
  /** 16bit signed integer */
@@ -1,7 +1,7 @@
1
1
  //@ts-ignore TODO
2
2
  import { describe, it, expect } from "bun:test";
3
- import { encodeTest, encodeSnapshotTest, expectError, randint, encodeFailTest, } from "../../utils.test";
4
- import * as st from "../../index";
3
+ import { encodeTest, encodeSnapshotTest, expectError, randint, encodeFailTest, } from "../../utils.test.js";
4
+ import * as st from "../../index.js";
5
5
  function test_sint(options) {
6
6
  const { name, range: [start, end], serializer, size, disableRangeCheck, } = options;
7
7
  describe(name, () => {
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /** 8bit unsigned integer */
3
3
  export declare function u8(): Serializer<number>;
4
4
  /** 16bit unsigned integer */
@@ -1,7 +1,7 @@
1
1
  //@ts-ignore TODO
2
2
  import { describe, it, expect } from "bun:test";
3
- import { encodeTest, encodeSnapshotTest, expectError, randint, encodeFailTest, } from "../../utils.test";
4
- import * as st from "../../index";
3
+ import { encodeTest, encodeSnapshotTest, expectError, randint, encodeFailTest, } from "../../utils.test.js";
4
+ import * as st from "../../index.js";
5
5
  function test_uint(options) {
6
6
  const { name, range: [start, end], serializer, size, disableMaxCheck, } = options;
7
7
  describe(name, () => {
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /**
3
3
  * Fixed length bytes
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { bytes, encodeFailTest, encodeTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { bytes, encodeFailTest, encodeTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.bytes", () => {
5
5
  const buffer = st.bytes(2);
6
6
  it("encode correctly", () => {
@@ -1,2 +1,2 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  export declare function sizedBytes(length: Serializer<number>): Serializer<ArrayBuffer>;
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { bytes, encodeFailTest, encodeTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { bytes, encodeFailTest, encodeTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.sizedBytes", () => {
5
5
  it("encode correctly", () => {
6
6
  const buffer = st.sizedBytes(st.u8());
@@ -1,4 +1,4 @@
1
- import type { Serializer } from "../../types";
1
+ import type { Serializer } from "../../types.js";
2
2
  /**
3
3
  * `st.json` stores string data by writing/reading the length and then reading that many bytes
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "bun:test";
2
- import { encodeFailTest, encodeTest } from "../../utils.test";
3
- import * as st from "../../index";
2
+ import { encodeFailTest, encodeTest } from "../../utils.test.js";
3
+ import * as st from "../../index.js";
4
4
  describe("st.string", () => {
5
5
  it("encode correctly", () => {
6
6
  encodeTest(st.string(st.u8()), "foo");
@@ -12,6 +12,9 @@ describe("st.string", () => {
12
12
  //@ts-expect-error, intentional mistake
13
13
  encodeFailTest(st.string(st.u8()), 8);
14
14
  });
15
+ it("works on long strings", () => {
16
+ encodeTest(st.string(st.u32()), "A".repeat(2 ** 24));
17
+ });
15
18
  it("errors on too long strings", () => {
16
19
  encodeFailTest(st.string(st.u8()), "A".repeat(256));
17
20
  });
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export type { InferInput as Infer, InferInput, InferOutput, ReaderContext, WriterContext, Serializer, } from "./types";
2
- export { read, createReaderContext } from "./read";
3
- export { write, createdWriterContext } from "./write";
4
- export * from "./datatypes/index";
5
- export * from "./transforms/index";
6
- export * from "./utilities/index";
1
+ export type { InferOutput as Infer, InferInput, InferOutput, ReaderContext, WriterContext, Serializer, } from "./types.js";
2
+ export { read, createReaderContext } from "./read.js";
3
+ export { write, createdWriterContext } from "./write.js";
4
+ export * from "./datatypes/index.js";
5
+ export * from "./transforms/index.js";
6
+ export * from "./utilities/index.js";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { read, createReaderContext } from "./read";
2
- export { write, createdWriterContext } from "./write";
3
- export * from "./datatypes/index";
4
- export * from "./transforms/index";
5
- export * from "./utilities/index";
1
+ export { read, createReaderContext } from "./read.js";
2
+ export { write, createdWriterContext } from "./write.js";
3
+ export * from "./datatypes/index.js";
4
+ export * from "./transforms/index.js";
5
+ export * from "./utilities/index.js";
package/dist/read.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- import type { Serializer } from "./types";
1
+ import type { Serializer, ReaderContext } from "./types.js";
2
2
  export declare function read<TIn, TOut>(serializer: Serializer<TIn, TOut>, buffer: ArrayBuffer): TOut;
3
- export declare function createReaderContext(buffer: ArrayBuffer): {
4
- offset: number;
5
- buffer: ArrayBuffer;
6
- view: DataView<ArrayBuffer>;
7
- };
3
+ export declare function createReaderContext(buffer: ArrayBuffer): ReaderContext;
package/dist/read.js CHANGED
@@ -1,8 +1,16 @@
1
1
  export function read(serializer, buffer) {
2
- return serializer.read(createReaderContext(buffer));
2
+ const ctx = createReaderContext(buffer);
3
+ try {
4
+ return serializer.read(ctx);
5
+ }
6
+ catch (e) {
7
+ const path = ctx.stack.join("") ?? "root";
8
+ throw new Error(`Deserialization error at serializer${path}`, { cause: e });
9
+ }
3
10
  }
4
11
  export function createReaderContext(buffer) {
5
12
  return {
13
+ stack: [],
6
14
  offset: 0,
7
15
  buffer,
8
16
  view: new DataView(buffer),
@@ -1,2 +1,5 @@
1
- import type { Transform } from "./pipe";
2
- export declare function encode<TIn, TOut>(encode: (value: TOut) => TIn, decode: (value: TIn) => TOut): Transform<TOut, TIn>;
1
+ import type { Transform } from "./pipe.js";
2
+ export declare function encode<TIn, TOut>(options: {
3
+ encode: (value: TOut) => TIn;
4
+ decode: (value: TIn) => TOut;
5
+ }): Transform<TOut, TIn>;
@@ -1,4 +1,5 @@
1
- export function encode(encode, decode) {
1
+ export function encode(options) {
2
+ const { encode, decode } = options;
2
3
  return (type) => ({
3
4
  size: type.size,
4
5
  read: (ctx) => decode(type.read(ctx)),
@@ -1,2 +1,2 @@
1
- export declare function enum_<const T>(values: T[]): import("./pipe").Transform<T, any>;
1
+ export declare function enum_<const T>(values: T[]): import("./pipe.js").Transform<T, any>;
2
2
  export { enum_ as enum };
@@ -1,13 +1,16 @@
1
- import { encode } from "./encode";
1
+ import { encode } from "./encode.js";
2
2
  export function enum_(values) {
3
- return encode((v) => {
4
- if (!values.includes(v))
5
- throw new Error(`Invalid enum variant: ${v}`);
6
- return v;
7
- }, (v) => {
8
- if (!values.includes(v))
9
- throw new Error(`Invalid enum variant: ${v}`);
10
- return v;
3
+ return encode({
4
+ encode: (v) => {
5
+ if (!values.includes(v))
6
+ throw new Error(`Invalid enum variant: ${v}`);
7
+ return v;
8
+ },
9
+ decode: (v) => {
10
+ if (!values.includes(v))
11
+ throw new Error(`Invalid enum variant: ${v}`);
12
+ return v;
13
+ },
11
14
  });
12
15
  }
13
16
  export { enum_ as enum };
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "node:test";
2
- import * as st from "../index";
3
- import { encodeTest, encodeFailTest } from "../utils.test";
2
+ import * as st from "../index.js";
3
+ import { encodeTest, encodeFailTest } from "../utils.test.js";
4
4
  describe("st.enum", () => {
5
5
  it("encode correctly", () => {
6
6
  encodeTest(st.pipe(st.u8(), st.enum([0, 1, 2])), //
@@ -1,12 +1,11 @@
1
- export { type Transform as Pipeline, pipe } from "./pipe";
2
- export { encode } from "./encode";
3
- export { modify } from "./modify";
4
- export { literal } from "./literal";
5
- export { enum } from "./enum";
6
- export { fixedOffset } from "./fixedOffset";
7
- export { noAdvance } from "./noAdvance";
8
- export { toAscii } from "./toAscii";
9
- export { toBytes } from "./toBytes";
10
- export { toHex } from "./toHex";
11
- export { toBase64 } from "./toBase64";
12
- export { toTypedArray } from "./toTypedArray";
1
+ export { type Transform as Pipeline, pipe } from "./pipe.js";
2
+ export { encode } from "./encode.js";
3
+ export { modify } from "./modify.js";
4
+ export { literal } from "./literal.js";
5
+ export { enum } from "./enum.js";
6
+ export { offset } from "./offset.js";
7
+ export { toAscii } from "./toAscii.js";
8
+ export { toBytes } from "./toBytes.js";
9
+ export { toHex } from "./toHex.js";
10
+ export { toBase64 } from "./toBase64.js";
11
+ export { toTypedArray } from "./toTypedArray.js";