json-as 1.3.1 → 1.3.3
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/CHANGELOG.md +9 -26
- package/README.md +43 -19
- package/assembly/deserialize/index/arbitrary.ts +1 -1
- package/assembly/deserialize/index/array.ts +6 -1
- package/assembly/deserialize/index/float.ts +1 -1
- package/assembly/deserialize/index/integer.ts +1 -1
- package/assembly/deserialize/index/unsigned.ts +1 -1
- package/assembly/deserialize/simd/string.ts +17 -13
- package/assembly/deserialize/simple/arbitrary.ts +1 -1
- package/assembly/deserialize/simple/array/generic.ts +42 -0
- package/assembly/deserialize/simple/array.ts +8 -1
- package/assembly/deserialize/{float.ts → simple/float.ts} +22 -2
- package/assembly/deserialize/{integer.ts → simple/integer.ts} +3 -2
- package/assembly/deserialize/simple/map.ts +62 -12
- package/assembly/deserialize/simple/object.ts +1 -1
- package/assembly/deserialize/simple/set.ts +119 -134
- package/assembly/deserialize/simple/staticarray.ts +13 -1
- package/assembly/deserialize/simple/string.ts +15 -10
- package/assembly/deserialize/simple/struct.ts +9 -157
- package/assembly/deserialize/simple/typedarray.ts +1 -1
- package/assembly/deserialize/{unsigned.ts → simple/unsigned.ts} +3 -2
- package/assembly/deserialize/swar/array/array.ts +42 -7
- package/assembly/deserialize/swar/array/bool.ts +6 -2
- package/assembly/deserialize/swar/array/float.ts +7 -3
- package/assembly/deserialize/swar/array/generic.ts +41 -0
- package/assembly/deserialize/swar/array/integer.ts +8 -4
- package/assembly/deserialize/swar/array/object.ts +21 -4
- package/assembly/deserialize/swar/array/shared.ts +19 -4
- package/assembly/deserialize/swar/array/string.ts +6 -2
- package/assembly/deserialize/swar/array/struct.ts +21 -4
- package/assembly/deserialize/swar/array.ts +57 -2
- package/assembly/deserialize/swar/string.ts +248 -372
- package/assembly/index.d.ts +1 -0
- package/assembly/index.ts +77 -19
- package/assembly/serialize/index/arbitrary.ts +3 -3
- package/assembly/serialize/index/float.ts +1 -1
- package/assembly/serialize/index/object.ts +1 -5
- package/assembly/serialize/simd/string.ts +4 -5
- package/assembly/serialize/simple/arbitrary.ts +3 -3
- package/assembly/serialize/simple/array.ts +18 -6
- package/assembly/serialize/simple/float.ts +20 -4
- package/assembly/serialize/simple/map.ts +10 -27
- package/assembly/serialize/simple/object.ts +1 -5
- package/assembly/serialize/simple/set.ts +3 -4
- package/assembly/serialize/simple/staticarray.ts +4 -3
- package/assembly/serialize/simple/typedarray.ts +9 -7
- package/assembly/serialize/swar/string.ts +0 -1
- package/assembly/tsconfig.json +1 -0
- package/assembly/util/dragonbox-cache.ts +4 -0
- package/assembly/util/dragonbox.ts +624 -0
- package/lib/as-bs.ts +35 -24
- package/package.json +26 -18
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +508 -148
- package/transform/lib/index.js.map +1 -1
package/lib/as-bs.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
2
|
-
import { heap } from "memory";
|
|
2
|
+
import { __heap_base, heap } from "memory";
|
|
3
3
|
|
|
4
4
|
// Buffer management constants
|
|
5
5
|
const SHRINK_EVERY_N_MASK: usize = 255; // check every 256 outputs
|
|
@@ -227,12 +227,14 @@ export namespace bs {
|
|
|
227
227
|
|
|
228
228
|
const current = load<usize>(dstFieldPtr);
|
|
229
229
|
let stringPtr: usize;
|
|
230
|
-
if (current
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
if (current >= __heap_base) {
|
|
231
|
+
if (changetype<OBJECT>(current - TOTAL_OVERHEAD).rtSize == byteLength) {
|
|
232
|
+
stringPtr = current;
|
|
233
|
+
} else {
|
|
234
|
+
// @ts-expect-error: __renew is a runtime builtin
|
|
235
|
+
stringPtr = __renew(current, byteLength);
|
|
236
|
+
store<usize>(dstFieldPtr, stringPtr);
|
|
237
|
+
}
|
|
236
238
|
} else {
|
|
237
239
|
// @ts-expect-error: __new is a runtime builtin
|
|
238
240
|
stringPtr = __new(byteLength, idof<string>());
|
|
@@ -284,18 +286,21 @@ export namespace bs {
|
|
|
284
286
|
*
|
|
285
287
|
* Enable caching by setting the `JSON_CACHE` environment variable:
|
|
286
288
|
* ```bash
|
|
287
|
-
* JSON_CACHE=
|
|
289
|
+
* JSON_CACHE=true npx asc your-file.ts --transform json-as/transform
|
|
288
290
|
* ```
|
|
289
291
|
*
|
|
290
|
-
*
|
|
292
|
+
* You can also configure cache size directly:
|
|
293
|
+
* - `JSON_CACHE=<int>` => bytes
|
|
294
|
+
* - `JSON_CACHE=<int>kb|mb|gb` => kilobits/megabits/gigabits
|
|
295
|
+
* - `JSON_CACHE=<int>KB|MB|GB` => kilobytes/megabytes/gigabytes
|
|
291
296
|
*
|
|
292
|
-
*
|
|
297
|
+
* ## Memory Configuration
|
|
293
298
|
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* Memory usage: ~49KB (4096 * 12 bytes per entry)
|
|
299
|
+
* The cache uses a size budget from `JSON_CACHE` (or defaults to 1MB when
|
|
300
|
+
* enabled with `true/on/yes`):
|
|
297
301
|
*
|
|
298
|
-
* - **
|
|
302
|
+
* - **CACHE_SIZE**: Number of direct-mapped cache slots. Derived from budget.
|
|
303
|
+
* - **ARENA_SIZE**: Circular buffer for storing cached serialized strings.
|
|
299
304
|
* When full, wraps around and overwrites oldest entries. Larger values retain
|
|
300
305
|
* more cached data but consume more memory.
|
|
301
306
|
*
|
|
@@ -322,16 +327,20 @@ export namespace sc {
|
|
|
322
327
|
// @ts-expect-error: @inline is a valid decorator
|
|
323
328
|
@inline export const ENTRY_LEN = offsetof<sc.Entry>("len");
|
|
324
329
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
export const CACHE_MASK = CACHE_SIZE - 1;
|
|
330
|
-
|
|
331
|
-
/** Size of the circular arena buffer for cached strings (1MB) */
|
|
332
|
-
export const ARENA_SIZE = 1 << 20;
|
|
330
|
+
// @ts-expect-error: JSON_CACHE may not be defined. If so, it will default to false.
|
|
331
|
+
export const CACHE_ENABLED: bool = isDefined(JSON_CACHE) ? JSON_CACHE : false;
|
|
332
|
+
// @ts-expect-error: JSON_CACHE_SIZE may not be defined. If so, it will default to 1MB.
|
|
333
|
+
export const CACHE_BYTES: usize = isDefined(JSON_CACHE_SIZE) ? <usize>JSON_CACHE_SIZE : (1 << 20);
|
|
333
334
|
/** Minimum serialized length to cache - smaller outputs aren't worth caching */
|
|
334
335
|
export const MIN_CACHE_LEN: usize = 128;
|
|
336
|
+
/** Size of the circular arena buffer for cached strings */
|
|
337
|
+
export const ARENA_SIZE: usize = CACHE_BYTES >= MIN_CACHE_LEN ? CACHE_BYTES : MIN_CACHE_LEN;
|
|
338
|
+
|
|
339
|
+
/** Number of cache slots (power of 2 for efficient masking). Set to 0 when caching disabled. */
|
|
340
|
+
const CACHE_SIZE_BASE: i32 = CACHE_ENABLED ? i32((ARENA_SIZE >> 10) >= 1 ? (ARENA_SIZE >> 10) : 1) : 0;
|
|
341
|
+
export const CACHE_SIZE: usize = CACHE_ENABLED ? <usize>(1 << (32 - clz<i32>(CACHE_SIZE_BASE - 1))) : 0;
|
|
342
|
+
/** Bitmask for fast modulo operation on cache index */
|
|
343
|
+
export const CACHE_MASK: usize = CACHE_SIZE > 0 ? CACHE_SIZE - 1 : 0;
|
|
335
344
|
|
|
336
345
|
/** Cache entry structure - stores pointer to string, cached output location, and length */
|
|
337
346
|
@unmanaged
|
|
@@ -345,9 +354,9 @@ export namespace sc {
|
|
|
345
354
|
}
|
|
346
355
|
|
|
347
356
|
/** Static array of cache entries */
|
|
348
|
-
export const entries = new StaticArray<sc.Entry>(CACHE_SIZE);
|
|
357
|
+
export const entries = new StaticArray<sc.Entry>(i32(CACHE_SIZE));
|
|
349
358
|
/** Circular buffer arena for storing cached serialized strings */
|
|
350
|
-
export const arena = new ArrayBuffer(ARENA_SIZE);
|
|
359
|
+
export const arena = new ArrayBuffer(i32(ARENA_SIZE));
|
|
351
360
|
/** Current write position in the arena */
|
|
352
361
|
export let arenaPtr: usize = changetype<usize>(arena);
|
|
353
362
|
/** End boundary of the arena */
|
|
@@ -391,7 +400,9 @@ export namespace sc {
|
|
|
391
400
|
* @param len - Length of serialized output
|
|
392
401
|
*/
|
|
393
402
|
export function insertCached(str: usize, start: usize, len: usize): void {
|
|
403
|
+
if (!CACHE_ENABLED || ARENA_SIZE == 0) return;
|
|
394
404
|
if (len < MIN_CACHE_LEN) return;
|
|
405
|
+
if (len > ARENA_SIZE) return;
|
|
395
406
|
if (arenaPtr + len > arenaEnd) {
|
|
396
407
|
// Wrap around to beginning of arena (circular buffer)
|
|
397
408
|
arenaPtr = changetype<usize>(arena);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"author": "Jairus Tanaka",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,18 +10,19 @@
|
|
|
10
10
|
"main": "transform/lib/index.js",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
13
|
-
"@eslint/js": "^
|
|
14
|
-
"@types/node": "^25.0
|
|
15
|
-
"as-test": "^1.0.
|
|
16
|
-
"assemblyscript": "^0.28.
|
|
17
|
-
"assemblyscript-prettier": "^3.0.
|
|
13
|
+
"@eslint/js": "^10.0.1",
|
|
14
|
+
"@types/node": "^25.6.0",
|
|
15
|
+
"as-test": "^1.0.7",
|
|
16
|
+
"assemblyscript": "^0.28.14",
|
|
17
|
+
"assemblyscript-prettier": "^3.0.4",
|
|
18
18
|
"chartjs-node-canvas": "^5.0.0",
|
|
19
19
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
20
|
-
"eslint": "^10.
|
|
21
|
-
"prettier": "3.8.
|
|
20
|
+
"eslint": "^10.2.0",
|
|
21
|
+
"prettier": "3.8.3",
|
|
22
|
+
"serve": "^14.2.6",
|
|
22
23
|
"tinybench": "^6.0.0",
|
|
23
|
-
"typescript": "^
|
|
24
|
-
"typescript-eslint": "^8.
|
|
24
|
+
"typescript": "^6.0.2",
|
|
25
|
+
"typescript-eslint": "^8.58.2"
|
|
25
26
|
},
|
|
26
27
|
"bugs": {
|
|
27
28
|
"url": "https://github.com/JairusSW/json-as/issues"
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"Deon Groenewald"
|
|
41
42
|
],
|
|
42
43
|
"description": "The only JSON library you'll need for AssemblyScript with SIMD and SWAR",
|
|
43
|
-
"homepage": "https://
|
|
44
|
+
"homepage": "https://docs.jairus.dev/json-as",
|
|
44
45
|
"files": [
|
|
45
46
|
"assembly/custom/",
|
|
46
47
|
"assembly/deserialize/",
|
|
@@ -80,16 +81,23 @@
|
|
|
80
81
|
},
|
|
81
82
|
"scripts": {
|
|
82
83
|
"ci": "act",
|
|
83
|
-
"test": "ast test --
|
|
84
|
-
"test:
|
|
84
|
+
"test": "ast test --parallel",
|
|
85
|
+
"test:fast": "npm run build:transform && JSON_USE_FAST_PATH=1 ast test --parallel --mode swar,simd",
|
|
86
|
+
"fuzz": "ast fuzz",
|
|
87
|
+
"test:fuzz": "ast test --fuzz --parallel",
|
|
88
|
+
"test:ci": "ast test --parallel --clean",
|
|
89
|
+
"test:ci:fast": "JSON_USE_FAST_PATH=1 ast test --parallel --clean",
|
|
85
90
|
"test:coverage": "ast test --enable coverage",
|
|
86
|
-
"bench": "npm run bench:as && npm run bench:js &&
|
|
87
|
-
"bench:as": "bash ./run-bench.as.sh",
|
|
88
|
-
"bench:js": "bash ./run-bench.js.sh",
|
|
89
|
-
"
|
|
91
|
+
"bench": "npm run bench:as && npm run bench:js && npm run charts:build",
|
|
92
|
+
"bench:as": "bash ./scripts/run-bench.as.sh",
|
|
93
|
+
"bench:js": "bash ./scripts/run-bench.js.sh",
|
|
94
|
+
"charts": "bun run charts:build && bun run charts:serve",
|
|
95
|
+
"charts:build": "bash ./scripts/build-charts.sh",
|
|
96
|
+
"charts:publish": "bash ./scripts/publish-benchmarks.sh",
|
|
97
|
+
"charts:serve": "serve ./build/charts/",
|
|
90
98
|
"build:test": "JSON_DEBUG=0 JSON_WRITE=assembly/test.ts asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --enable simd --debug --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
91
99
|
"build:tmp:test": "JSON_DEBUG=1 asc assembly/test.tmp.ts -o ./build/test.wasm --textFile ./build/test.wat --enable simd --debug --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
92
|
-
"build:test:wine": "JSON_DEBUG=1 JSON_WRITE=assembly/test.ts NODE_SKIP_PLATFORM_CHECK=1
|
|
100
|
+
"build:test:wine": "JSON_DEBUG=1 JSON_WRITE=assembly/test.ts NODE_SKIP_PLATFORM_CHECK=1 wineconsole --backend=curses ~/.win-bin/node/node.exe ./node_modules/assemblyscript/bin/asc.js assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --debug --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json",
|
|
93
101
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
94
102
|
"test:wasmer": "wasmer ./build/test.wasm",
|
|
95
103
|
"build:transform": "tsc -p ./transform",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAmJvC,qBAAa,aAAc,SAAQ,OAAO;IACxC,MAAM,CAAC,EAAE,EAAE,aAAa,CAAuB;IAExC,OAAO,EAAG,OAAO,CAAC;IAClB,OAAO,EAAG,MAAM,CAAC;IACjB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAA+B;IAC7D,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,CAAmB;IACrC,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAqB;IAEvD,OAAO,CAAC,4BAA4B;IA6CpC,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAYtD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,cAAoB,GAAG,MAAM;IAsC3E,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAghDnD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAItC,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IA4ClD,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIjD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA+J9B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe,GAAG,MAAM,EAAE;IA0BxD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO;CAc3D;AA4BD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,SAAS;IAChD,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAwDjC;AAoKD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C"}
|