json-as 1.3.9 → 1.5.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.
Files changed (122) hide show
  1. package/CHANGELOG.md +60 -19
  2. package/README.md +120 -21
  3. package/assembly/custom/chars.ts +39 -78
  4. package/assembly/deserialize/index/arbitrary.ts +28 -10
  5. package/assembly/deserialize/index/float.ts +2 -4
  6. package/assembly/deserialize/index/integer.ts +2 -4
  7. package/assembly/deserialize/index/object.ts +6 -1
  8. package/assembly/deserialize/index/string.ts +2 -7
  9. package/assembly/deserialize/index/unsigned.ts +2 -4
  10. package/assembly/deserialize/naive/array/arbitrary.ts +3 -136
  11. package/assembly/deserialize/naive/array/array.ts +30 -1
  12. package/assembly/deserialize/naive/array/integer.ts +2 -7
  13. package/assembly/deserialize/naive/array/map.ts +10 -14
  14. package/assembly/deserialize/naive/array/object.ts +10 -14
  15. package/assembly/deserialize/naive/array/struct.ts +19 -1
  16. package/assembly/deserialize/naive/bool.ts +1 -5
  17. package/assembly/deserialize/naive/date.ts +1 -2
  18. package/assembly/deserialize/naive/float.ts +4 -11
  19. package/assembly/deserialize/naive/integer.ts +2 -4
  20. package/assembly/deserialize/naive/map.ts +42 -205
  21. package/assembly/deserialize/naive/object.ts +291 -174
  22. package/assembly/deserialize/naive/raw.ts +1 -5
  23. package/assembly/deserialize/naive/set.ts +3 -6
  24. package/assembly/deserialize/naive/staticarray.ts +2 -4
  25. package/assembly/deserialize/naive/string.ts +68 -24
  26. package/assembly/deserialize/naive/typedarray.ts +1 -2
  27. package/assembly/deserialize/naive/unsigned.ts +2 -4
  28. package/assembly/deserialize/simd/array/integer.ts +5 -13
  29. package/assembly/deserialize/simd/float.ts +5 -12
  30. package/assembly/deserialize/simd/integer.ts +6 -15
  31. package/assembly/deserialize/simd/string.ts +21 -43
  32. package/assembly/deserialize/swar/array/arbitrary.ts +1 -2
  33. package/assembly/deserialize/swar/array/array.ts +2 -4
  34. package/assembly/deserialize/swar/array/bool.ts +2 -4
  35. package/assembly/deserialize/swar/array/box.ts +1 -2
  36. package/assembly/deserialize/swar/array/float.ts +8 -21
  37. package/assembly/deserialize/swar/array/generic.ts +2 -4
  38. package/assembly/deserialize/swar/array/integer.ts +13 -27
  39. package/assembly/deserialize/swar/array/map.ts +1 -2
  40. package/assembly/deserialize/swar/array/object.ts +2 -4
  41. package/assembly/deserialize/swar/array/raw.ts +1 -2
  42. package/assembly/deserialize/swar/array/shared.ts +9 -21
  43. package/assembly/deserialize/swar/array/string.ts +4 -10
  44. package/assembly/deserialize/swar/array/struct.ts +3 -9
  45. package/assembly/deserialize/swar/array.ts +1 -3
  46. package/assembly/deserialize/swar/float.ts +7 -17
  47. package/assembly/deserialize/swar/integer.ts +6 -15
  48. package/assembly/deserialize/swar/string.ts +40 -54
  49. package/assembly/deserialize/swar/typedarray.ts +4 -4
  50. package/assembly/index.d.ts +259 -21
  51. package/assembly/index.ts +1704 -266
  52. package/assembly/serialize/index/arbitrary.ts +70 -4
  53. package/assembly/serialize/index/jsonarray.ts +51 -0
  54. package/assembly/serialize/index/object.ts +39 -14
  55. package/assembly/serialize/index/string.ts +1 -2
  56. package/assembly/serialize/index/typedarray.ts +1 -2
  57. package/assembly/serialize/index.ts +1 -0
  58. package/assembly/serialize/naive/array.ts +23 -34
  59. package/assembly/serialize/naive/bool.ts +0 -1
  60. package/assembly/serialize/naive/float.ts +16 -25
  61. package/assembly/serialize/naive/integer.ts +1 -5
  62. package/assembly/serialize/naive/raw.ts +1 -2
  63. package/assembly/serialize/naive/set.ts +0 -4
  64. package/assembly/serialize/naive/staticarray.ts +0 -5
  65. package/assembly/serialize/naive/string.ts +11 -7
  66. package/assembly/serialize/naive/typedarray.ts +0 -6
  67. package/assembly/serialize/simd/string.ts +1 -3
  68. package/assembly/serialize/swar/string.ts +2 -4
  69. package/assembly/util/atoi-fast.ts +4 -14
  70. package/assembly/util/atoi.ts +1 -2
  71. package/assembly/util/bytes.ts +1 -2
  72. package/assembly/util/idofd.ts +1 -2
  73. package/assembly/util/isSpace.ts +1 -2
  74. package/assembly/util/itoa-fast.ts +9 -15
  75. package/assembly/util/nextPowerOf2.ts +1 -2
  76. package/assembly/util/parsefloat-fast.ts +4 -7
  77. package/assembly/util/ptrToStr.ts +1 -2
  78. package/assembly/util/scanValueEnd.ts +1 -2
  79. package/assembly/util/scanValueEndSimd.ts +198 -0
  80. package/assembly/util/scanValueEndSwar.ts +184 -0
  81. package/assembly/util/scientific.ts +8 -14
  82. package/assembly/util/simd-int.ts +4 -8
  83. package/assembly/util/snp.ts +2 -7
  84. package/assembly/util/stringScan.ts +2 -4
  85. package/assembly/util/swar-int.ts +8 -16
  86. package/assembly/util/swar.ts +2 -4
  87. package/lib/as-bs.ts +57 -42
  88. package/package.json +27 -10
  89. package/transform/lib/builder.d.ts +0 -1
  90. package/transform/lib/builder.js +0 -1
  91. package/transform/lib/index.d.ts +0 -1
  92. package/transform/lib/index.js +617 -326
  93. package/transform/lib/linkers/alias.d.ts +0 -1
  94. package/transform/lib/linkers/alias.js +0 -1
  95. package/transform/lib/linkers/custom.d.ts +0 -1
  96. package/transform/lib/linkers/custom.js +0 -1
  97. package/transform/lib/linkers/imports.d.ts +0 -1
  98. package/transform/lib/linkers/imports.js +0 -1
  99. package/transform/lib/types.d.ts +4 -2
  100. package/transform/lib/types.js +5 -1
  101. package/transform/lib/util.d.ts +0 -1
  102. package/transform/lib/util.js +0 -1
  103. package/transform/lib/visitor.d.ts +0 -1
  104. package/transform/lib/visitor.js +0 -1
  105. package/assembly/util/dragonbox-cache.ts +0 -445
  106. package/assembly/util/dragonbox.ts +0 -660
  107. package/transform/lib/builder.d.ts.map +0 -1
  108. package/transform/lib/builder.js.map +0 -1
  109. package/transform/lib/index.d.ts.map +0 -1
  110. package/transform/lib/index.js.map +0 -1
  111. package/transform/lib/linkers/alias.d.ts.map +0 -1
  112. package/transform/lib/linkers/alias.js.map +0 -1
  113. package/transform/lib/linkers/custom.d.ts.map +0 -1
  114. package/transform/lib/linkers/custom.js.map +0 -1
  115. package/transform/lib/linkers/imports.d.ts.map +0 -1
  116. package/transform/lib/linkers/imports.js.map +0 -1
  117. package/transform/lib/types.d.ts.map +0 -1
  118. package/transform/lib/types.js.map +0 -1
  119. package/transform/lib/util.d.ts.map +0 -1
  120. package/transform/lib/util.js.map +0 -1
  121. package/transform/lib/visitor.d.ts.map +0 -1
  122. package/transform/lib/visitor.js.map +0 -1
