Skip to content

Commit e279cf2

Browse files
committed
Bump to 0.4.6
1 parent bc7d3fd commit e279cf2

3 files changed

Lines changed: 25 additions & 11 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vectorjson",
3-
"version": "0.4.5",
3+
"version": "0.4.6",
44
"description": "O(n) WASM SIMD JSON parser for AI agents — stream fields instantly, abort errors early, offload parsing to Workers",
55
"type": "module",
66
"main": "dist/index.js",

src/js/index.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -721,19 +721,20 @@ export async function init(options?: {
721721
const status = engine.stream_get_status(streamId);
722722
if (status !== 1 /* complete */ && status !== 3 /* end_early */) return null;
723723
const bufPtr = engine.stream_get_buffer_ptr(streamId) >>> 0;
724-
const bufLen = engine.stream_get_buffer_len(streamId);
725-
if (bufLen === 0) return null;
726-
// Copy stream buffer with SIMD padding for doc_parse
727-
const padPtr = engine.alloc(bufLen + 64) >>> 0;
724+
// Use value_len (not buffer_len) — in JSONL mode buffer may contain next value's bytes
725+
const valueLen = engine.stream_get_value_len(streamId);
726+
if (valueLen === 0) return null;
727+
// Copy with SIMD padding for doc_parse
728+
const padPtr = engine.alloc(valueLen + 64) >>> 0;
728729
if (padPtr === 0) return null;
729-
new Uint8Array(engine.memory.buffer, padPtr, bufLen).set(
730-
new Uint8Array(engine.memory.buffer, bufPtr, bufLen),
730+
new Uint8Array(engine.memory.buffer, padPtr, valueLen).set(
731+
new Uint8Array(engine.memory.buffer, bufPtr, valueLen),
731732
);
732-
new Uint8Array(engine.memory.buffer, padPtr + bufLen, 64).fill(0x20);
733+
new Uint8Array(engine.memory.buffer, padPtr + valueLen, 64).fill(0x20);
733734
const docId = formatCode === 2
734-
? engine.doc_parse_fmt(padPtr, bufLen, 2)
735-
: engine.doc_parse(padPtr, bufLen);
736-
engine.dealloc(padPtr, bufLen + 64);
735+
? engine.doc_parse_fmt(padPtr, valueLen, 2)
736+
: engine.doc_parse(padPtr, valueLen);
737+
engine.dealloc(padPtr, valueLen + 64);
737738
if (docId < 0) return null;
738739
// Export tape → JS ArrayBuffer, then free slot
739740
const size = engine.doc_export_tape_size(docId);

test/tape-transfer.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ await test("imported result supports .free()", async () => {
9595
obj.free(); // should not throw
9696
});
9797

98+
await test("jsonl format round-trip", async () => {
99+
const parser = createParser({ format: "jsonl" });
100+
// Two JSONL values — getTapeBuffer should export only the first
101+
parser.feed('{"a":1}\n{"b":2}');
102+
const tape = parser.getTapeBuffer();
103+
assert(tape !== null, "getTapeBuffer should succeed for complete jsonl value");
104+
const obj = importTape(tape);
105+
assertEqual(obj.a, 1);
106+
// Second value should not leak into the first
107+
assertEqual(obj.b, undefined);
108+
parser.destroy();
109+
});
110+
98111
await test("json5 format round-trip", async () => {
99112
const parser = createParser({ format: "json5" });
100113
// JSON5: unquoted keys, single-quoted strings, trailing comma, comments

0 commit comments

Comments
 (0)