@nnilky/structo 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/datatypes/containers/array.js +9 -12
- package/dist/datatypes/containers/exhuastiveArray.js +6 -6
- package/dist/datatypes/containers/list.js +7 -7
- package/dist/datatypes/containers/object.js +9 -8
- package/dist/datatypes/numbers/bigints.js +2 -2
- package/dist/datatypes/numbers/floats.js +12 -9
- package/dist/datatypes/numbers/sints.js +13 -10
- package/dist/datatypes/numbers/uints.js +13 -10
- package/dist/datatypes/values/bytes.d.ts +2 -2
- package/dist/datatypes/values/bytes.js +6 -6
- package/dist/datatypes/values/bytes.test.js +2 -2
- package/dist/datatypes/values/sizedbytes.d.ts +1 -1
- package/dist/datatypes/values/sizedbytes.js +3 -4
- package/dist/datatypes/values/sizedbytes.test.js +1 -1
- package/dist/datatypes/values/string.js +2 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/read.d.ts +2 -3
- package/dist/read.js +10 -12
- package/dist/transforms/enum.d.ts +1 -1
- package/dist/transforms/literal.d.ts +1 -1
- package/dist/transforms/toAscii.d.ts +1 -1
- package/dist/transforms/toAscii.js +2 -2
- package/dist/transforms/toBase64.d.ts +1 -1
- package/dist/transforms/toBase64.js +2 -2
- package/dist/transforms/toBytes.d.ts +1 -1
- package/dist/transforms/toBytes.js +2 -2
- package/dist/transforms/toHex.d.ts +3 -3
- package/dist/transforms/toHex.js +4 -4
- package/dist/transforms/toTypedArray.d.ts +11 -6
- package/dist/transforms/toTypedArray.js +10 -5
- package/dist/transforms/toTypedArray.test.js +18 -9
- package/dist/types.d.ts +11 -9
- package/dist/utilities/remember.d.ts +1 -1
- package/dist/utilities/remember.js +3 -3
- package/dist/utils.test.d.ts +1 -1
- package/dist/utils.test.js +1 -3
- package/dist/write.d.ts +2 -2
- package/dist/write.js +47 -34
- package/package.json +7 -2
- package/dist/datatypes/containers/sizedbytes.d.ts +0 -2
- package/dist/datatypes/containers/sizedbytes.js +0 -17
- package/dist/datatypes/containers/sizedbytes.test.d.ts +0 -1
- package/dist/datatypes/containers/sizedbytes.test.js +0 -27
- package/dist/datatypes/containers/string.d.ts +0 -2
- package/dist/datatypes/containers/string.js +0 -24
- package/dist/datatypes/containers/string.test.d.ts +0 -1
- package/dist/datatypes/containers/string.test.js +0 -24
- package/dist/datatypes/transforms/encode.d.ts +0 -2
- package/dist/datatypes/transforms/encode.js +0 -7
- package/dist/datatypes/transforms/fixedOffset.d.ts +0 -2
- package/dist/datatypes/transforms/fixedOffset.js +0 -18
- package/dist/datatypes/transforms/modify.d.ts +0 -2
- package/dist/datatypes/transforms/modify.js +0 -7
- package/dist/datatypes/transforms/noAdvance.d.ts +0 -16
- package/dist/datatypes/transforms/noAdvance.js +0 -30
- package/dist/datatypes/transforms/pipe.d.ts +0 -11
- package/dist/datatypes/transforms/pipe.js +0 -16
- package/dist/datatypes/utilities/remember.d.ts +0 -15
- package/dist/datatypes/utilities/remember.js +0 -36
- package/dist/datatypes/utilities/remember.test.d.ts +0 -1
- package/dist/datatypes/utilities/remember.test.js +0 -44
- package/dist/datatypes/utils.test.d.ts +0 -8
- package/dist/datatypes/utils.test.js +0 -37
- package/dist/datatypes/values/byteliteral.d.ts +0 -2
- package/dist/datatypes/values/byteliteral.js +0 -20
- package/dist/datatypes/values/json.d.ts +0 -10
- package/dist/datatypes/values/json.js +0 -21
- package/dist/transforms/fixedOffset.d.ts +0 -2
- package/dist/transforms/fixedOffset.js +0 -18
- package/dist/transforms/noAdvance.d.ts +0 -16
- package/dist/transforms/noAdvance.js +0 -30
- package/dist/transforms/noAdvance.test.d.ts +0 -1
- package/dist/transforms/noAdvance.test.js +0 -17
package/README.md
CHANGED
|
@@ -20,14 +20,14 @@ const Entity = st.object({
|
|
|
20
20
|
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
- Extremely Fast! [benchmarks](./benchmark) show equivelent performance to hand written serializers
|
|
24
|
+
- Designed to be both Web & Node.js compatible
|
|
23
25
|
- Lightweight, base size is <1KB and each datatype is a few hundred bytes
|
|
24
|
-
-
|
|
25
|
-
- Designed for both Web/Node.js compatible
|
|
26
|
-
- Easily implement your own serializers
|
|
26
|
+
- Easily extendable with your own datatypes
|
|
27
27
|
|
|
28
28
|
Each serializer is completely seperate from the base library, meaning you only pay for what you use.
|
|
29
29
|
|
|
30
|
-
## Implementing your
|
|
30
|
+
## Implementing your datatype
|
|
31
31
|
|
|
32
32
|
Implementing your own serializer is incredibly simple, heres the `f64` serializer for example
|
|
33
33
|
|
|
@@ -7,31 +7,28 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
export function array(size, type) {
|
|
10
|
-
const SHOW_ERRORS =
|
|
11
|
-
const { read: readType, write: writeType, size: typeSize } = type;
|
|
10
|
+
const SHOW_ERRORS = false;
|
|
12
11
|
return {
|
|
13
12
|
size: type.size ? size * type.size : undefined,
|
|
14
13
|
write: (ctx, value) => {
|
|
15
14
|
if (value.length !== size)
|
|
16
15
|
throw new Error("Invalid Size");
|
|
17
|
-
if (
|
|
18
|
-
ctx.
|
|
16
|
+
if (type.size)
|
|
17
|
+
ctx.reserve(size * type.size);
|
|
19
18
|
for (let i = 0; i < size; i++) {
|
|
20
|
-
if (SHOW_ERRORS)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (SHOW_ERRORS)
|
|
24
|
-
ctx.stack.pop();
|
|
19
|
+
// if (SHOW_ERRORS) ctx.path.push(`[${i}]`);
|
|
20
|
+
type.write(ctx, value[i]);
|
|
21
|
+
// if (SHOW_ERRORS) ctx.path.pop();
|
|
25
22
|
}
|
|
26
23
|
},
|
|
27
24
|
read: (ctx) => {
|
|
28
25
|
const arr = new Array(size);
|
|
29
26
|
for (let i = 0; i < size; i++) {
|
|
30
27
|
if (SHOW_ERRORS)
|
|
31
|
-
ctx.
|
|
32
|
-
arr[i] =
|
|
28
|
+
ctx.path.push(`[${i}]`);
|
|
29
|
+
arr[i] = type.read(ctx);
|
|
33
30
|
if (SHOW_ERRORS)
|
|
34
|
-
ctx.
|
|
31
|
+
ctx.path.pop();
|
|
35
32
|
}
|
|
36
33
|
return arr;
|
|
37
34
|
},
|
|
@@ -12,23 +12,23 @@ export function exhuastiveArray(type) {
|
|
|
12
12
|
let arr = [];
|
|
13
13
|
let i = 0;
|
|
14
14
|
while (ctx.offset < ctx.view.byteLength) {
|
|
15
|
-
const TRACK_STACK = i++ <
|
|
15
|
+
const TRACK_STACK = i++ < 512;
|
|
16
16
|
if (TRACK_STACK)
|
|
17
|
-
ctx.
|
|
17
|
+
ctx.path.push(`[${arr.length - 1}]`);
|
|
18
18
|
arr.push(type.read(ctx));
|
|
19
19
|
if (TRACK_STACK)
|
|
20
|
-
ctx.
|
|
20
|
+
ctx.path.pop();
|
|
21
21
|
}
|
|
22
22
|
return arr;
|
|
23
23
|
},
|
|
24
24
|
write(ctx, value) {
|
|
25
|
-
const TRACK_STACK = value.length <
|
|
25
|
+
const TRACK_STACK = value.length < 512;
|
|
26
26
|
for (let i = 0; i < value.length; i++) {
|
|
27
27
|
if (TRACK_STACK)
|
|
28
|
-
ctx.
|
|
28
|
+
ctx.path.push(`[${i}]`);
|
|
29
29
|
type.write(ctx, value[i]);
|
|
30
30
|
if (TRACK_STACK)
|
|
31
|
-
ctx.
|
|
31
|
+
ctx.path.pop();
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
};
|
|
@@ -12,29 +12,29 @@ export function list(length, type) {
|
|
|
12
12
|
return {
|
|
13
13
|
write: (ctx, value) => {
|
|
14
14
|
length.write(ctx, value.length);
|
|
15
|
-
const TRACK_STACK = value.length <
|
|
15
|
+
const TRACK_STACK = value.length < 1000;
|
|
16
16
|
if (type.size) {
|
|
17
|
-
ctx.
|
|
17
|
+
ctx.reserve(value.length * type.size);
|
|
18
18
|
}
|
|
19
19
|
for (let i = 0; i < value.length; i++) {
|
|
20
20
|
if (TRACK_STACK)
|
|
21
|
-
ctx.
|
|
21
|
+
ctx.path.push(`[${i}]`);
|
|
22
22
|
const v = value[i];
|
|
23
23
|
type.write(ctx, v);
|
|
24
24
|
if (TRACK_STACK)
|
|
25
|
-
ctx.
|
|
25
|
+
ctx.path.pop();
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
read: (ctx) => {
|
|
29
29
|
const size = length.read(ctx);
|
|
30
|
-
const TRACK_STACK = size <
|
|
30
|
+
const TRACK_STACK = size < 1000;
|
|
31
31
|
const arr = new Array(size);
|
|
32
32
|
for (let i = 0; i < size; i++) {
|
|
33
33
|
if (TRACK_STACK)
|
|
34
|
-
ctx.
|
|
34
|
+
ctx.path.push(`[${i}]`);
|
|
35
35
|
arr[i] = type.read(ctx);
|
|
36
36
|
if (TRACK_STACK)
|
|
37
|
-
ctx.
|
|
37
|
+
ctx.path.pop();
|
|
38
38
|
}
|
|
39
39
|
return arr;
|
|
40
40
|
},
|
|
@@ -19,23 +19,24 @@ export function object(definition) {
|
|
|
19
19
|
size,
|
|
20
20
|
write: (ctx, value) => {
|
|
21
21
|
if (size)
|
|
22
|
-
ctx.
|
|
22
|
+
ctx.reserve(size);
|
|
23
23
|
for (let i = 0; i < entires.length; i++) {
|
|
24
24
|
const [key, serializer] = entires[i];
|
|
25
|
-
ctx.
|
|
25
|
+
// ctx.path.push(`.${key}`);
|
|
26
26
|
serializer.write(ctx, value[key]);
|
|
27
|
-
ctx.
|
|
27
|
+
// ctx.path.pop();
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
read: (ctx) => {
|
|
31
|
-
const output =
|
|
31
|
+
const output = {};
|
|
32
32
|
for (let i = 0; i < entires.length; i++) {
|
|
33
33
|
const [key, serializer] = entires[i];
|
|
34
|
-
ctx.
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// ctx.path.push(`.${key}`);
|
|
35
|
+
//@ts-expect-error
|
|
36
|
+
output[key] = serializer.read(ctx);
|
|
37
|
+
// ctx.path.pop();
|
|
37
38
|
}
|
|
38
|
-
return
|
|
39
|
+
return output;
|
|
39
40
|
},
|
|
40
41
|
};
|
|
41
42
|
}
|
|
@@ -13,7 +13,7 @@ export function u64Bigint(endian = "little") {
|
|
|
13
13
|
size: 8,
|
|
14
14
|
write: (ctx, value) => {
|
|
15
15
|
checkValue(value, 0n, 2n ** 64n);
|
|
16
|
-
ctx.
|
|
16
|
+
ctx.reserve(8);
|
|
17
17
|
ctx.view.setBigUint64(ctx.offset, BigInt(value), endian === "little");
|
|
18
18
|
ctx.offset += 8;
|
|
19
19
|
},
|
|
@@ -34,7 +34,7 @@ export function s64Bigint(endian = "little") {
|
|
|
34
34
|
size: 8,
|
|
35
35
|
write: (ctx, value) => {
|
|
36
36
|
checkValue(value, -(2n ** 63n), 2n ** 63n);
|
|
37
|
-
ctx.
|
|
37
|
+
ctx.reserve(8);
|
|
38
38
|
ctx.view.setBigInt64(ctx.offset, BigInt(value), endian === "little");
|
|
39
39
|
ctx.offset += 8;
|
|
40
40
|
},
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/** 16bit float */
|
|
2
2
|
export function f16(endian = "little") {
|
|
3
|
+
const littleEndian = endian === "little";
|
|
3
4
|
return {
|
|
4
5
|
size: 2,
|
|
5
6
|
write: (ctx, value) => {
|
|
6
|
-
ctx.
|
|
7
|
-
ctx.view.setFloat16(ctx.offset, value,
|
|
7
|
+
ctx.reserve(2);
|
|
8
|
+
ctx.view.setFloat16(ctx.offset, value, littleEndian);
|
|
8
9
|
ctx.offset += 2;
|
|
9
10
|
},
|
|
10
11
|
read: (ctx) => {
|
|
11
|
-
const value = ctx.view.getFloat16(ctx.offset,
|
|
12
|
+
const value = ctx.view.getFloat16(ctx.offset, littleEndian);
|
|
12
13
|
ctx.offset += 2;
|
|
13
14
|
return value;
|
|
14
15
|
},
|
|
@@ -16,15 +17,16 @@ export function f16(endian = "little") {
|
|
|
16
17
|
}
|
|
17
18
|
/** 32bit float */
|
|
18
19
|
export function f32(endian = "little") {
|
|
20
|
+
const littleEndian = endian === "little";
|
|
19
21
|
return {
|
|
20
22
|
size: 4,
|
|
21
23
|
write: (ctx, value) => {
|
|
22
|
-
ctx.
|
|
23
|
-
ctx.view.setFloat32(ctx.offset, value,
|
|
24
|
+
ctx.reserve(4);
|
|
25
|
+
ctx.view.setFloat32(ctx.offset, value, littleEndian);
|
|
24
26
|
ctx.offset += 4;
|
|
25
27
|
},
|
|
26
28
|
read: (ctx) => {
|
|
27
|
-
const value = ctx.view.getFloat32(ctx.offset,
|
|
29
|
+
const value = ctx.view.getFloat32(ctx.offset, littleEndian);
|
|
28
30
|
ctx.offset += 4;
|
|
29
31
|
return value;
|
|
30
32
|
},
|
|
@@ -32,15 +34,16 @@ export function f32(endian = "little") {
|
|
|
32
34
|
}
|
|
33
35
|
/** 64bit float */
|
|
34
36
|
export function f64(endian = "little") {
|
|
37
|
+
const littleEndian = endian === "little";
|
|
35
38
|
return {
|
|
36
39
|
size: 8,
|
|
37
40
|
write: (ctx, value) => {
|
|
38
|
-
ctx.
|
|
39
|
-
ctx.view.setFloat64(ctx.offset, value,
|
|
41
|
+
ctx.reserve(8);
|
|
42
|
+
ctx.view.setFloat64(ctx.offset, value, littleEndian);
|
|
40
43
|
ctx.offset += 8;
|
|
41
44
|
},
|
|
42
45
|
read: (ctx) => {
|
|
43
|
-
const value = ctx.view.getFloat64(ctx.offset,
|
|
46
|
+
const value = ctx.view.getFloat64(ctx.offset, littleEndian);
|
|
44
47
|
ctx.offset += 8;
|
|
45
48
|
return value;
|
|
46
49
|
},
|
|
@@ -12,7 +12,7 @@ export function s8() {
|
|
|
12
12
|
size: 1,
|
|
13
13
|
write: (ctx, value) => {
|
|
14
14
|
checkValue(value, -(2 ** 7), 2 ** 7);
|
|
15
|
-
ctx.
|
|
15
|
+
ctx.reserve(1);
|
|
16
16
|
ctx.view.setInt8(ctx.offset, value);
|
|
17
17
|
ctx.offset += 1;
|
|
18
18
|
},
|
|
@@ -25,16 +25,17 @@ export function s8() {
|
|
|
25
25
|
}
|
|
26
26
|
/** 16bit signed integer */
|
|
27
27
|
export function s16(endian = "little") {
|
|
28
|
+
const littleEndian = endian === "little";
|
|
28
29
|
return {
|
|
29
30
|
size: 2,
|
|
30
31
|
write: (ctx, value) => {
|
|
31
32
|
checkValue(value, -(2 ** 15), 2 ** 15);
|
|
32
|
-
ctx.
|
|
33
|
-
ctx.view.setInt16(ctx.offset, value,
|
|
33
|
+
ctx.reserve(2);
|
|
34
|
+
ctx.view.setInt16(ctx.offset, value, littleEndian);
|
|
34
35
|
ctx.offset += 2;
|
|
35
36
|
},
|
|
36
37
|
read: (ctx) => {
|
|
37
|
-
const value = ctx.view.getInt16(ctx.offset,
|
|
38
|
+
const value = ctx.view.getInt16(ctx.offset, littleEndian);
|
|
38
39
|
ctx.offset += 2;
|
|
39
40
|
return value;
|
|
40
41
|
},
|
|
@@ -42,16 +43,17 @@ export function s16(endian = "little") {
|
|
|
42
43
|
}
|
|
43
44
|
/** 32bit signed integer */
|
|
44
45
|
export function s32(endian = "little") {
|
|
46
|
+
const littleEndian = endian === "little";
|
|
45
47
|
return {
|
|
46
48
|
size: 4,
|
|
47
49
|
write: (ctx, value) => {
|
|
48
50
|
checkValue(value, -(2 ** 31), 2 ** 31);
|
|
49
|
-
ctx.
|
|
50
|
-
ctx.view.setInt32(ctx.offset, value,
|
|
51
|
+
ctx.reserve(4);
|
|
52
|
+
ctx.view.setInt32(ctx.offset, value, littleEndian);
|
|
51
53
|
ctx.offset += 4;
|
|
52
54
|
},
|
|
53
55
|
read: (ctx) => {
|
|
54
|
-
const value = ctx.view.getInt32(ctx.offset,
|
|
56
|
+
const value = ctx.view.getInt32(ctx.offset, littleEndian);
|
|
55
57
|
ctx.offset += 4;
|
|
56
58
|
return value;
|
|
57
59
|
},
|
|
@@ -59,16 +61,17 @@ export function s32(endian = "little") {
|
|
|
59
61
|
}
|
|
60
62
|
/** 64bit signed integer */
|
|
61
63
|
export function s64(endian = "little") {
|
|
64
|
+
const littleEndian = endian === "little";
|
|
62
65
|
return {
|
|
63
66
|
size: 8,
|
|
64
67
|
write: (ctx, value) => {
|
|
65
68
|
checkValue(value, -(2 ** 63), 2 ** 63);
|
|
66
|
-
ctx.
|
|
67
|
-
ctx.view.setBigInt64(ctx.offset, BigInt(value),
|
|
69
|
+
ctx.reserve(8);
|
|
70
|
+
ctx.view.setBigInt64(ctx.offset, BigInt(value), littleEndian);
|
|
68
71
|
ctx.offset += 8;
|
|
69
72
|
},
|
|
70
73
|
read: (ctx) => {
|
|
71
|
-
const value = Number(ctx.view.getBigInt64(ctx.offset,
|
|
74
|
+
const value = Number(ctx.view.getBigInt64(ctx.offset, littleEndian));
|
|
72
75
|
ctx.offset += 8;
|
|
73
76
|
return value;
|
|
74
77
|
},
|
|
@@ -7,7 +7,7 @@ export function u8() {
|
|
|
7
7
|
throw new Error("Not Integer");
|
|
8
8
|
if (value < 0 || value >= 2 ** 8)
|
|
9
9
|
throw new Error("Out of Range");
|
|
10
|
-
ctx.
|
|
10
|
+
ctx.reserve(1);
|
|
11
11
|
ctx.view.setUint8(ctx.offset, value);
|
|
12
12
|
ctx.offset += 1;
|
|
13
13
|
},
|
|
@@ -20,6 +20,7 @@ export function u8() {
|
|
|
20
20
|
}
|
|
21
21
|
/** 16bit unsigned integer */
|
|
22
22
|
export function u16(endian = "little") {
|
|
23
|
+
const littleEndian = endian === "little";
|
|
23
24
|
return {
|
|
24
25
|
size: 2,
|
|
25
26
|
write: (ctx, value) => {
|
|
@@ -27,12 +28,12 @@ export function u16(endian = "little") {
|
|
|
27
28
|
throw new Error("Not Integer");
|
|
28
29
|
if (value < 0 || value >= 2 ** 16)
|
|
29
30
|
throw new Error("Out of Range");
|
|
30
|
-
ctx.
|
|
31
|
-
ctx.view.setUint16(ctx.offset, value,
|
|
31
|
+
ctx.reserve(2);
|
|
32
|
+
ctx.view.setUint16(ctx.offset, value, littleEndian);
|
|
32
33
|
ctx.offset += 2;
|
|
33
34
|
},
|
|
34
35
|
read: (ctx) => {
|
|
35
|
-
const value = ctx.view.getUint16(ctx.offset,
|
|
36
|
+
const value = ctx.view.getUint16(ctx.offset, littleEndian);
|
|
36
37
|
ctx.offset += 2;
|
|
37
38
|
return value;
|
|
38
39
|
},
|
|
@@ -40,6 +41,7 @@ export function u16(endian = "little") {
|
|
|
40
41
|
}
|
|
41
42
|
/** 32bit unsigned integer */
|
|
42
43
|
export function u32(endian = "little") {
|
|
44
|
+
const littleEndian = endian === "little";
|
|
43
45
|
return {
|
|
44
46
|
size: 4,
|
|
45
47
|
write: (ctx, value) => {
|
|
@@ -47,12 +49,12 @@ export function u32(endian = "little") {
|
|
|
47
49
|
throw new Error("Not Integer");
|
|
48
50
|
if (value < 0 || value >= 2 ** 32)
|
|
49
51
|
throw new Error("Out of Range");
|
|
50
|
-
ctx.
|
|
51
|
-
ctx.view.setUint32(ctx.offset, value,
|
|
52
|
+
ctx.reserve(4);
|
|
53
|
+
ctx.view.setUint32(ctx.offset, value, littleEndian);
|
|
52
54
|
ctx.offset += 4;
|
|
53
55
|
},
|
|
54
56
|
read: (ctx) => {
|
|
55
|
-
const value = ctx.view.getUint32(ctx.offset,
|
|
57
|
+
const value = ctx.view.getUint32(ctx.offset, littleEndian);
|
|
56
58
|
ctx.offset += 4;
|
|
57
59
|
return value;
|
|
58
60
|
},
|
|
@@ -60,6 +62,7 @@ export function u32(endian = "little") {
|
|
|
60
62
|
}
|
|
61
63
|
/** 64bit unsigned integer */
|
|
62
64
|
export function u64(endian = "little") {
|
|
65
|
+
const littleEndian = endian === "little";
|
|
63
66
|
return {
|
|
64
67
|
size: 8,
|
|
65
68
|
write: (ctx, value) => {
|
|
@@ -67,12 +70,12 @@ export function u64(endian = "little") {
|
|
|
67
70
|
throw new Error("Not Integer");
|
|
68
71
|
if (value < 0 || value >= 2 ** 64)
|
|
69
72
|
throw new Error("Out of Range");
|
|
70
|
-
ctx.
|
|
71
|
-
ctx.view.setBigUint64(ctx.offset, BigInt(value),
|
|
73
|
+
ctx.reserve(8);
|
|
74
|
+
ctx.view.setBigUint64(ctx.offset, BigInt(value), littleEndian);
|
|
72
75
|
ctx.offset += 8;
|
|
73
76
|
},
|
|
74
77
|
read: (ctx) => {
|
|
75
|
-
const value = Number(ctx.view.getBigUint64(ctx.offset,
|
|
78
|
+
const value = Number(ctx.view.getBigUint64(ctx.offset, littleEndian));
|
|
76
79
|
ctx.offset += 8;
|
|
77
80
|
return value;
|
|
78
81
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as st from "../../index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Fixed length bytes
|
|
4
4
|
*
|
|
@@ -6,4 +6,4 @@ import type { Serializer } from "../../types.js";
|
|
|
6
6
|
* st.bytes(4)
|
|
7
7
|
* ```
|
|
8
8
|
*/
|
|
9
|
-
export declare function bytes(size: number): Serializer<
|
|
9
|
+
export declare function bytes(size: number): st.Serializer<Uint8Array>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as st from "../../index.js";
|
|
1
2
|
/**
|
|
2
3
|
* Fixed length bytes
|
|
3
4
|
*
|
|
@@ -9,17 +10,16 @@ export function bytes(size) {
|
|
|
9
10
|
return {
|
|
10
11
|
size,
|
|
11
12
|
write: (ctx, value) => {
|
|
12
|
-
|
|
13
|
-
if (bytes.length !== size)
|
|
13
|
+
if (value.length !== size)
|
|
14
14
|
throw new Error("Invalid Length");
|
|
15
|
-
ctx.
|
|
16
|
-
|
|
15
|
+
ctx.reserve(size);
|
|
16
|
+
ctx.bytes.set(value, ctx.offset);
|
|
17
17
|
ctx.offset += size;
|
|
18
18
|
},
|
|
19
19
|
read: (ctx) => {
|
|
20
|
-
const
|
|
20
|
+
const arr = ctx.bytes.subarray(ctx.offset, ctx.offset + size);
|
|
21
21
|
ctx.offset += size;
|
|
22
|
-
return slice;
|
|
22
|
+
return arr.slice();
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
25
|
}
|
|
@@ -16,7 +16,7 @@ describe("st.bytes", () => {
|
|
|
16
16
|
const data = new Uint8Array(size);
|
|
17
17
|
data.set([3, 4], 1000);
|
|
18
18
|
data.set([3, 4], 2000);
|
|
19
|
-
encodeTest(spec, data
|
|
19
|
+
encodeTest(spec, data);
|
|
20
20
|
});
|
|
21
21
|
it("large data writes work", () => {
|
|
22
22
|
const size = 1024 * 1024 * 8; // 8MB
|
|
@@ -30,7 +30,7 @@ describe("st.bytes", () => {
|
|
|
30
30
|
data.set([3, 4], 2000);
|
|
31
31
|
encodeTest(spec, {
|
|
32
32
|
before: 1,
|
|
33
|
-
data
|
|
33
|
+
data,
|
|
34
34
|
after: 2,
|
|
35
35
|
});
|
|
36
36
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Serializer } from "../../types.js";
|
|
2
|
-
export declare function sizedBytes(length: Serializer<number>): Serializer<
|
|
2
|
+
export declare function sizedBytes(length: Serializer<number>): Serializer<Uint8Array>;
|
|
@@ -2,14 +2,13 @@ export function sizedBytes(length) {
|
|
|
2
2
|
return {
|
|
3
3
|
write: (ctx, value) => {
|
|
4
4
|
length.write(ctx, value.byteLength);
|
|
5
|
-
|
|
6
|
-
ctx.
|
|
7
|
-
new Uint8Array(ctx.view.buffer).set(bytes, ctx.offset);
|
|
5
|
+
ctx.reserve(value.byteLength);
|
|
6
|
+
ctx.bytes.set(value, ctx.offset);
|
|
8
7
|
ctx.offset += value.byteLength;
|
|
9
8
|
},
|
|
10
9
|
read: (ctx) => {
|
|
11
10
|
const size = length.read(ctx);
|
|
12
|
-
const slice = ctx.
|
|
11
|
+
const slice = ctx.bytes.subarray(ctx.offset, ctx.offset + size);
|
|
13
12
|
ctx.offset += size;
|
|
14
13
|
return slice;
|
|
15
14
|
},
|
|
@@ -16,7 +16,7 @@ describe("st.sizedBytes", () => {
|
|
|
16
16
|
const data = new Uint8Array(size);
|
|
17
17
|
data.set([3, 4], 1000);
|
|
18
18
|
data.set([3, 4], 2000);
|
|
19
|
-
encodeTest(spec, data
|
|
19
|
+
encodeTest(spec, data);
|
|
20
20
|
});
|
|
21
21
|
it("errors on invalid length", () => {
|
|
22
22
|
encodeFailTest(st.sizedBytes(st.u8()), //
|
|
@@ -20,10 +20,9 @@ export function string(length) {
|
|
|
20
20
|
throw new Error("Expected String");
|
|
21
21
|
const bytes = encoder.encode(value);
|
|
22
22
|
const size = bytes.byteLength;
|
|
23
|
-
ctx.
|
|
23
|
+
ctx.reserve(size + lengthSize);
|
|
24
24
|
length.write(ctx, size);
|
|
25
|
-
|
|
26
|
-
arr.set(bytes);
|
|
25
|
+
ctx.bytes.set(bytes, ctx.offset);
|
|
27
26
|
ctx.offset += size;
|
|
28
27
|
},
|
|
29
28
|
read: (ctx) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { InferOutput as Infer, InferInput, InferOutput, ReaderContext, WriterContext, Serializer, } from "./types.js";
|
|
2
|
-
export { read
|
|
3
|
-
export { write,
|
|
2
|
+
export { read } from "./read.js";
|
|
3
|
+
export { write, writeInto } from "./write.js";
|
|
4
4
|
export * from "./datatypes/index.js";
|
|
5
5
|
export * from "./transforms/index.js";
|
|
6
6
|
export * from "./utilities/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { read
|
|
2
|
-
export { write,
|
|
1
|
+
export { read } from "./read.js";
|
|
2
|
+
export { write, writeInto } from "./write.js";
|
|
3
3
|
export * from "./datatypes/index.js";
|
|
4
4
|
export * from "./transforms/index.js";
|
|
5
5
|
export * from "./utilities/index.js";
|
package/dist/read.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type { Serializer
|
|
2
|
-
export declare function read<TIn, TOut>(serializer: Serializer<TIn, TOut>, buffer: ArrayBuffer): TOut;
|
|
3
|
-
export declare function createReaderContext(buffer: ArrayBuffer): ReaderContext;
|
|
1
|
+
import type { Serializer } from "./types.js";
|
|
2
|
+
export declare function read<TIn, TOut>(serializer: Serializer<TIn, TOut>, buffer: ArrayBuffer | SharedArrayBuffer, offset?: number): TOut;
|
package/dist/read.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
export function read(serializer, buffer) {
|
|
2
|
-
const ctx =
|
|
1
|
+
export function read(serializer, buffer, offset) {
|
|
2
|
+
const ctx = {
|
|
3
|
+
buffer: buffer,
|
|
4
|
+
view: new DataView(buffer),
|
|
5
|
+
bytes: new Uint8Array(buffer),
|
|
6
|
+
path: [],
|
|
7
|
+
offset: offset ?? 0,
|
|
8
|
+
};
|
|
3
9
|
try {
|
|
4
10
|
return serializer.read(ctx);
|
|
5
11
|
}
|
|
6
12
|
catch (e) {
|
|
7
|
-
const path = ctx.
|
|
8
|
-
throw new Error(`Deserialization error at serializer${path}`, { cause: e });
|
|
13
|
+
const path = ctx.path.join("") ?? "root";
|
|
14
|
+
throw new Error(`Deserialization error at serializer${path}\n${e}`, { cause: e });
|
|
9
15
|
}
|
|
10
16
|
}
|
|
11
|
-
export function createReaderContext(buffer) {
|
|
12
|
-
return {
|
|
13
|
-
stack: [],
|
|
14
|
-
offset: 0,
|
|
15
|
-
buffer,
|
|
16
|
-
view: new DataView(buffer),
|
|
17
|
-
};
|
|
18
|
-
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function enum_<const T>(values: T[]): import("./pipe.
|
|
1
|
+
export declare function enum_<const T>(values: T[]): import("./pipe.ts").Transform<T, any>;
|
|
2
2
|
export { enum_ as enum };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function literal<const T>(value: T): import("./pipe.
|
|
1
|
+
export declare function literal<const T>(value: T): import("./pipe.ts").Transform<T, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function toAscii(): import("./pipe.
|
|
1
|
+
export declare function toAscii(): import("./pipe.ts").Transform<string, Uint8Array<ArrayBufferLike>>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { encode } from "./encode.js";
|
|
2
2
|
export function toAscii() {
|
|
3
3
|
return encode({
|
|
4
|
-
encode: (v) => new Uint8Array(Array.from(v).map((char) => validateAscii(char.charCodeAt(0))))
|
|
5
|
-
decode: (v) => Array.from(
|
|
4
|
+
encode: (v) => new Uint8Array(Array.from(v).map((char) => validateAscii(char.charCodeAt(0)))),
|
|
5
|
+
decode: (v) => Array.from(v)
|
|
6
6
|
.map((v) => String.fromCharCode(v))
|
|
7
7
|
.join(""),
|
|
8
8
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function toBase64(): import("./pipe.
|
|
1
|
+
export declare function toBase64(): import("./pipe.ts").Transform<string, Uint8Array<ArrayBufferLike>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { encode } from "./encode.js";
|
|
2
2
|
export function toBase64() {
|
|
3
3
|
return encode({
|
|
4
|
-
encode: (v) => Uint8Array.fromBase64(v)
|
|
5
|
-
decode: (v) =>
|
|
4
|
+
encode: (v) => Uint8Array.fromBase64(v),
|
|
5
|
+
decode: (v) => v.toBase64(),
|
|
6
6
|
});
|
|
7
7
|
}
|
|
@@ -10,4 +10,4 @@
|
|
|
10
10
|
*
|
|
11
11
|
* `ArrayBuffer([0, 255, c])` => `[0, 255, ArrayBuffer([0, 255, 0])]`
|
|
12
12
|
*/
|
|
13
|
-
export declare function toBytes(): import("./pipe.
|
|
13
|
+
export declare function toBytes(): import("./pipe.ts").Transform<number[], Uint8Array<ArrayBufferLike>>;
|
|
@@ -13,8 +13,8 @@ import { encode } from "./encode.js";
|
|
|
13
13
|
*/
|
|
14
14
|
export function toBytes() {
|
|
15
15
|
return encode({
|
|
16
|
-
encode: (v) => new Uint8Array(v.map(validateByte))
|
|
17
|
-
decode: (v) => Array.from(
|
|
16
|
+
encode: (v) => new Uint8Array(v.map(validateByte)),
|
|
17
|
+
decode: (v) => Array.from(v),
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
const validateByte = (v) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Converts an
|
|
2
|
+
* Converts an Uint8Array to uppercase hex
|
|
3
3
|
*
|
|
4
4
|
* ```ts
|
|
5
5
|
* st.pipe(
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* )
|
|
9
9
|
* ```
|
|
10
10
|
*
|
|
11
|
-
* `
|
|
11
|
+
* `Uint8Array([0, 255, 0])` => `00FF00`
|
|
12
12
|
*/
|
|
13
|
-
export declare function toHex(): import("./pipe.
|
|
13
|
+
export declare function toHex(): import("./pipe.ts").Transform<string, Uint8Array<ArrayBufferLike>>;
|