@@ -82,8 +82,7 @@
82
82
  * @param srcStart Pointer to 16 source bytes (8 UTF-16 chars).
83
83
  * @returns The parsed 8-digit value, or `U32.MAX_VALUE` on invalid input.
84
84
  */
85
- // @ts-expect-error: @inline is a valid decorator
86
- @inline export function parse8Digits_SIMD(srcStart: usize): u32 {
85
+ export function parse8Digits_SIMD(srcStart: usize): u32 {
87
86
  const block = load<v128>(srcStart);
88
87
  const digits = i16x8.sub(block, SPLAT_30);
89
88
  if (v128.any_true(i16x8.gt_u(digits, SPLAT_09))) return U32.MAX_VALUE;
@@ -104,8 +103,7 @@
104
103
  * @param srcStart Pointer to 16 source bytes (8 UTF-16 chars).
105
104
  * @returns The parsed 8-digit value.
106
105
  */
107
- // @ts-expect-error: @inline is a valid decorator
108
- @inline export function parse8Digits_SIMD_Unsafe(srcStart: usize): u32 {
106
+ export function parse8Digits_SIMD_Unsafe(srcStart: usize): u32 {
109
107
  const block = load<v128>(srcStart);
110
108
  const digits = i16x8.sub(block, SPLAT_30);
111
109
  const packed = i8x16.narrow_i16x8_u(digits, ZERO_I16X8);
@@ -132,8 +130,7 @@
132
130
  * @param srcStart Pointer to 32 source bytes (16 UTF-16 chars).
133
131
  * @returns The parsed 16-digit value, or `U64.MAX_VALUE` on invalid input.
134
132
  */
135
- // @ts-expect-error: @inline is a valid decorator
136
- @inline export function parse16Digits_SIMD(srcStart: usize): u64 {
133
+ export function parse16Digits_SIMD(srcStart: usize): u64 {
137
134
  const block0 = load<v128>(srcStart);
138
135
  const block1 = load<v128>(srcStart, 16);
139
136
 
@@ -168,8 +165,7 @@
168
165
  * @param srcStart Pointer to 32 source bytes (16 UTF-16 chars).
169
166
  * @returns The parsed 16-digit value.
170
167
  */
171
- // @ts-expect-error: @inline is a valid decorator
172
- @inline export function parse16Digits_SIMD_Unsafe(srcStart: usize): u64 {
168
+ export function parse16Digits_SIMD_Unsafe(srcStart: usize): u64 {
173
169
  const block0 = load<v128>(srcStart);
174
170
  const block1 = load<v128>(srcStart, 16);
175
171
  const digits0 = i16x8.sub(block0, SPLAT_30);
@@ -6,11 +6,7 @@
6
6
  import { POW_TEN_TABLE_32, POW_TEN_TABLE_64 } from "../globals/tables";
7
7
  import { atoi } from "./atoi";
8
8
 
9
- // @ts-ignore: Decorator valid here
10
- @inline export function snp<T extends number>(
11
- srcStart: usize,
12
- srcEnd: usize,
13
- ): T {
9
+ export function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
14
10
  // @ts-ignore: type
15
11
  let val: T = 0;
16
12
  let char = load<u16>(srcStart) - 48;
@@ -62,8 +58,7 @@ import { atoi } from "./atoi";
62
58
  }
63
59
  }
64
60
 
65
- // @ts-ignore: Decorator valid here
66
- @inline function pow10<T extends number>(x: u16): T {
61
+ function pow10<T extends number>(x: u16): T {
67
62
  if (sizeof<T>() == 8) {
68
63
  return <T>load<u64>(POW_TEN_TABLE_64 + x);
69
64
  } else {
@@ -1,7 +1,6 @@
1
1
  import { BACK_SLASH, QUOTE } from "../custom/chars";
2
2
 
3
- // @ts-ignore
4
- @inline export function isUnescapedQuote(ptr: usize): bool {
3
+ export function isUnescapedQuote(ptr: usize): bool {
5
4
  if (load<u16>(ptr) != QUOTE) return false;
6
5
 
7
6
  let escaped = false;
@@ -13,8 +12,7 @@ import { BACK_SLASH, QUOTE } from "../custom/chars";
13
12
  return !escaped;
14
13
  }
15
14
 
16
- // @ts-ignore
17
- @inline export function scanStringEnd(ptr: usize, end: usize): usize {
15
+ export function scanStringEnd(ptr: usize, end: usize): usize {
18
16
  ptr += 2;
19
17
  while (ptr < end) {
20
18
  if (load<u16>(ptr) == QUOTE && isUnescapedQuote(ptr)) return ptr;
@@ -26,8 +26,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
26
26
  * @param block Four UTF-16 code units packed into a `u64`.
27
27
  * @returns The parsed 4-digit value, or `U32.MAX_VALUE` on invalid input.
28
28
  */
29
- // @ts-expect-error: @inline is a valid decorator
30
- @inline export function parse4Digits_Baseline(block: u64): u32 {
29
+ export function parse4Digits_Baseline(block: u64): u32 {
31
30
  const digits = (block & LANE_LO_4) - ZERO_4;
32
31
  if (((digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4) != 0) {
33
32
  return U32.MAX_VALUE;
@@ -58,8 +57,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
58
57
  * @param block Four UTF-16 code units packed into a `u64`.
59
58
  * @returns The parsed 4-digit value, or `U32.MAX_VALUE` on invalid input.
60
59
  */
61
- // @ts-expect-error: @inline is a valid decorator
62
- @inline export function parse4Digits_PairMul(block: u64): u32 {
60
+ export function parse4Digits_PairMul(block: u64): u32 {
63
61
  const digits = block - ZERO_4;
64
62
  if (((digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4) != 0) {
65
63
  return U32.MAX_VALUE;
@@ -76,8 +74,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
76
74
  * @param block Four UTF-16 code units packed into a `u64`.
77
75
  * @returns The parsed 4-digit value.
78
76
  */
79
- // @ts-expect-error: @inline is a valid decorator
80
- @inline export function parse4Digits_PairMul_Unsafe(block: u64): u32 {
77
+ export function parse4Digits_PairMul_Unsafe(block: u64): u32 {
81
78
  const digits = block - ZERO_4;
82
79
  const pairs = (digits * 10 + (digits >> 16)) & U32_LO_PAIR;
83
80
  return <u32>((pairs * FINAL_4_MAGIC) >> 32);
@@ -97,8 +94,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
97
94
  * @param hi The second `u64`, four UTF-16 code units.
98
95
  * @returns The parsed 8-digit value, or `U32.MAX_VALUE` on invalid input.
99
96
  */
100
- // @ts-expect-error: @inline is a valid decorator
101
- @inline export function parse8Digits_PairMul(lo: u64, hi: u64): u32 {
97
+ export function parse8Digits_PairMul(lo: u64, hi: u64): u32 {
102
98
  const loDigits = lo - ZERO_4;
103
99
  const hiDigits = hi - ZERO_4;
104
100
  const bad =
@@ -124,8 +120,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
124
120
  * @param hi The second `u64`, four UTF-16 code units.
125
121
  * @returns The parsed 8-digit value.
126
122
  */
127
- // @ts-expect-error: @inline is a valid decorator
128
- @inline export function parse8Digits_PairMul_Unsafe(lo: u64, hi: u64): u32 {
123
+ export function parse8Digits_PairMul_Unsafe(lo: u64, hi: u64): u32 {
129
124
  const loDigits = lo - ZERO_4;
130
125
  const hiDigits = hi - ZERO_4;
131
126
  const loPairs = (loDigits * 10 + (loDigits >> 16)) & U32_LO_PAIR;
@@ -150,8 +145,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
150
145
  * @param block Four UTF-16 code units packed into a `u64`.
151
146
  * @returns A mask with non-digit lanes flagged in their high bit, or 0.
152
147
  */
153
- // @ts-expect-error: @inline is a valid decorator
154
- @inline export function nonDigitMask4(block: u64): u64 {
148
+ export function nonDigitMask4(block: u64): u64 {
155
149
  const digits = (block & LANE_LO_4) - ZERO_4;
156
150
  return (digits | (digits + RANGE_ADD_4)) & RANGE_MASK_4;
157
151
  }
@@ -174,8 +168,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
174
168
  * @param srcStart Pointer to the start of 32 source bytes (16 UTF-16 chars).
175
169
  * @returns The parsed 16-digit value, or `U64.MAX_VALUE` on invalid input.
176
170
  */
177
- // @ts-expect-error: @inline is a valid decorator
178
- @inline export function parse16Digits_SWAR(srcStart: usize): u64 {
171
+ export function parse16Digits_SWAR(srcStart: usize): u64 {
179
172
  const b0 = load<u64>(srcStart);
180
173
  const b1 = load<u64>(srcStart, 8);
181
174
  const b2 = load<u64>(srcStart, 16);
@@ -220,8 +213,7 @@ const FINAL_4_MAGIC: u64 = 0x0000_0064_0000_0001;
220
213
  * @param srcStart Pointer to the start of 32 source bytes (16 UTF-16 chars).
221
214
  * @returns The parsed 16-digit value.
222
215
  */
223
- // @ts-expect-error: @inline is a valid decorator
224
- @inline export function parse16Digits_SWAR_Unsafe(srcStart: usize): u64 {
216
+ export function parse16Digits_SWAR_Unsafe(srcStart: usize): u64 {
225
217
  const b0 = load<u64>(srcStart);
226
218
  const b1 = load<u64>(srcStart, 8);
227
219
  const b2 = load<u64>(srcStart, 16);
@@ -18,8 +18,7 @@
18
18
  * @param block Packed UTF-16 ASCII hex digits.
19
19
  * @returns The decoded 16-bit value.
20
20
  */
21
- // @ts-expect-error: @inline is a valid decorator
22
- @inline export function hex4_to_u16_swar(block: u64): u16 {
21
+ export function hex4_to_u16_swar(block: u64): u16 {
23
22
  // (c & 0xF) + 9 * (c >> 6)
24
23
  block = (block & 0x0f000f000f000f) + ((block >> 6) & 0x03000300030003) * 9;
25
24
 
@@ -51,8 +50,7 @@
51
50
  * @param code The 16-bit value to encode.
52
51
  * @returns Four packed UTF-16 ASCII hex digits.
53
52
  */
54
- // @ts-expect-error: @inline is a valid decorator
55
- @inline export function u16_to_hex4_swar(code: u16): u64 {
53
+ export function u16_to_hex4_swar(code: u16): u64 {
56
54
  let block =
57
55
  (<u64>((code >> 12) & 0xf)) |
58
56
  ((<u64>((code >> 8) & 0xf)) << 16) |
package/lib/as-bs.ts CHANGED
@@ -40,15 +40,13 @@ export namespace bs {
40
40
  * Using bit shifts for efficiency: alpha = 1/8, so (1 - alpha) = 7/8
41
41
  * @param newSize - The new size to incorporate into the average
42
42
  */
43
- // @ts-expect-error: @inline is a valid decorator
44
- @inline function updateTypicalSize(newSize: usize): void {
43
+ function updateTypicalSize(newSize: usize): void {
45
44
  // EMA: typicalSize = (newSize >> 3) + typicalSize - (typicalSize >> 3)
46
45
  // Simplified: typicalSize += (newSize - typicalSize) >> 3
47
46
  typicalSize += (newSize - typicalSize) >> EMA_ALPHA_SHIFT;
48
47
  }
49
48
 
50
- // @ts-expect-error: @inline is a valid decorator
51
- @inline function renewBuffer(newSize: usize): void {
49
+ function renewBuffer(newSize: usize): void {
52
50
  const oldPtr = buffer;
53
51
  const relOffset = offset - oldPtr;
54
52
  const newPtr = heap.realloc(oldPtr, newSize);
@@ -57,8 +55,7 @@ export namespace bs {
57
55
  bufferSize = newSize;
58
56
  }
59
57
 
60
- // @ts-expect-error: @inline is a valid decorator
61
- @inline function reserve(requiredSize: usize, extra: usize): void {
58
+ function reserve(requiredSize: usize, extra: usize): void {
62
59
  if (requiredSize <= bufferSize) return;
63
60
  // Grow aggressively (2x) to minimize realloc frequency in hot serialization paths.
64
61
  let next = bufferSize << 1;
@@ -67,8 +64,7 @@ export namespace bs {
67
64
  renewBuffer(next);
68
65
  }
69
66
 
70
- // @ts-expect-error: @inline is a valid decorator
71
- @inline function finalizeDynamicOutput(len: usize): void {
67
+ function finalizeDynamicOutput(len: usize): void {
72
68
  counter += 1;
73
69
  updateTypicalSize(len);
74
70
  if ((counter & SHRINK_EVERY_N_MASK) == 0 && bufferSize > typicalSize << 2) {
@@ -83,8 +79,7 @@ export namespace bs {
83
79
  /**
84
80
  * Stores the state of the buffer, allowing further changes to be reset
85
81
  */
86
- // @ts-expect-error: @inline is a valid decorator
87
- @inline export function saveState(): void {
82
+ export function saveState(): void {
88
83
  pauseOffsets.push(offset - buffer);
89
84
  pauseStackSizes.push(stackSize);
90
85
  }
@@ -93,8 +88,7 @@ export namespace bs {
93
88
  * Resets the buffer to the state it was in when `pause()` was called.
94
89
  * This allows for changes made after the pause to be discarded.
95
90
  */
96
- // @ts-expect-error: @inline is a valid decorator
97
- @inline export function loadState(): void {
91
+ export function loadState(): void {
98
92
  const length = pauseOffsets.length;
99
93
  if (length == 0) return;
100
94
  const index = length - 1;
@@ -109,8 +103,7 @@ export namespace bs {
109
103
  * serialize/deserialize op mid-flight: a partial run can leave `offset`
110
104
  * advanced and the pause stacks non-empty, which would corrupt the next op.
111
105
  */
112
- // @ts-expect-error: @inline is a valid decorator
113
- @inline export function reset(): void {
106
+ export function reset(): void {
114
107
  offset = buffer;
115
108
  stackSize = 0;
116
109
  pauseOffsets.length = 0;
@@ -122,8 +115,7 @@ export namespace bs {
122
115
  * If necessary, reallocates the buffer to the exact new size.
123
116
  * @param size - The size to propose.
124
117
  */
125
- // @ts-expect-error: @inline is a valid decorator
126
- @inline export function ensureSize(size: u32): void {
118
+ export function ensureSize(size: u32): void {
127
119
  reserve(offset - buffer + usize(size), MIN_BUFFER_SIZE);
128
120
  }
129
121
 
@@ -132,8 +124,7 @@ export namespace bs {
132
124
  * If necessary, reallocates the buffer to the exact new size.
133
125
  * @param size - The size to propose.w
134
126
  */
135
- // @ts-expect-error: @inline is a valid decorator
136
- @inline export function proposeSize(size: u32): void {
127
+ export function proposeSize(size: u32): void {
137
128
  stackSize += size;
138
129
  reserve(stackSize, 0);
139
130
  }
@@ -143,8 +134,7 @@ export namespace bs {
143
134
  * If necessary, reallocates the buffer to the exact new size.
144
135
  * @param size - The size to grow by.
145
136
  */
146
- // @ts-expect-error: @inline is a valid decorator
147
- @inline export function growSize(size: u32): void {
137
+ export function growSize(size: u32): void {
148
138
  stackSize += size;
149
139
  reserve(stackSize, MIN_BUFFER_SIZE);
150
140
  }
@@ -153,8 +143,7 @@ export namespace bs {
153
143
  * Resizes the buffer to the specified size.
154
144
  * @param newSize - The new buffer size.
155
145
  */
156
- // @ts-expect-error: @inline is a valid decorator
157
- @inline export function resize(newSize: u32): void {
146
+ export function resize(newSize: u32): void {
158
147
  const oldPtr = buffer;
159
148
  const relOffset = offset - oldPtr;
160
149
  const newPtr = heap.realloc(buffer, newSize);
@@ -168,8 +157,7 @@ export namespace bs {
168
157
  * finalization. Keeps enough capacity for the recent typical output size while
169
158
  * releasing clearly excess memory.
170
159
  */
171
- // @ts-expect-error: @inline is a valid decorator
172
- @inline export function shrink(): void {
160
+ export function shrink(): void {
173
161
  let next = typicalSize << 1;
174
162
  if (next < MIN_BUFFER_SIZE) next = MIN_BUFFER_SIZE;
175
163
  if (bufferSize > next) {
@@ -184,8 +172,7 @@ export namespace bs {
184
172
  * Copies the buffer's content to a new object of a specified type. Does not shrink the buffer.
185
173
  * @returns The new object containing the buffer's content.
186
174
  */
187
- // @ts-expect-error: @inline is a valid decorator
188
- @inline export function cpyOut<T>(): T {
175
+ export function cpyOut<T>(): T {
189
176
  if (pauseOffsets.length == 0) {
190
177
  const len = offset - buffer;
191
178
  // @ts-expect-error: __new is a runtime builtin
@@ -214,8 +201,7 @@ export namespace bs {
214
201
  * Note: this restores only `offset`. Deserialization paths do not currently depend on
215
202
  * `stackSize`, which is tracked for serialization growth heuristics.
216
203
  */
217
- // @ts-expect-error: @inline is a valid decorator
218
- @inline export function sliceOut<T>(start: usize): T {
204
+ export function sliceOut<T>(start: usize): T {
219
205
  const sliceStart = buffer + start;
220
206
  const len = offset - sliceStart;
221
207
  // @ts-expect-error: __new is a runtime builtin
@@ -229,8 +215,7 @@ export namespace bs {
229
215
  * Copies the slice starting at a caller-provided relative buffer offset into a string field
230
216
  * and restores `offset` back to that slice start.
231
217
  */
232
- // @ts-expect-error: @inline is a valid decorator
233
- @inline export function toField(start: usize, dstFieldPtr: usize): void {
218
+ export function toField(start: usize, dstFieldPtr: usize): void {
234
219
  const sliceStart = buffer + start;
235
220
  const byteLength = <u32>(offset - sliceStart);
236
221
  if (byteLength == 0) {
@@ -265,8 +250,7 @@ export namespace bs {
265
250
  * adaptive buffer management - shrinks buffer when consistently oversized.
266
251
  * @returns The new object containing the buffer's content.
267
252
  */
268
- // @ts-expect-error: @inline is a valid decorator
269
- @inline export function out<T>(): T {
253
+ export function out<T>(): T {
270
254
  let out: usize;
271
255
  if (cacheOutput === 0) {
272
256
  const len = offset - buffer;
@@ -287,6 +271,42 @@ export namespace bs {
287
271
  }
288
272
  return changetype<T>(out);
289
273
  }
274
+
275
+ /**
276
+ * Like `out<T>()`, but writes the finished bytes into the existing object
277
+ * `target`, reusing its allocation: an in-place overwrite when the size
278
+ * already matches, `__renew` when it differs. Falls back to a fresh
279
+ * `out<T>()` when `target` is null or a static (`< __heap_base`), so callers
280
+ * can pass an empty/uninitialized target on the first call. Mirrors the reuse
281
+ * policy of `toField`, but for the top-level return value.
282
+ */
283
+ export function outTo<T>(target: usize): T {
284
+ if (target < __heap_base) return out<T>();
285
+ let len: usize;
286
+ let src: usize;
287
+ if (cacheOutput === 0) {
288
+ len = offset - buffer;
289
+ src = buffer;
290
+ } else {
291
+ len = cacheOutputLen;
292
+ src = cacheOutput;
293
+ }
294
+ let dst = target;
295
+ if (changetype<OBJECT>(target - TOTAL_OVERHEAD).rtSize != <u32>len) {
296
+ // @ts-expect-error: __renew is a runtime builtin
297
+ dst = __renew(target, len);
298
+ }
299
+ memory.copy(dst, src, len);
300
+ if (cacheOutput === 0) {
301
+ finalizeDynamicOutput(len);
302
+ } else {
303
+ cacheOutput = 0;
304
+ cacheOutputLen = 0;
305
+ offset = buffer;
306
+ stackSize = 0;
307
+ }
308
+ return changetype<T>(dst);
309
+ }
290
310
  }
291
311
 
292
312
  /**
@@ -334,12 +354,9 @@ export namespace bs {
334
354
  * avoiding re-serialization of previously seen strings.
335
355
  */
336
356
  export namespace sc {
337
- // @ts-expect-error: @inline is a valid decorator
338
- @inline export const ENTRY_KEY = offsetof<sc.Entry>("key");
339
- // @ts-expect-error: @inline is a valid decorator
340
- @inline export const ENTRY_PTR = offsetof<sc.Entry>("ptr");
341
- // @ts-expect-error: @inline is a valid decorator
342
- @inline export const ENTRY_LEN = offsetof<sc.Entry>("len");
357
+ export const ENTRY_KEY = offsetof<sc.Entry>("key");
358
+ export const ENTRY_PTR = offsetof<sc.Entry>("ptr");
359
+ export const ENTRY_LEN = offsetof<sc.Entry>("len");
343
360
 
344
361
  // @ts-expect-error: JSON_CACHE may not be defined. If so, it will default to false.
345
362
  export const CACHE_ENABLED: bool = isDefined(JSON_CACHE) ? JSON_CACHE : false;
@@ -388,8 +405,7 @@ export namespace sc {
388
405
  * Uses pointer address shifted right by 4 bits (aligned to 16-byte boundaries)
389
406
  * masked to fit within cache size.
390
407
  */
391
- // @ts-expect-error: @inline is a valid decorator
392
- @inline
408
+
393
409
  export function indexFor(ptr: usize): usize {
394
410
  return (ptr >> 4) & CACHE_MASK;
395
411
  }
@@ -400,8 +416,7 @@ export namespace sc {
400
416
  * @param key - The string pointer to look up
401
417
  * @returns true if cache hit, false if cache miss
402
418
  */
403
- // @ts-expect-error: @inline is a valid decorator
404
- @inline
419
+
405
420
  export function tryEmitCached(key: usize): bool {
406
421
  const e = unchecked(entries[indexFor(key)]);
407
422
  if (e.key == key) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.3.9",
4
- "author": "Jairus Tanaka",
3
+ "version": "1.5.0",
4
+ "author": "Jairus Tanaka <me@jairus.dev>",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/JairusSW/json-as.git"
@@ -11,22 +11,25 @@
11
11
  "devDependencies": {
12
12
  "@assemblyscript/wasi-shim": "^0.1.0",
13
13
  "@eslint/js": "^10.0.1",
14
- "@types/node": "^25.9.1",
14
+ "@types/node": "^25.9.2",
15
15
  "as-heap-analyzer": "^1.2.0",
16
- "as-test": "^1.5.2",
17
- "assemblyscript": "^0.28.17",
16
+ "as-test": "^1.6.0",
17
+ "assemblyscript": "^0.28.18",
18
+ "assemblyscript-json": "^1.1.0",
18
19
  "assemblyscript-prettier": "^3.0.4",
19
20
  "chartjs-node-canvas": "^5.0.0",
20
21
  "chartjs-plugin-datalabels": "^2.2.0",
21
- "eslint": "^10.4.0",
22
+ "eslint": "^10.4.1",
23
+ "fast-json-parse": "^1.0.3",
24
+ "fast-json-stringify": "^6.4.0",
22
25
  "husky": "^9.1.7",
23
- "json-as": "./",
26
+ "json-as": "file:./",
24
27
  "prettier": "3.8.3",
25
28
  "serve": "^14.2.6",
26
29
  "tinybench": "^6.0.2",
27
- "try-as": "^1.1.2",
30
+ "try-as": "^1.1.4",
28
31
  "typescript": "^6.0.3",
29
- "typescript-eslint": "^8.60.0"
32
+ "typescript-eslint": "^8.60.1"
30
33
  },
31
34
  "bugs": {
32
35
  "url": "https://github.com/JairusSW/json-as/issues"
@@ -95,6 +98,7 @@
95
98
  "test:ci": "ast test --parallel --clean --enable try-as",
96
99
  "test:coverage": "ast test --enable coverage --enable try-as",
97
100
  "bench": "bash -c 'bash ./scripts/run-bench.as.sh \"$@\" && { arg=\"${1:-}\"; if [ -z \"$arg\" ] || [ \"${arg#custom/}\" = \"$arg\" ]; then bash ./scripts/run-bench.js.sh \"$@\"; fi; } && bash ./scripts/build-charts.sh' --",
101
+ "bench:all": "bash ./scripts/bench-all.sh",
98
102
  "bench:as": "bash ./scripts/run-bench.as.sh",
99
103
  "bench:js": "bash ./scripts/run-bench.js.sh",
100
104
  "charts": "bun run charts:build && bun run charts:serve",
@@ -107,6 +111,16 @@
107
111
  "test:wasmtime": "wasmtime ./build/test.wasm",
108
112
  "test:wasmer": "wasmer ./build/test.wasm",
109
113
  "build:transform": "tsc -p ./transform",
114
+ "build:playground": "npm run build:transform && JSON_DEBUG=0 JSON_WRITE=assembly/playground.ts asc assembly/playground.ts --transform ./transform -o ./build/playground.wasm --textFile ./build/playground.wat --enable simd --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
115
+ "build:pg": "npm run build:playground",
116
+ "run:playground": "wasmtime ./build/playground.wasm",
117
+ "run:pg": "npm run run:playground",
118
+ "playground": "npm run build:playground && npm run run:playground",
119
+ "build:playground:tmp": "asc assembly/playground.tmp.ts -o ./build/playground.tmp.wasm --textFile ./build/playground.tmp.wat -O3 --noAssert --uncheckedBehavior always --runtime incremental --enable bulk-memory --enable simd --use JSON_MODE=1 --exportStart start --exportRuntime",
120
+ "playground:tmp": "npm run build:playground:tmp && v8 --no-liftoff --module ./bench/runners/assemblyscript.js -- playground.tmp.wasm",
121
+ "pg:tmp": "npm run playground:tmp",
122
+ "play": "npm run playground",
123
+ "pg": "npm run playground",
110
124
  "bench:wasmer": "wasmer ./build/bench.wasm --llvm",
111
125
  "format": "prettier -w .",
112
126
  "lint": "eslint . --no-warn-ignored",
@@ -122,5 +136,8 @@
122
136
  "prepare": "husky"
123
137
  },
124
138
  "type": "module",
125
- "types": "assembly/index.ts"
139
+ "types": "assembly/index.ts",
140
+ "dependencies": {
141
+ "xjb-as": "^0.1.0"
142
+ }
126
143
  }
@@ -84,4 +84,3 @@ export declare class ASTBuilder extends Visitor {
84
84
  serializeAccessModifiers(node: DeclarationStatement): void;
85
85
  finish(): string;
86
86
  }
87
- //# sourceMappingURL=builder.d.ts.map
@@ -1362,4 +1362,3 @@ export class ASTBuilder extends Visitor {
1362
1362
  return ret;
1363
1363
  }
1364
1364
  }
1365
- //# sourceMappingURL=builder.js.map
@@ -35,4 +35,3 @@ export default class Transformer extends Transform {
35
35
  afterParse(parser: Parser): void;
36
36
  }
37
37
  export declare function stripNull(type: string): string;
38
- //# sourceMappingURL=index.d.ts.map