vectorjson 0.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/LICENSE +190 -0
- package/README.md +547 -0
- package/dist/engine.wasm +0 -0
- package/dist/index.d.ts +227 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +10 -0
- package/package.json +63 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VectorJSON — SIMD-accelerated JSON parser
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* JS bytes → [Zig + zimdjson SIMD] → tape → lazy Proxy over doc slots
|
|
6
|
+
*
|
|
7
|
+
* The Zig engine (engine.wasm) parses JSON bytes into an internal tape format
|
|
8
|
+
* using SIMD-accelerated algorithms from zimdjson.
|
|
9
|
+
*
|
|
10
|
+
* Primary parse path: doc-slot (tape-direct navigation via Zig exports).
|
|
11
|
+
* FinalizationRegistry auto-frees doc slots when the Proxy is GC'd.
|
|
12
|
+
* Users CAN call .free() to release immediately if desired.
|
|
13
|
+
*/
|
|
14
|
+
export type ParseStatus = "complete" | "complete_early" | "incomplete" | "invalid";
|
|
15
|
+
export type FeedStatus = "incomplete" | "complete" | "error" | "end_early";
|
|
16
|
+
/** Result shape compatible with Vercel AI SDK's parsePartialJson */
|
|
17
|
+
export type PartialJsonState = "successful-parse" | "repaired-parse" | "failed-parse";
|
|
18
|
+
/** Discriminated union — narrows `value` type when you check `state`. */
|
|
19
|
+
export type PartialJsonResult<T = unknown> = {
|
|
20
|
+
value: T;
|
|
21
|
+
state: "successful-parse";
|
|
22
|
+
} | {
|
|
23
|
+
value: T | undefined;
|
|
24
|
+
state: "repaired-parse";
|
|
25
|
+
} | {
|
|
26
|
+
value: undefined;
|
|
27
|
+
state: "failed-parse";
|
|
28
|
+
};
|
|
29
|
+
/** Recursively make all properties optional — matches Vercel AI SDK's DeepPartial. */
|
|
30
|
+
export type DeepPartial<T> = T extends object ? T extends Array<infer U> ? Array<DeepPartial<U>> : {
|
|
31
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
32
|
+
} : T;
|
|
33
|
+
export interface StreamingParser<T = unknown> {
|
|
34
|
+
/** Feed a chunk of bytes to the parser. Only NEW bytes are scanned (O(chunk_size)). */
|
|
35
|
+
feed(chunk: Uint8Array | string): FeedStatus;
|
|
36
|
+
/** Get the parsed value. Returns autocompleted partial value while incomplete, final value when complete; throws on parse errors. */
|
|
37
|
+
getValue(): T | undefined;
|
|
38
|
+
/** Get remaining bytes after end_early status (for NDJSON). */
|
|
39
|
+
getRemaining(): Uint8Array | null;
|
|
40
|
+
/** Get the current status without feeding data. */
|
|
41
|
+
getStatus(): FeedStatus;
|
|
42
|
+
/** Copy the accumulated stream buffer into a new ArrayBuffer (for Worker postMessage transfer). */
|
|
43
|
+
getRawBuffer(): ArrayBuffer | null;
|
|
44
|
+
/** Destroy the parser and free all resources. */
|
|
45
|
+
destroy(): void;
|
|
46
|
+
}
|
|
47
|
+
export interface ParseResult {
|
|
48
|
+
status: ParseStatus;
|
|
49
|
+
value?: unknown;
|
|
50
|
+
remaining?: Uint8Array;
|
|
51
|
+
error?: string;
|
|
52
|
+
/** Check if a value (object/array) from an incomplete parse is fully present in the original input. */
|
|
53
|
+
isComplete(value: unknown): boolean;
|
|
54
|
+
/** Full materialization via JSON.parse — fastest way to get a plain JS object tree. */
|
|
55
|
+
toJSON(): unknown;
|
|
56
|
+
}
|
|
57
|
+
/** Compiled path segment: string = key, number = index, '*' = wildcard */
|
|
58
|
+
export type PathSegment = string | number;
|
|
59
|
+
export interface PathEvent {
|
|
60
|
+
type: 'value';
|
|
61
|
+
path: string;
|
|
62
|
+
value: unknown;
|
|
63
|
+
offset: number;
|
|
64
|
+
length: number;
|
|
65
|
+
index?: number;
|
|
66
|
+
key?: string;
|
|
67
|
+
matches: (string | number)[];
|
|
68
|
+
}
|
|
69
|
+
export interface DeltaEvent {
|
|
70
|
+
type: 'delta';
|
|
71
|
+
path: string;
|
|
72
|
+
value: string;
|
|
73
|
+
offset: number;
|
|
74
|
+
length: number;
|
|
75
|
+
}
|
|
76
|
+
export interface RootEvent {
|
|
77
|
+
type: 'root';
|
|
78
|
+
index: number;
|
|
79
|
+
value: unknown;
|
|
80
|
+
}
|
|
81
|
+
export interface EventParser {
|
|
82
|
+
on(path: string, callback: (event: PathEvent) => void): EventParser;
|
|
83
|
+
on<T>(path: string, schema: {
|
|
84
|
+
safeParse: (v: unknown) => {
|
|
85
|
+
success: boolean;
|
|
86
|
+
data?: T;
|
|
87
|
+
};
|
|
88
|
+
}, callback: (event: PathEvent & {
|
|
89
|
+
value: T;
|
|
90
|
+
}) => void): EventParser;
|
|
91
|
+
onDelta(path: string, callback: (event: DeltaEvent) => void): EventParser;
|
|
92
|
+
onText(callback: (text: string) => void): EventParser;
|
|
93
|
+
skip(...paths: string[]): EventParser;
|
|
94
|
+
off(path: string, callback?: Function): EventParser;
|
|
95
|
+
feed(chunk: string | Uint8Array): FeedStatus;
|
|
96
|
+
getValue(): unknown | undefined;
|
|
97
|
+
getRemaining(): Uint8Array | null;
|
|
98
|
+
getStatus(): FeedStatus;
|
|
99
|
+
/** Copy the accumulated stream buffer into a new ArrayBuffer (for Worker postMessage transfer). */
|
|
100
|
+
getRawBuffer(): ArrayBuffer | null;
|
|
101
|
+
destroy(): void;
|
|
102
|
+
}
|
|
103
|
+
export interface VectorJSON {
|
|
104
|
+
/**
|
|
105
|
+
* Parse a JSON string or Uint8Array into a value.
|
|
106
|
+
* Primitives (null, boolean, number) are returned directly as JS values.
|
|
107
|
+
* Objects and arrays return Proxy objects — values materialize only when accessed.
|
|
108
|
+
* Call .free() on the result to release resources immediately, or let
|
|
109
|
+
* FinalizationRegistry handle it automatically when the Proxy is GC'd.
|
|
110
|
+
*/
|
|
111
|
+
parse(input: string | Uint8Array): ParseResult;
|
|
112
|
+
/**
|
|
113
|
+
* Create a streaming parser for incremental JSON parsing.
|
|
114
|
+
* Feed chunks as they arrive; only new bytes are processed per call.
|
|
115
|
+
* Total work is O(N) regardless of how many chunks — no re-parsing.
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* const parser = vj.createParser();
|
|
119
|
+
* for await (const chunk of stream) {
|
|
120
|
+
* const status = parser.feed(chunk);
|
|
121
|
+
* if (status === "complete" || status === "end_early") {
|
|
122
|
+
* const value = parser.getValue();
|
|
123
|
+
* // use value...
|
|
124
|
+
* parser.destroy();
|
|
125
|
+
* break;
|
|
126
|
+
* }
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
createParser(): StreamingParser;
|
|
131
|
+
/**
|
|
132
|
+
* Create a streaming parser with schema validation.
|
|
133
|
+
* `getValue()` returns `undefined` when the schema rejects the value (same as incomplete).
|
|
134
|
+
* T is auto-inferred from the schema — no manual `<T>` needed.
|
|
135
|
+
*
|
|
136
|
+
* ```ts
|
|
137
|
+
* const parser = vj.createParser(z.object({ name: z.string() }));
|
|
138
|
+
* parser.feed('{"name":"Alice"}');
|
|
139
|
+
* parser.getValue(); // { name: string } | undefined
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
createParser<T>(schema: {
|
|
143
|
+
safeParse: (v: unknown) => {
|
|
144
|
+
success: boolean;
|
|
145
|
+
data?: T;
|
|
146
|
+
};
|
|
147
|
+
}): StreamingParser<T>;
|
|
148
|
+
/**
|
|
149
|
+
* Eagerly materialize a lazy proxy into plain JS objects.
|
|
150
|
+
* If the value is already a plain JS value, returns it as-is.
|
|
151
|
+
*/
|
|
152
|
+
materialize(value: unknown): unknown;
|
|
153
|
+
/**
|
|
154
|
+
* Drop-in replacement for AI SDK partial JSON parsers.
|
|
155
|
+
* Parses a potentially incomplete JSON string and returns a plain JS object.
|
|
156
|
+
*
|
|
157
|
+
* Compatible with Vercel AI SDK's `parsePartialJson` — returns `{ value, state }`
|
|
158
|
+
* where state is "successful-parse", "repaired-parse", or "failed-parse".
|
|
159
|
+
*
|
|
160
|
+
* ```ts
|
|
161
|
+
* // Drop-in for Vercel AI SDK:
|
|
162
|
+
* const { value, state } = vj.parsePartialJson('{"a": 1, "b": ');
|
|
163
|
+
* // value = { a: 1, b: null }, state = "repaired-parse"
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
parsePartialJson(input: string): PartialJsonResult;
|
|
167
|
+
/**
|
|
168
|
+
* Parse partial JSON with schema-inferred types.
|
|
169
|
+
* T is auto-inferred from the schema — no manual `<T>` needed.
|
|
170
|
+
*
|
|
171
|
+
* Returns `DeepPartial<T>` because incomplete JSON will have missing fields.
|
|
172
|
+
* When `safeParse` succeeds, returns the validated `data`.
|
|
173
|
+
* When `safeParse` fails on a repaired-parse, returns the raw parsed value
|
|
174
|
+
* (typed as `DeepPartial<T>`) — the object is partial, that's expected.
|
|
175
|
+
*
|
|
176
|
+
* ```ts
|
|
177
|
+
* const User = z.object({ name: z.string(), age: z.number() });
|
|
178
|
+
* const { value, state } = vj.parsePartialJson('{"name":"Al', User);
|
|
179
|
+
* // value: { name?: string; age?: number } | undefined
|
|
180
|
+
* // state: "repaired-parse"
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
parsePartialJson<T>(input: string, schema: {
|
|
184
|
+
safeParse: (v: unknown) => {
|
|
185
|
+
success: boolean;
|
|
186
|
+
data?: T;
|
|
187
|
+
};
|
|
188
|
+
}): PartialJsonResult<DeepPartial<T>>;
|
|
189
|
+
/**
|
|
190
|
+
* Create an event-driven streaming parser with path subscriptions,
|
|
191
|
+
* string delta emission, multi-root support, and JSON boundary detection.
|
|
192
|
+
*/
|
|
193
|
+
createEventParser(options?: {
|
|
194
|
+
multiRoot?: boolean;
|
|
195
|
+
onRoot?: (event: RootEvent) => void;
|
|
196
|
+
}): EventParser;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Initialize VectorJSON by loading and linking the WASM module.
|
|
200
|
+
* Call this once; subsequent calls return the cached instance.
|
|
201
|
+
*/
|
|
202
|
+
export declare function init(options?: {
|
|
203
|
+
engineWasm?: string | URL | BufferSource;
|
|
204
|
+
}): Promise<VectorJSON>;
|
|
205
|
+
/**
|
|
206
|
+
* Convenience: parse JSON using a pre-initialized instance.
|
|
207
|
+
* Initializes on first call.
|
|
208
|
+
*/
|
|
209
|
+
export declare function parse(input: string | Uint8Array): Promise<ParseResult>;
|
|
210
|
+
/**
|
|
211
|
+
* Convenience: parse partial JSON using a pre-initialized instance.
|
|
212
|
+
* Drop-in replacement for AI SDK partial JSON parsers.
|
|
213
|
+
* Initializes on first call.
|
|
214
|
+
*
|
|
215
|
+
* ```ts
|
|
216
|
+
* import { parsePartialJson } from 'vectorjson';
|
|
217
|
+
* const { value, state } = await parsePartialJson('{"a": 1, "b": ');
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export declare function parsePartialJson(input: string): Promise<PartialJsonResult>;
|
|
221
|
+
export declare function parsePartialJson<T>(input: string, schema: {
|
|
222
|
+
safeParse: (v: unknown) => {
|
|
223
|
+
success: boolean;
|
|
224
|
+
data?: T;
|
|
225
|
+
};
|
|
226
|
+
}): Promise<PartialJsonResult<DeepPartial<T>>>;
|
|
227
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/js/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{readFile as w0}from"node:fs/promises";import{fileURLToPath as aQ}from"node:url";import{dirname as F0,join as O0}from"node:path";var tQ={1:"Exceeded maximum nesting depth",2:"Document exceeds maximum capacity",3:"Invalid escape sequence",4:"Invalid Unicode code point",5:"Invalid number literal",6:"Expected colon after key",7:"Expected string key in object",8:"Expected comma or closing bracket in array",9:"Expected comma or closing brace in object",10:"Incomplete array",11:"Incomplete object",12:"Unexpected trailing content",13:"Out of memory",99:"Unknown parse error"},l=new TextDecoder("utf-8"),p=Array.from({length:256},(S,QQ)=>String.fromCharCode(QQ)),FQ=null;async function eQ(S){if(FQ)return FQ;let QQ=F0(aQ(import.meta.url)),OQ=O0(QQ,"engine.wasm"),Q0=S?.engineWasm instanceof ArrayBuffer||ArrayBuffer.isView(S?.engineWasm)?S.engineWasm:await w0(typeof S?.engineWasm==="string"?S.engineWasm:S?.engineWasm instanceof URL?aQ(S.engineWasm):OQ),{instance:$0}=await WebAssembly.instantiate(Q0,{}),q=$0.exports,KQ=new TextEncoder,SQ={ptr:0,cap:0},q0={ptr:0,cap:0},gQ={ptr:0,cap:0};function EQ(Q,$,X){if($<=Q.cap)return Q.ptr;if(Q.ptr!==0)q.dealloc(Q.ptr,Q.cap);let z=Q.cap===0?X:Q.cap;while(z<$)z*=2;if(Q.ptr=q.alloc(z)>>>0,Q.ptr===0)throw new Error("VectorJSON: allocation failed");return Q.cap=z,Q.ptr}function GQ(Q,$,X,z){if(typeof Q==="string"){let Y=Q.length+X,N=EQ($,Y,z),G=KQ.encodeInto(Q,new Uint8Array(q.memory.buffer,N,Y));if(G.read<Q.length)Y=Q.length*3+X,N=EQ($,Y,z),G=KQ.encodeInto(Q,new Uint8Array(q.memory.buffer,N,Y));return{ptr:N,len:G.written}}let Z=Q.byteLength,L=EQ($,Z+X,z);return new Uint8Array(q.memory.buffer,L,Z).set(Q),{ptr:L,len:Z}}function uQ(Q){if(Q.length===0)return{ptr:1,len:0};return GQ(Q,q0,0,256)}let DQ=q.doc_batch_ptr()>>>0,CQ=0,vQ=1,bQ=2,yQ=3,xQ=4,jQ=5,sQ=6,t=["incomplete","complete","error","end_early"],W0=0,z0=2,X0=3,$Q=Symbol("vectorjson.lazy"),JQ=Symbol(),XQ=new Map,lQ=new FinalizationRegistry(({docId:Q,generation:$})=>{if(XQ.get(Q)!==$)return;XQ.delete(Q),ZQ.delete(Q),q.doc_free(Q)});function AQ(Q){let $=new Uint32Array(Q);return $.set(new Uint32Array(q.memory.buffer,DQ,Q)),$}function oQ(Q,$,X){let Z=Q($,X,0);if(Z<16384)return AQ(Z);let L=[],Y=AQ(Z);for(let N=0;N<Z;N++)L.push(Y[N]);while(Z===16384){let N=new Uint32Array(q.memory.buffer,DQ+65536,1)[0];Z=Q($,X,N),Y=AQ(Z);for(let G=0;G<Z;G++)L.push(Y[G])}return new Uint32Array(L)}let ZQ=new Map;function NQ(Q,$){let X=q.doc_read_string_raw(Q,$)>>>0;if(X===0)return"";let z=new Uint32Array(q.memory.buffer,DQ,3),Z=z[0],L=z[2],Y=ZQ.get(Q);if(Y!==void 0){let T=Y.slice(Z,Z+X);return L?JSON.parse('"'+T+'"'):T}let N=q.doc_get_input_ptr(Q)>>>0,G=l.decode(new Uint8Array(q.memory.buffer,N+Z,X));return L?JSON.parse('"'+G+'"'):G}function fQ(Q,$){let X=q.doc_get_tag(Q,$);if(X===CQ)return null;if(X===vQ)return!0;if(X===bQ)return!1;if(X===yQ)return q.doc_get_number(Q,$);if(X===xQ)return NQ(Q,$);if(X===jQ||X===sQ){let z=q.doc_get_src_pos(Q,$)>>>0,Z=q.doc_get_close_index(Q,$)-1,L=q.doc_get_src_pos(Q,Z),Y=q.doc_get_input_ptr(Q)>>>0,N=new Uint8Array(q.memory.buffer,Y+z,L+1-z);return JSON.parse(l.decode(N))}return null}function Z0(Q){return Q._e||(Q._e=oQ(q.doc_array_elements,Q._d,Q._i))}function PQ(Q,$,X,z,Z,L=!1){let Y=q.doc_get_tag(Q,$);if(Y===CQ)return null;if(Y===vQ)return!0;if(Y===bQ)return!1;if(Y===yQ)return q.doc_get_number(Q,$);if(Y===xQ)return NQ(Q,$);if(Y===jQ){if(L)return new Proxy({_d:Q,_i:$,_k:X,_g:z,_f:Z},H0);return fQ(Q,$)}return new Proxy(Object.assign([],{_d:Q,_i:$,_k:X,_g:z,_f:Z,_l:q.doc_get_count(Q,$),_p:L}),iQ)}let iQ={get(Q,$,X){if($==="free"||$===Symbol.dispose)return Q._f;if($===$Q)return{docId:Q._d,index:Q._i};if($==="length")return Q._l;if($===Symbol.iterator){let z=Q;return function(){let Z=0;return{next(){if(Z>=z._l)return{done:!0,value:void 0};return{done:!1,value:iQ.get(z,String(Z++),z)}}}}}if($===Symbol.toStringTag)return"Array";if(typeof $==="string"){let z=Number($);if(Number.isInteger(z)&&z>=0&&z<Q._l){if(!Q._c)Q._c=new Array(Q._l);if(Q._c[z]!==void 0)return Q._c[z];let Z=Z0(Q),L=PQ(Q._d,Z[z],Q._k,Q._g,Q._f,Q._p);return Q._c[z]=L,L}if($ in Array.prototype)return fQ(Q._d,Q._i)[$]}return},has(Q,$){if($===$Q||$==="free"||$===Symbol.dispose||$==="length")return!0;if(typeof $!=="string")return!1;let X=Number($);return Number.isInteger(X)&&X>=0&&X<Q._l},ownKeys(Q){let $=[];for(let X=0;X<Q._l;X++)$.push(String(X));return $.push("length"),$},getOwnPropertyDescriptor(Q,$){if($==="length")return{value:Q._l,writable:!1,enumerable:!1,configurable:!1};if(typeof $==="string"){let X=Number($);if(Number.isInteger(X)&&X>=0&&X<Q._l)return{value:this.get(Q,$,Q),writable:!1,enumerable:!0,configurable:!0}}return}},H0={get(Q,$,X){if($==="free"||$===Symbol.dispose)return Q._f;if($===$Q)return{docId:Q._d,index:Q._i};if(typeof $!=="string")return $===Symbol.toStringTag?"Object":void 0;if(!Q._c)Q._c=Object.create(null);if($ in Q._c)return Q._c[$];let{ptr:z,len:Z}=uQ($),L=q.doc_find_field(Q._d,Q._i,z,Z);if(L!==0){let T=PQ(Q._d,L,Q._k,Q._g,Q._f,!0);return Q._c[$]=T,T}let N=this.ownKeys(Q).indexOf($);if(N===-1)return;let G=PQ(Q._d,Q._ki[N]+1,Q._k,Q._g,Q._f,!0);return Q._c[$]=G,G},has(Q,$){if($===$Q||$==="free"||$===Symbol.dispose)return!0;if(typeof $!=="string")return!1;let{ptr:X,len:z}=uQ($);if(q.doc_find_field(Q._d,Q._i,X,z)!==0)return!0;return this.ownKeys(Q).includes($)},ownKeys(Q){if(!Q._keys){let $=oQ(q.doc_object_keys,Q._d,Q._i);Q._ki=$,Q._keys=Array.from($,(X)=>NQ(Q._d,X))}return Q._keys},getOwnPropertyDescriptor(Q,$){if(typeof $!=="string")return;let X=this.get(Q,$,Q);if(X===void 0)return;return{value:X,writable:!1,enumerable:!0,configurable:!0}}};function M0(Q){if(Q===null||typeof Q!=="object")return!1;try{return $Q in Q}catch{return!1}}function YQ(Q,$=!1){let X=q.doc_get_tag(Q,1);if(X<=xQ){let Y=X===CQ?null:X===vQ?!0:X===bQ?!1:X===yQ?q.doc_get_number(Q,1):NQ(Q,1);return ZQ.delete(Q),q.doc_free(Q),Y}let z=(XQ.get(Q)??0)+1;XQ.set(Q,z);let Z={docId:Q};return lQ.register(Z,{docId:Q,generation:z},Z),PQ(Q,1,Z,z,()=>{if(XQ.get(Q)!==z)return;XQ.delete(Q),ZQ.delete(Q),q.doc_free(Q),lQ.unregister(Z)},X===jQ||$)}function kQ(Q,$){let X=q.doc_parse(Q,$);if(X<0){let z=q.get_error_code();if(z===2||z===13){if(typeof globalThis.gc==="function")globalThis.gc();X=q.doc_parse(Q,$)}}return X}function VQ(Q){return Q.replace(/\[(\*|\d+)\]/g,".$1").split(".").filter(Boolean).map(($)=>$==="*"?"*":/^\d+$/.test($)?+$:$)}function dQ(Q,$,X){let z=[];for(let Z=0;Z<X;Z++)if(Q[Z]!==null)z.push(Q[Z]);else if($[Z]!==null)z.push(String($[Z]));return z.join(".")}return FQ={parse(Q){let{ptr:$,len:X}=GQ(Q,SQ,64,4096);new Uint8Array(q.memory.buffer,$+X,64).fill(32);let z=(G,T,f,y,e,o)=>{let B=JQ;return{status:G,value:T,remaining:e,error:o,isComplete(E){if(f===1/0)return!0;if(E===null||E===void 0||typeof E!=="object")return!0;try{let x=E[$Q];if(!x||typeof x.docId!=="number")return!0;let k=q.doc_get_tag(x.docId,x.index);if(k===jQ||k===sQ){let F=q.doc_get_close_index(x.docId,x.index);return q.doc_get_src_pos(x.docId,F)>>>0<f}return!0}catch{return!0}},toJSON(){if(B!==JQ)return B;return B=y!==void 0?JSON.parse(y):T}}},Z=(G)=>{if(!G){let T=q.get_error_code();G=`VectorJSON: ${tQ[T]||`Parse error (code ${T})`}`}return z("invalid",void 0,1/0,void 0,void 0,G)},L=typeof Q==="string"&&X===Q.length,Y=kQ($,X);if(Y>=0){if(L)ZQ.set(Y,Q);let G=typeof Q==="string"?Q:l.decode(new Uint8Array(q.memory.buffer,$,X));return z("complete",YQ(Y),1/0,G)}let N=q.classify_input($,X);if(N===X0)return Z("Invalid JSON structure");if(N===z0){let G=q.get_value_end(),T=X-G,f=new Uint8Array(T);f.set(new Uint8Array(q.memory.buffer,$+G,T)),new Uint8Array(q.memory.buffer,$+G,64).fill(32);let y=l.decode(new Uint8Array(q.memory.buffer,$,G));if(Y=kQ($,G),Y>=0){if(L)ZQ.set(Y,Q);return z("complete_early",YQ(Y),1/0,y,f)}return Z()}if(N===W0){let G=q.autocomplete_input($,X,SQ.cap);if(G===0){if(X===0)return z("incomplete",void 0,X,void 0);return Z("Invalid JSON structure")}let T=l.decode(new Uint8Array(q.memory.buffer,$,G));if(Y=kQ($,G),Y>=0)return z("incomplete",YQ(Y,!0),X,T);return Z()}return Z()},materialize(Q){if(!M0(Q))return Q;let{docId:$,index:X}=Q[$Q];return fQ($,X)},parsePartialJson(Q,$){if(!Q)return{value:void 0,state:"failed-parse"};let X=FQ.parse(Q);switch(X.status){case"complete":case"complete_early":{let z=X.toJSON();if($){let Z=$.safeParse(z);if(Z.success)return{value:Z.data,state:"successful-parse"};return{value:void 0,state:"successful-parse"}}return{value:z,state:"successful-parse"}}case"incomplete":{let z=X.toJSON();if($){let Z=$.safeParse(z);if(Z.success)return{value:Z.data,state:"repaired-parse"};return{value:z,state:"repaired-parse"}}return{value:z,state:"repaired-parse"}}default:return{value:void 0,state:"failed-parse"}}},createEventParser(Q){let $=Q?.multiRoot??!1,X=Q?.onRoot,z=q.stream_create();if(z<0)throw new Error("VectorJSON: Failed to create event parser (max 4 concurrent)");let Z=!1,L=0,Y=[],N=[],G=[],T=[],f=0,y=1,e=2,o=3,B=f,E="",x=0;function k(M){if(B===o)return M;let J="",U=0;while(U<M.length){if(B===o){J+=M.slice(U);break}if(B===y){let H=M.indexOf("</think>",U);if(H===-1){let W=M.slice(U);for(let O of T)O(W);U=M.length}else{let W=M.slice(U,H);if(W)for(let O of T)O(W);U=H+8,B=f,E=""}continue}if(B===e){let H="`".repeat(x),W=M.indexOf(H,U);if(W===-1)J+=M.slice(U),U=M.length;else J+=M.slice(U,W),U=W+x,x=0,B=f,E="";continue}let w=M[U];if(w==="{"||w==="["||w==='"'){if(E){for(let H of T)H(E);E=""}B=o,J+=M.slice(U);break}if(E+=w,E.endsWith("<think>")){let H=E.slice(0,-7);if(H)for(let W of T)W(H);B=y,E="",U++;continue}if(w==="`"){let H=0,W=U;while(W<M.length&&M[W]==="`")H++,W++;if(H>=3){while(W<M.length&&M[W]!==`
|
|
2
|
+
`)W++;if(W<M.length)W++;x=H,B=e;let O=E.slice(0,-1);if(O)for(let C of T)C(O);E="",U=W;continue}}if(U++,E.length>1024){for(let H of T)H(E);E=""}}if(J.length>0)return J;return null}let F=0,u=!1,g=!1,b=[],s=[],i=[],qQ=[],D=-1,_=!1,V=!1,R="",K=!1,P=-1,j=!1,A="",v=0,c=!1,WQ=-1,_Q=void 0,h=[],r=null,UQ=null,n="",zQ=!1,d="";function a(M){if(h.length===0){_Q=M;return}let J=h[h.length-1];if(Array.isArray(J))J.push(M);else if(r!==null)J[r]=M,UQ=r,r=null}function pQ(M){if(h.length===0){_Q=M;return}let J=h[h.length-1];if(Array.isArray(J))if(J.length>0)J[J.length-1]=M;else J.push(M);else if(UQ!==null)J[UQ]=M}function J0(){_Q=void 0,h.length=0,r=null,UQ=null,n="",zQ=!1,d=""}function Y0(){F=0,u=!1,g=!1,b.length=0,s.length=0,i.length=0,qQ.length=0,D=-1,_=!1,V=!1,R="",K=!1,P=-1,j=!1,A="",v=0,c=!1,WQ=-1,J0()}function hQ(M,J){let U=M.length;if(J?U!==F:U>F)return null;let w=[];for(let H=0;H<U;H++){let W=M[H],O=s[H],C=i[H];if(W==="*")w.push(C!==null?C:O??"");else if(typeof W==="number"?C!==W:O!==W)return null}return w}function wQ(){return G.length>0&&G.some((M)=>hQ(M,!1)!==null)}function TQ(M,J,U){if(Y.length===0)return;let w=dQ(s,i,F);for(let H of Y){let W=hQ(H.segments,!0);if(!W)continue;let O;try{O=JSON.parse(l.decode(M))}catch{continue}if(H.schema){let m=H.schema.safeParse(O);if(!m.success)continue;O=m.data}let C={type:"value",path:w,value:O,offset:J,length:U,matches:W};for(let m=W.length-1;m>=0;m--){let I=W[m];if(typeof I==="number"&&C.index===void 0)C.index=I;if(typeof I==="string"&&C.key===void 0)C.key=I}H.callback(C)}}function cQ(M,J,U){if(N.length===0)return;let w=dQ(s,i,F);for(let H of N){if(!hQ(H.segments,!0))continue;H.callback({type:"delta",path:w,value:M,offset:J,length:U})}}function rQ(M,J,U){for(let w=J;w<U;w++){let H=M[w];if(c){if(H===44||H===125||H===93||H===32||H===10||H===13||H===9){let W=w-WQ;TQ(M.slice(WQ,w),WQ,W);try{a(JSON.parse(d))}catch{a(null)}d="",c=!1,WQ=-1,w--;continue}d+=p[H];continue}if(g){if(g=!1,j&&D<0){let W;switch(H){case 110:W=`
|
|
3
|
+
`;break;case 114:W="\r";break;case 116:W="\t";break;case 34:W='"';break;case 92:W="\\";break;case 47:W="/";break;case 98:W="\b";break;case 102:W="\f";break;default:W=p[H];break}if(A+=W,zQ)n+=W;if(K)R+=W}else if(K)R+=p[H];continue}if(u){if(H===92){g=!0;continue}if(H===34){if(u=!1,K){if(K=!1,F>0)s[F-1]=R;r=R,R="";continue}if(j&&D<0){if(A&&N.length>0){let C=w-v;cQ(A,v,C)}A="";let W=P,O=w+1-W;TQ(M.slice(W,w+1),W,O),pQ(n),n="",zQ=!1}j=!1,P=-1;continue}if(j&&D<0){let W=p[H];if(A+=W,zQ)n+=W;if(K)R+=W}else if(K)R+=p[H];continue}switch(H){case 123:{if(b[F]="o",s[F]=null,i[F]=null,qQ[F]=w,F++,_=!0,V=!1,D<0&&wQ())D=F-1;let W={};a(W),h.push(W);break}case 91:{if(b[F]="a",s[F]=null,i[F]=0,qQ[F]=w,F++,_=!1,V=!1,D<0&&wQ())D=F-1;let W=[];a(W),h.push(W);break}case 125:case 93:{F--;let W=D>=0;if(W&&F<=D)D=-1;if(F>=0&&D<0&&!W){let O=qQ[F],C=w+1-O;TQ(M.slice(O,w+1),O,C)}if(F>0)_=b[F-1]==="o",V=!1;h.pop();break}case 34:{if(u=!0,_&&D<0)K=!0,R="";else if(V||F===0||F>0&&b[F-1]==="a"){if(D<0&&!wQ())j=!0,P=w,A="",v=w+1,n="",zQ=!0,a("");V=!1}break}case 58:{if(_=!1,V=!0,r!==null&&h.length>0){let W=h[h.length-1];if(!Array.isArray(W))W[r]=null,UQ=r}break}case 44:{if(F>0&&b[F-1]==="a"){let W=i[F-1];if(i[F-1]=(W??-1)+1,D<0&&wQ())D=F-1}if(F>0&&b[F-1]==="o")_=!0,s[F-1]=null;V=!1;break}default:{if(V||F===0||F>0&&b[F-1]==="a"){if(H>=48&&H<=57||H===45||H===116||H===102||H===110){if(D<0&&!wQ()){let W=w+1;while(W<U){let O=M[W];if(O===44||O===125||O===93||O===32||O===10||O===13||O===9)break;W++}if(W<U){TQ(M.slice(w,W),w,W-w);let O=l.decode(M.slice(w,W));try{a(JSON.parse(O))}catch{a(null)}w=W-1}else c=!0,WQ=w,d=l.decode(M.slice(w,U)),w=U}V=!1}}break}}}if(zQ&&n)pQ(n);if(j&&A.length>0&&D<0&&N.length>0)cQ(A,v,U-v),A="",v=U}let HQ={on(M,...J){let U,w;if(J.length===2&&typeof J[0]==="object"&&J[0]!==null&&"safeParse"in J[0])U=J[0],w=J[1];else w=J[0];return Y.push({segments:VQ(M),callback:w,schema:U}),HQ},onDelta(M,J){return N.push({segments:VQ(M),callback:J}),HQ},onText(M){return T.push(M),HQ},skip(...M){for(let J of M)G.push(VQ(J));return HQ},off(M,J){let U=VQ(M),w=(W,O)=>W.length===O.length&&W.every((C,m)=>C===O[m]),H=(W)=>{for(let O=W.length-1;O>=0;O--)if(w(W[O].segments,U)&&(!J||W[O].callback===J))W.splice(O,1)};return H(Y),H(N),HQ},feed(M){if(Z)throw new Error("EventParser already destroyed");let J;if(typeof M==="string"){if(J=k(M),J===null)return t[q.stream_get_status(z)]}else if(B===o)J=M;else{let m=l.decode(M),I=k(m);if(I===null)return t[q.stream_get_status(z)];J=KQ.encode(I)}let{ptr:U,len:w}=GQ(J,gQ,0,4096),H=q.stream_get_buffer_len(z),W=q.stream_feed(z,U,w),O=q.stream_get_buffer_len(z);if(O>H){let m=q.stream_get_buffer_ptr(z)>>>0,I=W===1||W===3?Math.min(O,q.stream_get_value_len(z)):O;if(I>H){let mQ=new Uint8Array(q.memory.buffer,m,I);rQ(mQ,H,I)}if((W===1||W===3)&&c&&d){try{a(JSON.parse(d))}catch{a(null)}d="",c=!1,WQ=-1}}let C=t[W]||"error";if($&&(C==="complete"||C==="end_early")){let m=0;while(m++<1e4){let I=q.stream_get_status(z);if(I!==1&&I!==3)break;let mQ=q.stream_get_buffer_ptr(z)>>>0,LQ=q.stream_get_value_len(z),MQ=new Uint8Array(LQ+64);MQ.set(new Uint8Array(q.memory.buffer,mQ,LQ)),MQ.fill(32,LQ);let nQ=q.stream_reset_for_next(z);Y0();let BQ=q.alloc(MQ.length)>>>0;if(BQ){new Uint8Array(q.memory.buffer,BQ,MQ.length).set(MQ);let RQ=q.doc_parse(BQ,LQ);if(q.dealloc(BQ,MQ.length),RQ>=0&&X)X({type:"root",index:L++,value:YQ(RQ)})}if(nQ>0&&(Y.length>0||N.length>0)){let RQ=q.stream_get_buffer_ptr(z)>>>0,IQ=q.stream_get_buffer_len(z);if(IQ>0){let U0=new Uint8Array(q.memory.buffer,RQ,IQ);rQ(U0,0,IQ)}}if(nQ===0)break}return t[q.stream_get_status(z)]||"incomplete"}return C},getValue(){if(Z)throw new Error("EventParser already destroyed");let M=q.stream_get_status(z);if(M===2)throw new SyntaxError("VectorJSON: Parse error in stream");if(M===0){let H=_Q;if(c&&d){let W=d,O=W.startsWith("t")?"true":W.startsWith("f")?"false":W.startsWith("n")?"null":W;try{let C=JSON.parse(O);if(h.length===0)H=C}catch{}}else if(zQ&&h.length===0)H=n;if(H===void 0)return;return H}let J=q.stream_get_buffer_ptr(z)>>>0,U=q.stream_get_value_len(z);new Uint8Array(q.memory.buffer,J+U,64).fill(32);let w=q.doc_parse(J,U);if(w<0){let H=q.get_error_code(),W=tQ[H]||`Parse error (code ${H})`;throw new SyntaxError(`VectorJSON: ${W}`)}return YQ(w)},getRemaining(){if(Z)return null;let M=q.stream_get_remaining_ptr(z)>>>0,J=q.stream_get_remaining_len(z);if(J>0){let U=new Uint8Array(J);return U.set(new Uint8Array(q.memory.buffer,M,J)),U}return null},getStatus(){if(Z)return"error";return t[q.stream_get_status(z)]||"error"},getRawBuffer(){if(Z)return null;let M=q.stream_get_buffer_ptr(z)>>>0,J=q.stream_get_buffer_len(z);if(J===0)return null;let U=new ArrayBuffer(J);return new Uint8Array(U).set(new Uint8Array(q.memory.buffer,M,J)),U},destroy(){if(!Z)q.stream_destroy(z),Z=!0}};return HQ},createParser(Q){let $=q.stream_create();if($<0)throw new Error("VectorJSON: Failed to create streaming parser (max 4 concurrent)");let X=!1,z=JQ,Z,L=void 0,Y=[],N=null,G=null,T="",f=!1,y="",e=!1,o=!1,B=0,E=[],x=!1,k=!1,F="",u=!1,g=!1;function b(_){if(Y.length===0){L=_;return}let V=Y[Y.length-1];if(Array.isArray(V))V.push(_);else if(N!==null)V[N]=_,G=N,N=null}function s(_){if(Y.length===0){L=_;return}let V=Y[Y.length-1];if(Array.isArray(V))if(V.length>0)V[V.length-1]=_;else V.push(_);else if(G!==null)V[G]=_}function i(_,V,R){for(let K=V;K<R;K++){let P=_[K];if(g){if(P===44||P===125||P===93||P===32||P===10||P===13||P===9){try{b(JSON.parse(y))}catch{b(null)}y="",g=!1,K--;continue}y+=p[P];continue}if(o){if(o=!1,f){let j;switch(P){case 110:j=`
|
|
4
|
+
`;break;case 114:j="\r";break;case 116:j="\t";break;case 34:j='"';break;case 92:j="\\";break;case 47:j="/";break;case 98:j="\b";break;case 102:j="\f";break;default:j=p[P];break}T+=j}if(u)F+=p[P];continue}if(e){if(P===92){o=!0;continue}if(P===34){if(e=!1,u){u=!1,N=F,F="";continue}if(f)s(T),T="",f=!1;continue}if(f)T+=p[P];if(u)F+=p[P];continue}switch(P){case 123:{E[B]="o",B++,x=!0,k=!1;let j={};b(j),Y.push(j);break}case 91:{E[B]="a",B++,x=!1,k=!1;let j=[];b(j),Y.push(j);break}case 125:case 93:{if(B--,Y.pop(),B>0)x=E[B-1]==="o",k=!1;break}case 34:{e=!0;let j=k||B===0||B>0&&E[B-1]==="a";if(x)u=!0,F="";else if(j)T="",f=!0,b(""),k=!1;break}case 58:{if(x=!1,k=!0,N!==null&&Y.length>0){let j=Y[Y.length-1];if(!Array.isArray(j))j[N]=null,G=N}break}case 44:{if(B>0&&E[B-1]==="o")x=!0;k=!1;break}default:{if(k||B===0||B>0&&E[B-1]==="a"){if(P>=48&&P<=57||P===45||P===116||P===102||P===110){let A=K+1;while(A<R){let v=_[A];if(v===44||v===125||v===93||v===32||v===10||v===13||v===9)break;A++}if(A<R){let v=l.decode(_.slice(K,A));try{b(JSON.parse(v))}catch{b(null)}K=A-1}else g=!0,y=l.decode(_.slice(K,R)),K=R;k=!1}}break}}}if(f&&T)s(T);if(g){let K=q.stream_get_status($);if(K===1||K===3){let P=y,j=P.startsWith("t")?"true":P.startsWith("f")?"false":P.startsWith("n")?"null":P;try{b(JSON.parse(j))}catch{b(null)}y="",g=!1}}}let qQ=()=>{if(Z!==void 0)return;let _=q.stream_get_remaining_ptr($)>>>0,V=q.stream_get_remaining_len($);if(V>0)Z=new Uint8Array(V),Z.set(new Uint8Array(q.memory.buffer,_,V));else Z=null},D=0;return{feed(_){if(X)throw new Error("Parser already destroyed");if((typeof _==="string"?_.length:_.byteLength)===0)return t[q.stream_get_status($)];let{ptr:R,len:K}=GQ(_,gQ,0,4096),P=q.stream_feed($,R,K),j=q.stream_get_buffer_len($);if(j>D){let A=q.stream_get_buffer_ptr($)>>>0,v=P===1||P===3?Math.min(j,q.stream_get_value_len($)):j;if(v>D){let c=new Uint8Array(q.memory.buffer,A,v);i(c,D,v)}D=j}return t[P]||"error"},getValue(){if(X)throw new Error("Parser already destroyed");if(z!==JQ)return z;let _=q.stream_get_status($);if(_===2)throw new SyntaxError("VectorJSON: Parse error in stream");if(_===0){let R=L;if(g&&y){let K=y,P=K.startsWith("t")?"true":K.startsWith("f")?"false":K.startsWith("n")?"null":K;try{let j=JSON.parse(P);if(Y.length===0)R=j}catch{}}else if(f&&Y.length===0)R=T;if(R===void 0)return;return R}if(g&&y){try{b(JSON.parse(y))}catch{b(null)}y="",g=!1}qQ();let V=L;if(Q){let R=Q.safeParse(V);if(!R.success)return z=void 0;V=R.data}return z=V},getRemaining(){if(X)return null;return qQ(),Z},getStatus(){if(X)return"error";let _=q.stream_get_status($);return t[_]||"error"},getRawBuffer(){if(X)return null;let _=q.stream_get_buffer_ptr($)>>>0,V=q.stream_get_buffer_len($);if(V===0)return null;let R=new ArrayBuffer(V);return new Uint8Array(R).set(new Uint8Array(q.memory.buffer,_,V)),R},destroy(){if(!X)q.stream_destroy($),X=!0,z=JQ}}}},FQ}async function P0(S){return(await eQ()).parse(S)}async function V0(S,QQ){let OQ=await eQ();if(QQ)return OQ.parsePartialJson(S,QQ);return OQ.parsePartialJson(S)}export{V0 as parsePartialJson,P0 as parse,eQ as init};
|
|
5
|
+
|
|
6
|
+
//# debugId=3E3F6A9010F3273664756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/js/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * VectorJSON — SIMD-accelerated JSON parser\n *\n * Architecture:\n * JS bytes → [Zig + zimdjson SIMD] → tape → lazy Proxy over doc slots\n *\n * The Zig engine (engine.wasm) parses JSON bytes into an internal tape format\n * using SIMD-accelerated algorithms from zimdjson.\n *\n * Primary parse path: doc-slot (tape-direct navigation via Zig exports).\n * FinalizationRegistry auto-frees doc slots when the Proxy is GC'd.\n * Users CAN call .free() to release immediately if desired.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\n// --- Types ---\n\nexport type ParseStatus = \"complete\" | \"complete_early\" | \"incomplete\" | \"invalid\";\nexport type FeedStatus = \"incomplete\" | \"complete\" | \"error\" | \"end_early\";\n\n/** Result shape compatible with Vercel AI SDK's parsePartialJson */\nexport type PartialJsonState =\n | \"successful-parse\"\n | \"repaired-parse\"\n | \"failed-parse\";\n\n/** Discriminated union — narrows `value` type when you check `state`. */\nexport type PartialJsonResult<T = unknown> =\n | { value: T; state: \"successful-parse\" }\n | { value: T | undefined; state: \"repaired-parse\" }\n | { value: undefined; state: \"failed-parse\" };\n\n/** Recursively make all properties optional — matches Vercel AI SDK's DeepPartial. */\nexport type DeepPartial<T> =\n T extends object\n ? T extends Array<infer U>\n ? Array<DeepPartial<U>>\n : { [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\nexport interface StreamingParser<T = unknown> {\n /** Feed a chunk of bytes to the parser. Only NEW bytes are scanned (O(chunk_size)). */\n feed(chunk: Uint8Array | string): FeedStatus;\n /** Get the parsed value. Returns autocompleted partial value while incomplete, final value when complete; throws on parse errors. */\n getValue(): T | undefined;\n /** Get remaining bytes after end_early status (for NDJSON). */\n getRemaining(): Uint8Array | null;\n /** Get the current status without feeding data. */\n getStatus(): FeedStatus;\n /** Copy the accumulated stream buffer into a new ArrayBuffer (for Worker postMessage transfer). */\n getRawBuffer(): ArrayBuffer | null;\n /** Destroy the parser and free all resources. */\n destroy(): void;\n}\n\nexport interface ParseResult {\n status: ParseStatus;\n value?: unknown;\n remaining?: Uint8Array;\n error?: string;\n /** Check if a value (object/array) from an incomplete parse is fully present in the original input. */\n isComplete(value: unknown): boolean;\n /** Full materialization via JSON.parse — fastest way to get a plain JS object tree. */\n toJSON(): unknown;\n}\n\n// --- EventParser Types ---\n\n/** Compiled path segment: string = key, number = index, '*' = wildcard */\nexport type PathSegment = string | number;\n\nexport interface PathEvent {\n type: 'value';\n path: string;\n value: unknown;\n offset: number;\n length: number;\n index?: number;\n key?: string;\n matches: (string | number)[];\n}\n\nexport interface DeltaEvent {\n type: 'delta';\n path: string;\n value: string;\n offset: number;\n length: number;\n}\n\nexport interface RootEvent {\n type: 'root';\n index: number;\n value: unknown;\n}\n\nexport interface EventParser {\n on(path: string, callback: (event: PathEvent) => void): EventParser;\n on<T>(path: string, schema: { safeParse: (v: unknown) => { success: boolean; data?: T } }, callback: (event: PathEvent & { value: T }) => void): EventParser;\n onDelta(path: string, callback: (event: DeltaEvent) => void): EventParser;\n onText(callback: (text: string) => void): EventParser;\n skip(...paths: string[]): EventParser;\n off(path: string, callback?: Function): EventParser;\n feed(chunk: string | Uint8Array): FeedStatus;\n getValue(): unknown | undefined;\n getRemaining(): Uint8Array | null;\n getStatus(): FeedStatus;\n /** Copy the accumulated stream buffer into a new ArrayBuffer (for Worker postMessage transfer). */\n getRawBuffer(): ArrayBuffer | null;\n destroy(): void;\n}\n\nexport interface VectorJSON {\n /**\n * Parse a JSON string or Uint8Array into a value.\n * Primitives (null, boolean, number) are returned directly as JS values.\n * Objects and arrays return Proxy objects — values materialize only when accessed.\n * Call .free() on the result to release resources immediately, or let\n * FinalizationRegistry handle it automatically when the Proxy is GC'd.\n */\n parse(input: string | Uint8Array): ParseResult;\n /**\n * Create a streaming parser for incremental JSON parsing.\n * Feed chunks as they arrive; only new bytes are processed per call.\n * Total work is O(N) regardless of how many chunks — no re-parsing.\n *\n * ```ts\n * const parser = vj.createParser();\n * for await (const chunk of stream) {\n * const status = parser.feed(chunk);\n * if (status === \"complete\" || status === \"end_early\") {\n * const value = parser.getValue();\n * // use value...\n * parser.destroy();\n * break;\n * }\n * }\n * ```\n */\n createParser(): StreamingParser;\n /**\n * Create a streaming parser with schema validation.\n * `getValue()` returns `undefined` when the schema rejects the value (same as incomplete).\n * T is auto-inferred from the schema — no manual `<T>` needed.\n *\n * ```ts\n * const parser = vj.createParser(z.object({ name: z.string() }));\n * parser.feed('{\"name\":\"Alice\"}');\n * parser.getValue(); // { name: string } | undefined\n * ```\n */\n createParser<T>(schema: { safeParse: (v: unknown) => { success: boolean; data?: T } }): StreamingParser<T>;\n /**\n * Eagerly materialize a lazy proxy into plain JS objects.\n * If the value is already a plain JS value, returns it as-is.\n */\n materialize(value: unknown): unknown;\n /**\n * Drop-in replacement for AI SDK partial JSON parsers.\n * Parses a potentially incomplete JSON string and returns a plain JS object.\n *\n * Compatible with Vercel AI SDK's `parsePartialJson` — returns `{ value, state }`\n * where state is \"successful-parse\", \"repaired-parse\", or \"failed-parse\".\n *\n * ```ts\n * // Drop-in for Vercel AI SDK:\n * const { value, state } = vj.parsePartialJson('{\"a\": 1, \"b\": ');\n * // value = { a: 1, b: null }, state = \"repaired-parse\"\n * ```\n */\n parsePartialJson(input: string): PartialJsonResult;\n /**\n * Parse partial JSON with schema-inferred types.\n * T is auto-inferred from the schema — no manual `<T>` needed.\n *\n * Returns `DeepPartial<T>` because incomplete JSON will have missing fields.\n * When `safeParse` succeeds, returns the validated `data`.\n * When `safeParse` fails on a repaired-parse, returns the raw parsed value\n * (typed as `DeepPartial<T>`) — the object is partial, that's expected.\n *\n * ```ts\n * const User = z.object({ name: z.string(), age: z.number() });\n * const { value, state } = vj.parsePartialJson('{\"name\":\"Al', User);\n * // value: { name?: string; age?: number } | undefined\n * // state: \"repaired-parse\"\n * ```\n */\n parsePartialJson<T>(input: string, schema: { safeParse: (v: unknown) => { success: boolean; data?: T } }): PartialJsonResult<DeepPartial<T>>;\n /**\n * Create an event-driven streaming parser with path subscriptions,\n * string delta emission, multi-root support, and JSON boundary detection.\n */\n createEventParser(options?: {\n multiRoot?: boolean;\n onRoot?: (event: RootEvent) => void;\n }): EventParser;\n}\n\n// --- Error codes from Zig engine ---\nconst ERROR_MESSAGES: Record<number, string> = {\n 1: \"Exceeded maximum nesting depth\",\n 2: \"Document exceeds maximum capacity\",\n 3: \"Invalid escape sequence\",\n 4: \"Invalid Unicode code point\",\n 5: \"Invalid number literal\",\n 6: \"Expected colon after key\",\n 7: \"Expected string key in object\",\n 8: \"Expected comma or closing bracket in array\",\n 9: \"Expected comma or closing brace in object\",\n 10: \"Incomplete array\",\n 11: \"Incomplete object\",\n 12: \"Unexpected trailing content\",\n 13: \"Out of memory\",\n 99: \"Unknown parse error\",\n};\n\n// --- Module types ---\n\ninterface EngineExports {\n memory: WebAssembly.Memory;\n alloc(size: number): number;\n dealloc(ptr: number, size: number): void;\n get_error_code(): number;\n doc_parse(ptr: number, len: number): number;\n doc_free(docId: number): void;\n doc_get_tag(docId: number, index: number): number;\n doc_get_number(docId: number, index: number): number;\n doc_read_string_raw(docId: number, index: number): number;\n doc_get_count(docId: number, index: number): number;\n doc_get_src_pos(docId: number, index: number): number;\n doc_get_close_index(docId: number, index: number): number;\n doc_find_field(docId: number, objIndex: number, keyPtr: number, keyLen: number): number;\n doc_get_input_ptr(docId: number): number;\n doc_batch_ptr(): number;\n doc_array_elements(docId: number, arrIndex: number, resumeAt: number): number;\n doc_object_keys(docId: number, objIndex: number, resumeAt: number): number;\n stream_create(): number;\n stream_destroy(id: number): void;\n stream_feed(id: number, ptr: number, len: number): number;\n stream_get_status(id: number): number;\n stream_get_buffer_ptr(id: number): number;\n stream_get_value_len(id: number): number;\n stream_get_remaining_ptr(id: number): number;\n stream_get_remaining_len(id: number): number;\n stream_get_buffer_len(id: number): number;\n stream_get_buffer_cap(id: number): number;\n stream_reset_for_next(id: number): number;\n classify_input(ptr: number, len: number): number;\n autocomplete_input(ptr: number, len: number, buf_cap: number): number;\n get_value_end(): number;\n}\n\nconst utf8Decoder = new TextDecoder('utf-8');\n\n// Pre-computed byte→char table — avoids String.fromCharCode() calls in hot loops\nconst B2C: string[] = Array.from({ length: 256 }, (_, i) => String.fromCharCode(i));\n\nlet _instance: VectorJSON | null = null;\n\n/**\n * Initialize VectorJSON by loading and linking the WASM module.\n * Call this once; subsequent calls return the cached instance.\n */\nexport async function init(options?: {\n engineWasm?: string | URL | BufferSource;\n}): Promise<VectorJSON> {\n if (_instance) return _instance;\n\n // Resolve WASM file path — always use import.meta.url at runtime\n // (avoids __dirname being baked in at bundle time by Bun/esbuild)\n const distDir = dirname(fileURLToPath(import.meta.url));\n const enginePath = join(distDir, \"engine.wasm\");\n\n // Load WASM bytes\n const engineBytes =\n options?.engineWasm instanceof ArrayBuffer ||\n ArrayBuffer.isView(options?.engineWasm)\n ? (options!.engineWasm as BufferSource)\n : await readFile(\n typeof options?.engineWasm === \"string\"\n ? options.engineWasm\n : options?.engineWasm instanceof URL\n ? fileURLToPath(options.engineWasm)\n : enginePath,\n );\n\n // --- Instantiate Zig engine ---\n const { instance: engineInstance } = await WebAssembly.instantiate(engineBytes, {});\n const engine = engineInstance.exports as unknown as EngineExports;\n\n const encoder = new TextEncoder();\n\n // --- Reusable WASM buffers — grow-only, shared allocator pattern ---\n const inputBuf = { ptr: 0, cap: 0 };\n const keyBuf = { ptr: 0, cap: 0 };\n const feedBuf = { ptr: 0, cap: 0 };\n\n function ensureBuf(buf: typeof inputBuf, needed: number, minCap: number): number {\n if (needed <= buf.cap) return buf.ptr;\n if (buf.ptr !== 0) engine.dealloc(buf.ptr, buf.cap);\n let cap = buf.cap === 0 ? minCap : buf.cap;\n while (cap < needed) cap *= 2;\n buf.ptr = engine.alloc(cap) >>> 0;\n if (buf.ptr === 0) throw new Error(\"VectorJSON: allocation failed\");\n buf.cap = cap;\n return buf.ptr;\n }\n\n /** Encode string or copy Uint8Array into a reusable WASM buffer. Returns { ptr, len }. */\n function writeToWasm(\n input: string | Uint8Array, buf: typeof inputBuf, extraCap: number, minCap: number,\n ): { ptr: number; len: number } {\n if (typeof input === \"string\") {\n // Try optimistic allocation (1x for likely-ASCII), fall back to 3x for multi-byte\n let maxBytes = input.length + extraCap;\n let ptr = ensureBuf(buf, maxBytes, minCap);\n let result = encoder.encodeInto(input, new Uint8Array(engine.memory.buffer, ptr, maxBytes));\n if (result.read! < input.length) {\n // Input has multi-byte chars — reallocate with worst-case 3x\n maxBytes = input.length * 3 + extraCap;\n ptr = ensureBuf(buf, maxBytes, minCap);\n result = encoder.encodeInto(input, new Uint8Array(engine.memory.buffer, ptr, maxBytes));\n }\n return { ptr, len: result.written! };\n }\n const len = input.byteLength;\n const ptr = ensureBuf(buf, len + extraCap, minCap);\n new Uint8Array(engine.memory.buffer, ptr, len).set(input);\n return { ptr, len };\n }\n\n function writeKeyToMemory(key: string): { ptr: number; len: number } {\n if (key.length === 0) return { ptr: 1, len: 0 };\n return writeToWasm(key, keyBuf, 0, 256);\n }\n\n // --- Constants ---\n // Batch buffer address is a fixed global in WASM — cache to avoid repeated WASM calls\n const batchAddr = engine.doc_batch_ptr() >>> 0;\n\n const TAG_NULL = 0;\n const TAG_TRUE = 1;\n const TAG_FALSE = 2;\n const TAG_NUMBER = 3;\n const TAG_STRING = 4;\n const TAG_OBJECT = 5;\n const TAG_ARRAY = 6;\n\n const FEED_STATUS: readonly FeedStatus[] = [\"incomplete\", \"complete\", \"error\", \"end_early\"];\n const CLASSIFY_INCOMPLETE = 0;\n const CLASSIFY_COMPLETE_EARLY = 2;\n const CLASSIFY_INVALID = 3;\n\n // --- Sentinels ---\n const LAZY_PROXY = Symbol(\"vectorjson.lazy\");\n const UNCACHED = Symbol();\n\n // --- Explicit document disposal ---\n // Track generation per docId to prevent stale FinalizationRegistry callbacks\n // from freeing a reused slot. Each parse increments the generation.\n const docGenerations = new Map<number, number>();\n\n // --- FinalizationRegistry for auto-cleanup of document slots ---\n const docRegistry = new FinalizationRegistry(\n ({ docId, generation }: { docId: number; generation: number }) => {\n if (docGenerations.get(docId) !== generation) return; // stale callback\n docGenerations.delete(docId);\n docInputs.delete(docId);\n engine.doc_free(docId);\n },\n );\n\n /** Copy `count` u32 indices from the WASM batch buffer into a JS Uint32Array. */\n function copyBatchIndices(count: number): Uint32Array {\n const copy = new Uint32Array(count);\n copy.set(new Uint32Array(engine.memory.buffer, batchAddr, count));\n return copy;\n }\n\n /** Read all batch indices with pagination for >16384 items. */\n function readBatchPaginated(\n fn: (docId: number, idx: number, resume: number) => number,\n docId: number, idx: number,\n ): Uint32Array {\n const BATCH_CAP = 16384;\n let count = fn(docId, idx, 0);\n if (count < BATCH_CAP) return copyBatchIndices(count);\n const all: number[] = [];\n let page = copyBatchIndices(count);\n for (let i = 0; i < count; i++) all.push(page[i]);\n while (count === BATCH_CAP) {\n const resumeAt = new Uint32Array(engine.memory.buffer, batchAddr + BATCH_CAP * 4, 1)[0];\n count = fn(docId, idx, resumeAt);\n page = copyBatchIndices(count);\n for (let i = 0; i < count; i++) all.push(page[i]);\n }\n return new Uint32Array(all);\n }\n\n // --- Per-document original input tracking (for ASCII fast-path) ---\n // When input is a JS string and all chars are ASCII (byteLen === str.length),\n // we can slice the original string directly instead of reading WASM memory.\n const docInputs = new Map<number, string>();\n\n // --- Read a doc string at a tape index into a JS string ---\n // Strings are stored as source offsets into the original input.\n // The escape flag (batch_buffer[2]) tells us if decoding is needed,\n // avoiding a linear scan with includes('\\\\').\n function docReadString(docId: number, index: number): string {\n const rawLen = engine.doc_read_string_raw(docId, index) >>> 0;\n if (rawLen === 0) return \"\";\n\n const batch = new Uint32Array(engine.memory.buffer, batchAddr, 3);\n const srcOffset = batch[0];\n const hasEscapes = batch[2];\n\n // ASCII fast-path: if original JS string is available and was ASCII,\n // slice directly — no WASM memory read, no TextDecoder overhead.\n const asciiInput = docInputs.get(docId);\n if (asciiInput !== undefined) {\n const raw = asciiInput.slice(srcOffset, srcOffset + rawLen);\n return hasEscapes ? JSON.parse('\"' + raw + '\"') : raw;\n }\n\n const inputPtr = engine.doc_get_input_ptr(docId) >>> 0;\n const raw = utf8Decoder.decode(\n new Uint8Array(engine.memory.buffer, inputPtr + srcOffset, rawLen),\n );\n // has_escapes flag from SIMD skipString — no need for includes('\\\\')\n return hasEscapes ? JSON.parse('\"' + raw + '\"') : raw;\n }\n\n // --- Deep materialize from document tape ---\n // For containers (objects/arrays), slices the source span from WASM memory\n // and delegates to native JSON.parse — faster than recursive tape walking.\n // For primitives, reads directly from the tape.\n function deepMaterializeDoc(docId: number, index: number): unknown {\n const tag = engine.doc_get_tag(docId, index);\n if (tag === TAG_NULL) return null;\n if (tag === TAG_TRUE) return true;\n if (tag === TAG_FALSE) return false;\n if (tag === TAG_NUMBER) return engine.doc_get_number(docId, index);\n if (tag === TAG_STRING) return docReadString(docId, index);\n if (tag === TAG_OBJECT || tag === TAG_ARRAY) {\n // Get source span: opening bracket → closing bracket (inclusive)\n // doc_get_close_index returns one-past-end (simdjson convention for skipping).\n // The actual closing bracket is at closeIdx - 1.\n const startPos = (engine.doc_get_src_pos(docId, index) >>> 0);\n const closingTapeIdx = engine.doc_get_close_index(docId, index) - 1;\n const closePos = engine.doc_get_src_pos(docId, closingTapeIdx);\n const inputPtr = engine.doc_get_input_ptr(docId) >>> 0;\n const raw = new Uint8Array(\n engine.memory.buffer, inputPtr + startPos, closePos + 1 - startPos,\n );\n return JSON.parse(utf8Decoder.decode(raw));\n }\n return null;\n }\n\n /** Batch-read all element tape indices for an array (cached). */\n function batchElemIndices(target: any): Uint32Array {\n return target._e || (target._e = readBatchPaginated(engine.doc_array_elements, target._d, target._i));\n }\n\n /** Resolve a tape value: primitives return directly.\n * Objects: deep-materialize (complete parses) or Proxy (incomplete, for isComplete).\n * Arrays: always lazy Proxy. */\n function resolveValue(\n docId: number, index: number,\n keepAlive: object, generation: number,\n freeFn: (() => void) | undefined,\n proxyObjects = false,\n ): unknown {\n const tag = engine.doc_get_tag(docId, index);\n if (tag === TAG_NULL) return null;\n if (tag === TAG_TRUE) return true;\n if (tag === TAG_FALSE) return false;\n if (tag === TAG_NUMBER) return engine.doc_get_number(docId, index);\n if (tag === TAG_STRING) return docReadString(docId, index);\n\n // Objects: Proxy for incomplete parses (so isComplete can get tape index),\n // deep-materialize for complete parses (fast native property access).\n if (tag === TAG_OBJECT) {\n if (proxyObjects) {\n return new Proxy({ _d: docId, _i: index, _k: keepAlive, _g: generation, _f: freeFn } as any, docObjHandler);\n }\n return deepMaterializeDoc(docId, index);\n }\n\n // Arrays → lazy Proxy (materialize elements on access, cached)\n return new Proxy(\n Object.assign([], { _d: docId, _i: index, _k: keepAlive, _g: generation, _f: freeFn,\n _l: engine.doc_get_count(docId, index), _p: proxyObjects }),\n docArrHandler,\n );\n }\n\n // --- Shared Proxy handler for doc-backed array cursors ---\n const docArrHandler: ProxyHandler<any> = {\n get(target, prop, _receiver) {\n if (prop === 'free' || prop === Symbol.dispose) return target._f;\n if (prop === LAZY_PROXY) return { docId: target._d, index: target._i };\n if (prop === 'length') return target._l;\n if (prop === Symbol.iterator) {\n const t = target; // single capture instead of 7 locals\n return function () {\n let i = 0;\n return {\n next() {\n if (i >= t._l) return { done: true as const, value: undefined };\n // Use indexed get to populate cache (avoids double-resolving)\n return { done: false as const, value: docArrHandler.get!(t, String(i++), t) };\n },\n };\n };\n }\n if (prop === Symbol.toStringTag) return \"Array\";\n if (typeof prop === 'string') {\n const idx = Number(prop);\n if (Number.isInteger(idx) && idx >= 0 && idx < target._l) {\n if (!target._c) target._c = new Array(target._l);\n if (target._c[idx] !== undefined) return target._c[idx];\n const indices = batchElemIndices(target);\n const val = resolveValue(target._d, indices[idx], target._k, target._g, target._f, target._p);\n target._c[idx] = val;\n return val;\n }\n if (prop in Array.prototype) {\n const materialized = deepMaterializeDoc(target._d, target._i) as unknown[];\n return (materialized as unknown as Record<string, unknown>)[prop];\n }\n }\n return undefined;\n },\n has(target, prop) {\n if (prop === LAZY_PROXY || prop === 'free' || prop === Symbol.dispose || prop === 'length') return true;\n if (typeof prop !== 'string') return false;\n const idx = Number(prop);\n return Number.isInteger(idx) && idx >= 0 && idx < target._l;\n },\n ownKeys(target) {\n const keys: string[] = [];\n for (let i = 0; i < target._l; i++) keys.push(String(i));\n keys.push('length');\n return keys;\n },\n getOwnPropertyDescriptor(target, prop) {\n if (prop === 'length') {\n return { value: target._l, writable: false, enumerable: false, configurable: false };\n }\n if (typeof prop === 'string') {\n const idx = Number(prop);\n if (Number.isInteger(idx) && idx >= 0 && idx < target._l) {\n return { value: this.get!(target, prop, target), writable: false, enumerable: true, configurable: true };\n }\n }\n return undefined;\n },\n };\n\n // --- Shared Proxy handler for doc-backed object proxies (incomplete parses) ---\n // doc_find_field compares raw source bytes against the key. For keys with\n // escape sequences (\\n, \\uXXXX), raw comparison fails — we fall back to\n // ownKeys iteration which properly decodes each key via docReadString.\n const docObjHandler: ProxyHandler<any> = {\n get(target, prop, _receiver) {\n if (prop === 'free' || prop === Symbol.dispose) return target._f;\n if (prop === LAZY_PROXY) return { docId: target._d, index: target._i };\n if (typeof prop !== 'string') return prop === Symbol.toStringTag ? \"Object\" : undefined;\n if (!target._c) target._c = Object.create(null);\n if (prop in target._c) return target._c[prop];\n const { ptr, len } = writeKeyToMemory(prop);\n const valIdx = engine.doc_find_field(target._d, target._i, ptr, len);\n if (valIdx !== 0) {\n // Fast path: key matched raw source bytes (no escapes)\n const val = resolveValue(target._d, valIdx, target._k, target._g, target._f, true);\n target._c[prop] = val;\n return val;\n }\n // Fallback: escaped keys won't match raw bytes — iterate all keys\n const keys = this.ownKeys!(target) as string[];\n const keyIdx = keys.indexOf(prop);\n if (keyIdx === -1) return undefined;\n // Resolve value via cached key tape indices\n const val = resolveValue(target._d, target._ki[keyIdx] + 1, target._k, target._g, target._f, true);\n target._c[prop] = val;\n return val;\n },\n has(target, prop) {\n if (prop === LAZY_PROXY || prop === 'free' || prop === Symbol.dispose) return true;\n if (typeof prop !== 'string') return false;\n const { ptr, len } = writeKeyToMemory(prop);\n if (engine.doc_find_field(target._d, target._i, ptr, len) !== 0) return true;\n // Fallback for escaped keys\n const keys = this.ownKeys!(target) as string[];\n return keys.includes(prop);\n },\n ownKeys(target) {\n if (!target._keys) {\n const indices = readBatchPaginated(engine.doc_object_keys, target._d, target._i);\n target._ki = indices;\n target._keys = Array.from(indices, (idx) => docReadString(target._d, idx));\n }\n return target._keys;\n },\n getOwnPropertyDescriptor(target, prop) {\n if (typeof prop !== 'string') return undefined;\n // JSON cannot produce undefined — get() returning undefined means field not found\n const val = this.get!(target, prop, target);\n if (val === undefined) return undefined;\n return { value: val, writable: false, enumerable: true, configurable: true };\n },\n };\n\n // --- Check if a value is a lazy proxy ---\n function isLazyProxy(value: unknown): boolean {\n if (value === null || typeof value !== \"object\") return false;\n try { return LAZY_PROXY in (value as Record<symbol, unknown>); }\n catch { return false; }\n }\n\n // --- Build a value from a doc slot root (shared by parse + createParser) ---\n function buildDocRoot(docId: number, proxyObjects = false): unknown {\n const rootTag = engine.doc_get_tag(docId, 1);\n // Primitives: extract value and free doc immediately (no Proxy needed)\n if (rootTag <= TAG_STRING) {\n const value = rootTag === TAG_NULL ? null\n : rootTag === TAG_TRUE ? true\n : rootTag === TAG_FALSE ? false\n : rootTag === TAG_NUMBER ? engine.doc_get_number(docId, 1)\n : docReadString(docId, 1);\n docInputs.delete(docId);\n engine.doc_free(docId);\n return value;\n }\n // Containers: register for GC and wrap in Proxy with manual .free()\n const generation = (docGenerations.get(docId) ?? 0) + 1;\n docGenerations.set(docId, generation);\n const keepAlive = { docId };\n docRegistry.register(keepAlive, { docId, generation }, keepAlive);\n const freeFn = () => {\n void keepAlive; // prevent GC of sentinel\n if (docGenerations.get(docId) !== generation) return;\n docGenerations.delete(docId);\n docInputs.delete(docId);\n engine.doc_free(docId);\n docRegistry.unregister(keepAlive);\n };\n // Root always gets Proxy so .free() is accessible; force objects to Proxy for isComplete()\n return resolveValue(docId, 1, keepAlive, generation, freeFn, rootTag === TAG_OBJECT || proxyObjects);\n }\n\n // --- Helper: retry doc_parse with GC on slot exhaustion ---\n function tryDocParse(p: number, l: number): number {\n let docId = engine.doc_parse(p, l);\n if (docId < 0) {\n const errCode = engine.get_error_code();\n if (errCode === 2 || errCode === 13) {\n if (typeof globalThis.gc === \"function\") globalThis.gc();\n docId = engine.doc_parse(p, l);\n }\n }\n return docId;\n }\n\n // --- Path Pattern Compiler ---\n // Segments: string = key, number = index, '*' = wildcard\n\n function compilePath(pattern: string): PathSegment[] {\n return pattern.replace(/\\[(\\*|\\d+)\\]/g, '.$1').split('.').filter(Boolean)\n .map(s => s === '*' ? '*' : /^\\d+$/.test(s) ? +s : s);\n }\n\n function buildResolvedPath(keyStack: (string | null)[], indexStack: (number | null)[], depth: number): string {\n const parts: string[] = [];\n for (let i = 0; i < depth; i++) {\n if (keyStack[i] !== null) parts.push(keyStack[i]!);\n else if (indexStack[i] !== null) parts.push(String(indexStack[i]));\n }\n return parts.join('.');\n }\n\n // --- Public API ---\n _instance = {\n parse(input: string | Uint8Array): ParseResult {\n // Write input into reusable WASM buffer with extra headroom for autocomplete\n const { ptr, len } = writeToWasm(input, inputBuf, 64, 4096);\n // Pad after input for SIMD safety\n new Uint8Array(engine.memory.buffer, ptr + len, 64).fill(0x20);\n\n // Helper: build ParseResult with isComplete() and toJSON()\n const makeResult = (\n status: ParseStatus,\n value: unknown,\n autocompleteBoundary: number,\n toJSONStr: string | undefined,\n remaining?: Uint8Array,\n error?: string,\n ): ParseResult => {\n let _toJSONCache: unknown = UNCACHED;\n return {\n status,\n value,\n remaining,\n error,\n isComplete(val: unknown): boolean {\n if (autocompleteBoundary === Infinity) return true;\n if (val === null || val === undefined || typeof val !== \"object\") return true;\n try {\n const handle = (val as any)[LAZY_PROXY] as { docId?: number; index?: number } | undefined;\n if (!handle || typeof handle.docId !== \"number\") return true;\n const tag = engine.doc_get_tag(handle.docId, handle.index!);\n if (tag === TAG_OBJECT || tag === TAG_ARRAY) {\n const closeIdx = engine.doc_get_close_index(handle.docId, handle.index!);\n const closeSrcPos = engine.doc_get_src_pos(handle.docId, closeIdx) >>> 0;\n return closeSrcPos < autocompleteBoundary;\n }\n return true;\n } catch {\n return true; // fail-safe: freed doc → treat as complete\n }\n },\n toJSON(): unknown {\n if (_toJSONCache !== UNCACHED) return _toJSONCache;\n return (_toJSONCache = toJSONStr !== undefined ? JSON.parse(toJSONStr) : value);\n },\n };\n };\n\n // Helper: build an invalid ParseResult from the last engine error code\n const invalidResult = (msg?: string): ParseResult => {\n if (!msg) {\n const code = engine.get_error_code();\n msg = `VectorJSON: ${ERROR_MESSAGES[code] || `Parse error (code ${code})`}`;\n }\n return makeResult(\"invalid\", undefined, Infinity, undefined, undefined, msg);\n };\n\n // Track whether input is an ASCII JS string (byteLen === str.length).\n // If so, docReadString can slice the original string directly.\n const isAsciiStr = typeof input === \"string\" && len === input.length;\n\n // ── Happy path: try doc_parse directly (no classify overhead) ──\n let docId = tryDocParse(ptr, len);\n if (docId >= 0) {\n if (isAsciiStr) docInputs.set(docId, input as string);\n // For string input at full length, reuse the original string (avoids decode)\n const toJSONStr = typeof input === \"string\" ? input\n : utf8Decoder.decode(new Uint8Array(engine.memory.buffer, ptr, len));\n return makeResult(\"complete\", buildDocRoot(docId), Infinity, toJSONStr);\n }\n\n // ── doc_parse failed — classify to determine why ──\n const classification = engine.classify_input(ptr, len);\n\n if (classification === CLASSIFY_INVALID) {\n return invalidResult(\"Invalid JSON structure\");\n }\n\n if (classification === CLASSIFY_COMPLETE_EARLY) {\n const parseLen = engine.get_value_end();\n const remainLen = len - parseLen;\n const remainingCopy = new Uint8Array(remainLen);\n remainingCopy.set(new Uint8Array(engine.memory.buffer, ptr + parseLen, remainLen));\n new Uint8Array(engine.memory.buffer, ptr + parseLen, 64).fill(0x20);\n\n const toJSONStr = utf8Decoder.decode(new Uint8Array(engine.memory.buffer, ptr, parseLen));\n docId = tryDocParse(ptr, parseLen);\n if (docId >= 0) {\n if (isAsciiStr) docInputs.set(docId, input as string);\n return makeResult(\"complete_early\", buildDocRoot(docId), Infinity, toJSONStr, remainingCopy);\n }\n return invalidResult();\n }\n\n if (classification === CLASSIFY_INCOMPLETE) {\n const parseLen = engine.autocomplete_input(ptr, len, inputBuf.cap);\n if (parseLen === 0) {\n if (len === 0) return makeResult(\"incomplete\", undefined, len, undefined);\n return invalidResult(\"Invalid JSON structure\");\n }\n const toJSONStr = utf8Decoder.decode(new Uint8Array(engine.memory.buffer, ptr, parseLen));\n docId = tryDocParse(ptr, parseLen);\n if (docId >= 0) {\n // Don't use ASCII fast-path for incomplete: autocomplete appended\n // closing tokens that aren't in the original JS string.\n return makeResult(\"incomplete\", buildDocRoot(docId, true), len, toJSONStr);\n }\n return invalidResult();\n }\n\n return invalidResult();\n },\n\n materialize(value: unknown): unknown {\n if (!isLazyProxy(value)) return value;\n const { docId, index } = (value as any)[LAZY_PROXY];\n return deepMaterializeDoc(docId, index);\n },\n\n parsePartialJson(input: string, schema?: { safeParse: (v: unknown) => { success: boolean; data?: unknown } }): PartialJsonResult {\n if (!input) return { value: undefined, state: \"failed-parse\" as const };\n const result = _instance!.parse(input);\n switch (result.status) {\n case \"complete\":\n case \"complete_early\": {\n const value = result.toJSON();\n if (schema) {\n const validated = schema.safeParse(value);\n if (validated.success) return { value: validated.data, state: \"successful-parse\" as const };\n return { value: undefined, state: \"successful-parse\" as const };\n }\n return { value, state: \"successful-parse\" as const };\n }\n case \"incomplete\": {\n const value = result.toJSON();\n if (schema) {\n const validated = schema.safeParse(value);\n if (validated.success) return { value: validated.data, state: \"repaired-parse\" as const };\n // Partial JSON: safeParse fails (missing fields expected) → keep raw value\n return { value, state: \"repaired-parse\" as const };\n }\n return { value, state: \"repaired-parse\" as const };\n }\n default:\n return { value: undefined, state: \"failed-parse\" as const };\n }\n },\n\n createEventParser(options?: {\n multiRoot?: boolean;\n onRoot?: (event: RootEvent) => void;\n }): EventParser {\n const multiRoot = options?.multiRoot ?? false;\n const onRootCb = options?.onRoot;\n\n const streamId = engine.stream_create();\n if (streamId < 0) {\n throw new Error(\"VectorJSON: Failed to create event parser (max 4 concurrent)\");\n }\n\n let destroyed = false;\n let rootIndex = 0;\n\n // --- Subscription storage ---\n type Sub = { segments: PathSegment[]; callback: Function; schema?: { safeParse: Function } };\n const pathSubs: Sub[] = [];\n const deltaSubs: Sub[] = [];\n const skipPatterns: PathSegment[][] = [];\n const textCallbacks: ((text: string) => void)[] = [];\n\n // --- JSON Seeker state ---\n const SEEKER_SEEKING = 0, SEEKER_IN_THINK = 1, SEEKER_IN_FENCE = 2, SEEKER_FEEDING = 3;\n let seekerState = SEEKER_SEEKING;\n let seekerBuf = ''; // accumulates non-JSON text for seeking\n let fenceBacktickCount = 0;\n\n function seekerFeed(text: string): string | null {\n // In FEEDING state, pass through directly\n if (seekerState === SEEKER_FEEDING) return text;\n\n let result = '';\n let i = 0;\n\n while (i < text.length) {\n if (seekerState === SEEKER_FEEDING) {\n result += text.slice(i);\n break;\n }\n\n if (seekerState === SEEKER_IN_THINK) {\n const closeIdx = text.indexOf('</think>', i);\n if (closeIdx === -1) {\n const captured = text.slice(i);\n for (const cb of textCallbacks) cb(captured);\n i = text.length;\n } else {\n const captured = text.slice(i, closeIdx);\n if (captured) for (const cb of textCallbacks) cb(captured);\n i = closeIdx + '</think>'.length;\n seekerState = SEEKER_SEEKING;\n seekerBuf = '';\n }\n continue;\n }\n\n if (seekerState === SEEKER_IN_FENCE) {\n // Look for closing fence\n const closeFence = '`'.repeat(fenceBacktickCount);\n const closeIdx = text.indexOf(closeFence, i);\n if (closeIdx === -1) {\n result += text.slice(i);\n i = text.length;\n } else {\n result += text.slice(i, closeIdx);\n i = closeIdx + fenceBacktickCount;\n fenceBacktickCount = 0;\n seekerState = SEEKER_SEEKING;\n seekerBuf = '';\n }\n continue;\n }\n\n // SEEKING state\n const ch = text[i];\n\n // Definitive JSON start characters → switch to FEEDING\n // Only { [ \" are reliable indicators — bare keywords (t/f/n) and\n // digits can appear in prose, so we only treat them as JSON start\n // if they're not part of other content.\n if (ch === '{' || ch === '[' || ch === '\"') {\n // Flush remaining seeker buf as text\n if (seekerBuf) {\n for (const cb of textCallbacks) cb(seekerBuf);\n seekerBuf = '';\n }\n seekerState = SEEKER_FEEDING;\n result += text.slice(i);\n break;\n }\n\n // Check for <think> tag\n seekerBuf += ch;\n if (seekerBuf.endsWith('<think>')) {\n const beforeTag = seekerBuf.slice(0, -'<think>'.length);\n if (beforeTag) for (const cb of textCallbacks) cb(beforeTag);\n seekerState = SEEKER_IN_THINK;\n seekerBuf = '';\n i++;\n continue;\n }\n\n // Check for code fence (``` with optional label)\n if (ch === '`') {\n // Count consecutive backticks\n let btCount = 0;\n let j = i;\n while (j < text.length && text[j] === '`') { btCount++; j++; }\n if (btCount >= 3) {\n // Skip label (e.g., \"json\") until newline\n while (j < text.length && text[j] !== '\\n') j++;\n if (j < text.length) j++; // skip the newline\n fenceBacktickCount = btCount;\n seekerState = SEEKER_IN_FENCE;\n const beforeFence = seekerBuf.slice(0, -1); // remove only the 1 backtick appended to seekerBuf\n if (beforeFence) for (const cb of textCallbacks) cb(beforeFence);\n seekerBuf = '';\n i = j;\n continue;\n }\n }\n\n // Whitespace and other non-JSON chars — keep seeking\n i++;\n\n // Flush accumulated non-JSON text periodically\n if (seekerBuf.length > 1024) {\n for (const cb of textCallbacks) cb(seekerBuf);\n seekerBuf = '';\n }\n }\n\n if (result.length > 0) return result;\n return null;\n }\n\n // --- PathTracker state ---\n let ptDepth = 0;\n let ptInString = false;\n let ptEscapeNext = false;\n let ptContextStack: ('o' | 'a')[] = []; // object or array at each level\n let ptKeyStack: (string | null)[] = []; // current key at each depth\n let ptIndexStack: (number | null)[] = []; // current array index at each depth\n let ptValueStartStack: number[] = []; // byte offset where value started\n let ptSkipDepth = -1; // if >= 0, we're inside a skipped path\n let ptExpectingKey = false;\n let ptAfterColon = false;\n let ptKeyAccum = '';\n let ptAccumulatingKey = false;\n let ptStringValueStart = -1;\n let ptInStringValue = false;\n let ptDeltaAccum = '';\n let ptDeltaByteStart = 0; // byte offset where current delta accumulation started\n let ptInScalar = false; // tracking a scalar that may span chunks\n let ptScalarStart = -1; // byte offset where current scalar started\n\n // --- Live document builder ---\n // Incrementally builds a JS object/array as bytes are scanned.\n // getValue() returns this growing object. O(n) total materialization.\n let ldRoot: unknown = undefined; // the growing root value\n let ldStack: (Record<string, unknown> | unknown[])[] = []; // container stack\n let ldCurrentKey: string | null = null; // pending key for object assignment\n let ldActiveKey: string | null = null; // key used for current string being updated\n let ldStringAccum = ''; // accumulating string value\n let ldInStringValue = false; // currently inside a string value\n let ldScalarAccum = ''; // accumulating scalar chars\n\n function ldSetValue(value: unknown) {\n if (ldStack.length === 0) {\n ldRoot = value;\n return;\n }\n const parent = ldStack[ldStack.length - 1];\n if (Array.isArray(parent)) {\n parent.push(value);\n } else if (ldCurrentKey !== null) {\n parent[ldCurrentKey] = value;\n ldActiveKey = ldCurrentKey; // remember key for in-place updates\n ldCurrentKey = null;\n }\n }\n\n // Update a string/scalar value in-place (for partial strings being built)\n function ldUpdateString(str: string) {\n if (ldStack.length === 0) {\n ldRoot = str;\n return;\n }\n const parent = ldStack[ldStack.length - 1];\n if (Array.isArray(parent)) {\n if (parent.length > 0) parent[parent.length - 1] = str;\n else parent.push(str);\n } else if (ldActiveKey !== null) {\n parent[ldActiveKey] = str;\n }\n }\n\n function ldReset() {\n ldRoot = undefined;\n ldStack.length = 0;\n ldCurrentKey = null;\n ldActiveKey = null;\n ldStringAccum = '';\n ldInStringValue = false;\n ldScalarAccum = '';\n }\n\n function ptReset() {\n ptDepth = 0; ptInString = false; ptEscapeNext = false;\n ptContextStack.length = 0; ptKeyStack.length = 0;\n ptIndexStack.length = 0; ptValueStartStack.length = 0;\n ptSkipDepth = -1; ptExpectingKey = false; ptAfterColon = false;\n ptKeyAccum = ''; ptAccumulatingKey = false;\n ptStringValueStart = -1; ptInStringValue = false;\n ptDeltaAccum = ''; ptDeltaByteStart = 0;\n ptInScalar = false; ptScalarStart = -1;\n ldReset();\n }\n\n /** Unified path matcher: exact = segments.length must equal depth, prefix = <= depth.\n * Returns wildcard matches on success, null on failure. */\n function matchPath(segments: PathSegment[], exact: boolean): (string | number)[] | null {\n const len = segments.length;\n if (exact ? len !== ptDepth : len > ptDepth) return null;\n const matches: (string | number)[] = [];\n for (let s = 0; s < len; s++) {\n const seg = segments[s];\n const key = ptKeyStack[s], idx = ptIndexStack[s];\n if (seg === '*') matches.push(idx !== null ? idx : (key ?? ''));\n else if (typeof seg === 'number' ? idx !== seg : key !== seg) return null;\n }\n return matches;\n }\n\n function isPathSkipped(): boolean {\n return skipPatterns.length > 0 && skipPatterns.some(p => matchPath(p, false) !== null);\n }\n\n function fireValueComplete(valueBytes: Uint8Array, offset: number, length: number) {\n if (pathSubs.length === 0) return;\n const resolvedPath = buildResolvedPath(ptKeyStack, ptIndexStack, ptDepth);\n for (const sub of pathSubs) {\n const matches = matchPath(sub.segments, true);\n if (!matches) continue;\n let value: unknown;\n try { value = JSON.parse(utf8Decoder.decode(valueBytes)); } catch { continue; }\n if (sub.schema) {\n const result = sub.schema.safeParse(value);\n if (!result.success) continue;\n value = result.data;\n }\n const event: PathEvent = { type: 'value', path: resolvedPath, value, offset, length, matches };\n for (let i = matches.length - 1; i >= 0; i--) {\n const m = matches[i];\n if (typeof m === 'number' && event.index === undefined) event.index = m;\n if (typeof m === 'string' && event.key === undefined) event.key = m;\n }\n sub.callback(event as any);\n }\n }\n\n function fireDelta(value: string, offset: number, length: number) {\n if (deltaSubs.length === 0) return;\n const resolvedPath = buildResolvedPath(ptKeyStack, ptIndexStack, ptDepth);\n for (const sub of deltaSubs) {\n if (!matchPath(sub.segments, true)) continue;\n sub.callback({ type: 'delta', path: resolvedPath, value, offset, length });\n }\n }\n\n function ptScan(buf: Uint8Array, from: number, to: number) {\n for (let i = from; i < to; i++) {\n const c = buf[i];\n\n // Check if we're continuing a scalar from a previous chunk\n if (ptInScalar) {\n if (c === 0x2C || c === 0x7D || c === 0x5D || c === 0x20 || c === 0x0A || c === 0x0D || c === 0x09) {\n // Scalar ended — fire value complete for the whole span\n const scalarLen = i - ptScalarStart;\n fireValueComplete(buf.slice(ptScalarStart, i), ptScalarStart, scalarLen);\n // Live doc: finalize scalar\n try { ldSetValue(JSON.parse(ldScalarAccum)); } catch { ldSetValue(null); }\n ldScalarAccum = '';\n ptInScalar = false;\n ptScalarStart = -1;\n // Re-process this delimiter char (it may be comma/close bracket)\n i--;\n continue;\n }\n // Still inside the scalar, keep scanning\n ldScalarAccum += B2C[c];\n continue;\n }\n\n if (ptEscapeNext) {\n ptEscapeNext = false;\n if (ptInStringValue && ptSkipDepth < 0) {\n // Decode escape for delta\n let decoded: string;\n switch (c) {\n case 0x6E: decoded = '\\n'; break; // n\n case 0x72: decoded = '\\r'; break; // r\n case 0x74: decoded = '\\t'; break; // t\n case 0x22: decoded = '\"'; break; // \"\n case 0x5C: decoded = '\\\\'; break; // \\\n case 0x2F: decoded = '/'; break; // /\n case 0x62: decoded = '\\b'; break; // b\n case 0x66: decoded = '\\f'; break; // f\n default: decoded = B2C[c]; break;\n }\n ptDeltaAccum += decoded;\n // Live doc: accumulate decoded escape char (batched — flushed at string close or chunk end)\n if (ldInStringValue) {\n ldStringAccum += decoded;\n }\n if (ptAccumulatingKey) ptKeyAccum += decoded;\n } else if (ptAccumulatingKey) {\n ptKeyAccum += B2C[c];\n }\n continue;\n }\n\n if (ptInString) {\n if (c === 0x5C) { // backslash\n ptEscapeNext = true;\n continue;\n }\n if (c === 0x22) { // closing quote\n ptInString = false;\n if (ptAccumulatingKey) {\n ptAccumulatingKey = false;\n // Store key at parent depth (ptDepth-1) since we're inside the container\n if (ptDepth > 0) ptKeyStack[ptDepth - 1] = ptKeyAccum;\n // Live doc: store key for next value assignment\n ldCurrentKey = ptKeyAccum;\n ptKeyAccum = '';\n continue;\n }\n // End of string value\n if (ptInStringValue && ptSkipDepth < 0) {\n // Flush final delta — use tracked byte offsets, not decoded char count\n if (ptDeltaAccum && deltaSubs.length > 0) {\n const deltaByteLen = i - ptDeltaByteStart; // raw bytes from start to closing quote\n fireDelta(ptDeltaAccum, ptDeltaByteStart, deltaByteLen);\n }\n ptDeltaAccum = '';\n // Fire value complete for the string\n const start = ptStringValueStart;\n const len = i + 1 - start;\n fireValueComplete(buf.slice(start, i + 1), start, len);\n // Live doc: final update (value already in parent from ldSetValue('') at open)\n ldUpdateString(ldStringAccum);\n ldStringAccum = '';\n ldInStringValue = false;\n }\n ptInStringValue = false;\n ptStringValueStart = -1;\n continue;\n }\n // Regular string character\n if (ptInStringValue && ptSkipDepth < 0) {\n const ch = B2C[c];\n ptDeltaAccum += ch;\n // Live doc: accumulate string char (batched — flushed at string close or chunk end)\n if (ldInStringValue) ldStringAccum += ch;\n if (ptAccumulatingKey) ptKeyAccum += ch;\n } else if (ptAccumulatingKey) {\n ptKeyAccum += B2C[c];\n }\n continue;\n }\n\n // Not in string\n switch (c) {\n case 0x7B: { // {\n ptContextStack[ptDepth] = 'o';\n ptKeyStack[ptDepth] = null;\n ptIndexStack[ptDepth] = null;\n ptValueStartStack[ptDepth] = i;\n ptDepth++;\n ptExpectingKey = true;\n ptAfterColon = false;\n // Check if we should skip this depth\n if (ptSkipDepth < 0 && isPathSkipped()) {\n ptSkipDepth = ptDepth - 1;\n }\n // Live doc: create object and push to stack\n const obj: Record<string, unknown> = {};\n ldSetValue(obj);\n ldStack.push(obj);\n break;\n }\n case 0x5B: { // [\n ptContextStack[ptDepth] = 'a';\n ptKeyStack[ptDepth] = null;\n ptIndexStack[ptDepth] = 0;\n ptValueStartStack[ptDepth] = i;\n ptDepth++;\n ptExpectingKey = false;\n ptAfterColon = false;\n if (ptSkipDepth < 0 && isPathSkipped()) {\n ptSkipDepth = ptDepth - 1;\n }\n // Live doc: create array and push to stack\n const arr: unknown[] = [];\n ldSetValue(arr);\n ldStack.push(arr);\n break;\n }\n case 0x7D: // }\n case 0x5D: { // ]\n ptDepth--;\n const wasSkipped = ptSkipDepth >= 0;\n if (wasSkipped && ptDepth <= ptSkipDepth) {\n ptSkipDepth = -1;\n }\n // Fire value complete for the container (only if not exiting a skipped path)\n if (ptDepth >= 0 && ptSkipDepth < 0 && !wasSkipped) {\n const start = ptValueStartStack[ptDepth];\n const len = i + 1 - start;\n fireValueComplete(buf.slice(start, i + 1), start, len);\n }\n // Restore parent context\n if (ptDepth > 0) {\n const parentCtx = ptContextStack[ptDepth - 1];\n ptExpectingKey = parentCtx === 'o';\n ptAfterColon = false;\n }\n // Live doc: pop container from stack\n ldStack.pop();\n break;\n }\n case 0x22: { // opening quote\n ptInString = true;\n if (ptExpectingKey && ptSkipDepth < 0) {\n // Start accumulating key\n ptAccumulatingKey = true;\n ptKeyAccum = '';\n } else if (ptAfterColon || ptDepth === 0 || (ptDepth > 0 && ptContextStack[ptDepth - 1] === 'a')) {\n // String value — only track if not in a skipped path\n if (ptSkipDepth < 0 && !isPathSkipped()) {\n ptInStringValue = true;\n ptStringValueStart = i;\n ptDeltaAccum = '';\n ptDeltaByteStart = i + 1; // byte after opening quote\n // Live doc: start string value accumulation\n ldStringAccum = '';\n ldInStringValue = true;\n // Push an empty string as placeholder so updates work\n ldSetValue('');\n }\n ptAfterColon = false;\n }\n break;\n }\n case 0x3A: { // colon\n ptExpectingKey = false;\n ptAfterColon = true;\n // Live doc: set null placeholder for pending key\n if (ldCurrentKey !== null && ldStack.length > 0) {\n const parent = ldStack[ldStack.length - 1];\n if (!Array.isArray(parent)) {\n (parent as Record<string, unknown>)[ldCurrentKey] = null;\n ldActiveKey = ldCurrentKey;\n }\n }\n break;\n }\n case 0x2C: { // comma\n // In array: increment index\n if (ptDepth > 0 && ptContextStack[ptDepth - 1] === 'a') {\n const idx = ptIndexStack[ptDepth - 1];\n ptIndexStack[ptDepth - 1] = (idx ?? -1) + 1;\n // Check skip for new array index\n if (ptSkipDepth < 0 && isPathSkipped()) {\n ptSkipDepth = ptDepth - 1;\n }\n }\n // In object: expect next key\n if (ptDepth > 0 && ptContextStack[ptDepth - 1] === 'o') {\n ptExpectingKey = true;\n ptKeyStack[ptDepth - 1] = null;\n }\n ptAfterColon = false;\n break;\n }\n default: {\n // Scalar values (numbers, true, false, null)\n if (ptAfterColon || ptDepth === 0 || (ptDepth > 0 && ptContextStack[ptDepth - 1] === 'a')) {\n if (c >= 0x30 && c <= 0x39 || c === 0x2D || c === 0x74 || c === 0x66 || c === 0x6E) {\n // Find end of scalar\n if (ptSkipDepth < 0 && !isPathSkipped()) {\n let j = i + 1;\n while (j < to) {\n const sc = buf[j];\n if (sc === 0x2C || sc === 0x7D || sc === 0x5D || sc === 0x20 || sc === 0x0A || sc === 0x0D || sc === 0x09) break;\n j++;\n }\n if (j < to) {\n // Complete scalar within this chunk\n fireValueComplete(buf.slice(i, j), i, j - i);\n // Live doc: parse and set scalar value\n const scalarStr = utf8Decoder.decode(buf.slice(i, j));\n try { ldSetValue(JSON.parse(scalarStr)); } catch { ldSetValue(null); }\n i = j - 1; // -1 because loop will increment\n } else {\n // Scalar extends past this chunk — track it\n ptInScalar = true;\n ptScalarStart = i;\n ldScalarAccum = utf8Decoder.decode(buf.slice(i, to));\n i = to; // skip to end, will resume on next feed\n }\n }\n ptAfterColon = false;\n }\n }\n break;\n }\n }\n }\n\n // Flush accumulated string to live doc parent (batched update)\n if (ldInStringValue && ldStringAccum) {\n ldUpdateString(ldStringAccum);\n }\n\n // Flush accumulated deltas at end of each feed for in-progress strings\n // This ensures onDelta fires incrementally per feed(), not just at string close\n if (ptInStringValue && ptDeltaAccum.length > 0 && ptSkipDepth < 0 && deltaSubs.length > 0) {\n fireDelta(ptDeltaAccum, ptDeltaByteStart, to - ptDeltaByteStart);\n ptDeltaAccum = '';\n ptDeltaByteStart = to;\n }\n }\n\n // --- EventParser object ---\n const self: EventParser = {\n on(path: string, ...args: any[]): EventParser {\n let schema: { safeParse: Function } | undefined;\n let callback: (event: PathEvent) => void;\n if (args.length === 2 && typeof args[0] === 'object' && args[0] !== null && 'safeParse' in args[0]) {\n schema = args[0];\n callback = args[1];\n } else {\n callback = args[0];\n }\n pathSubs.push({ segments: compilePath(path), callback, schema });\n return self;\n },\n\n onDelta(path: string, callback: (event: DeltaEvent) => void): EventParser {\n deltaSubs.push({ segments: compilePath(path), callback });\n return self;\n },\n\n onText(callback: (text: string) => void): EventParser {\n textCallbacks.push(callback);\n return self;\n },\n\n skip(...paths: string[]): EventParser {\n for (const p of paths) skipPatterns.push(compilePath(p));\n return self;\n },\n\n off(path: string, callback?: Function): EventParser {\n const compiled = compilePath(path);\n const eq = (a: PathSegment[], b: PathSegment[]) =>\n a.length === b.length && a.every((s, i) => s === b[i]);\n const remove = (subs: Sub[]) => {\n for (let i = subs.length - 1; i >= 0; i--) {\n if (eq(subs[i].segments, compiled) && (!callback || subs[i].callback === callback))\n subs.splice(i, 1);\n }\n };\n remove(pathSubs);\n remove(deltaSubs);\n return self;\n },\n\n feed(chunk: string | Uint8Array): FeedStatus {\n if (destroyed) throw new Error(\"EventParser already destroyed\");\n\n // Run through JSON seeker first\n let jsonContent: string | Uint8Array | null;\n if (typeof chunk === 'string') {\n jsonContent = seekerFeed(chunk);\n if (jsonContent === null) return FEED_STATUS[engine.stream_get_status(streamId)]!;\n } else if (seekerState === SEEKER_FEEDING) {\n // Fast path: skip string conversion when seeker is already feeding JSON\n jsonContent = chunk;\n } else {\n const str = utf8Decoder.decode(chunk);\n const result = seekerFeed(str);\n if (result === null) return FEED_STATUS[engine.stream_get_status(streamId)]!;\n jsonContent = encoder.encode(result);\n }\n\n // Feed to WASM stream\n const { ptr, len } = writeToWasm(jsonContent, feedBuf, 0, 4096);\n const prevLen = engine.stream_get_buffer_len(streamId);\n const status = engine.stream_feed(streamId, ptr, len);\n const newLen = engine.stream_get_buffer_len(streamId);\n\n // Scan new bytes with PathTracker (always runs — needed for live document builder)\n if (newLen > prevLen) {\n const bufPtr = (engine.stream_get_buffer_ptr(streamId) >>> 0);\n // For end_early/complete: only scan up to the value boundary\n const scanEnd = (status === 1 || status === 3)\n ? Math.min(newLen, engine.stream_get_value_len(streamId))\n : newLen;\n if (scanEnd > prevLen) {\n const wasmBuf = new Uint8Array(engine.memory.buffer, bufPtr, scanEnd);\n ptScan(wasmBuf, prevLen, scanEnd);\n }\n // Finalize pending scalar on complete/end_early\n if ((status === 1 || status === 3) && ptInScalar && ldScalarAccum) {\n try { ldSetValue(JSON.parse(ldScalarAccum)); } catch { ldSetValue(null); }\n ldScalarAccum = '';\n ptInScalar = false;\n ptScalarStart = -1;\n }\n }\n\n const feedStatus = FEED_STATUS[status] || \"error\";\n\n // Multi-root handling: drain all complete values\n if (multiRoot && (feedStatus === 'complete' || feedStatus === 'end_early')) {\n let loopGuard = 0;\n while (loopGuard++ < 10000) {\n const curStatus = engine.stream_get_status(streamId);\n if (curStatus !== 1 && curStatus !== 3) break; // not complete/end_early\n\n // Copy value bytes before reset (SIMD padding would overwrite remaining)\n const bp = (engine.stream_get_buffer_ptr(streamId) >>> 0);\n const vl = engine.stream_get_value_len(streamId);\n const valueCopy = new Uint8Array(vl + 64);\n valueCopy.set(new Uint8Array(engine.memory.buffer, bp, vl));\n // Pad copy for SIMD safety\n valueCopy.fill(0x20, vl);\n\n // Reset stream for next value BEFORE parsing (preserves remaining bytes)\n const remaining = engine.stream_reset_for_next(streamId);\n ptReset();\n\n // Now parse the copied value bytes\n const parsePtr = engine.alloc(valueCopy.length) >>> 0;\n if (parsePtr) {\n new Uint8Array(engine.memory.buffer, parsePtr, valueCopy.length).set(valueCopy);\n const did = engine.doc_parse(parsePtr, vl);\n engine.dealloc(parsePtr, valueCopy.length);\n if (did >= 0 && onRootCb) {\n onRootCb({ type: 'root', index: rootIndex++, value: buildDocRoot(did) });\n }\n }\n\n // Scan remaining bytes with PathTracker\n if (remaining > 0 && (pathSubs.length > 0 || deltaSubs.length > 0)) {\n const nbp = (engine.stream_get_buffer_ptr(streamId) >>> 0);\n const nbl = engine.stream_get_buffer_len(streamId);\n if (nbl > 0) {\n const wb = new Uint8Array(engine.memory.buffer, nbp, nbl);\n ptScan(wb, 0, nbl);\n }\n }\n\n if (remaining === 0) break;\n }\n return FEED_STATUS[engine.stream_get_status(streamId)] || \"incomplete\";\n }\n\n return feedStatus;\n },\n\n getValue(): unknown | undefined {\n if (destroyed) throw new Error(\"EventParser already destroyed\");\n const status = engine.stream_get_status(streamId);\n if (status === 2) throw new SyntaxError(\"VectorJSON: Parse error in stream\");\n\n if (status === 0) {\n // incomplete — return the incrementally-built live document\n let value: unknown = ldRoot;\n\n // Handle pending values not yet committed to ldRoot\n if (ptInScalar && ldScalarAccum) {\n const partial = ldScalarAccum;\n const completed = partial.startsWith('t') ? 'true'\n : partial.startsWith('f') ? 'false'\n : partial.startsWith('n') ? 'null'\n : partial;\n try {\n const parsed = JSON.parse(completed);\n if (ldStack.length === 0) value = parsed;\n } catch { /* leave as-is */ }\n } else if (ldInStringValue && ldStack.length === 0) {\n value = ldStringAccum;\n }\n\n if (value === undefined) return undefined;\n return value;\n }\n\n // complete or end_early — do a final WASM parse for correctness\n const bufPtr = (engine.stream_get_buffer_ptr(streamId) >>> 0);\n const valueLen = engine.stream_get_value_len(streamId);\n new Uint8Array(engine.memory.buffer, bufPtr + valueLen, 64).fill(0x20);\n const docId = engine.doc_parse(bufPtr, valueLen);\n if (docId < 0) {\n const errorCode = engine.get_error_code();\n const msg = ERROR_MESSAGES[errorCode] || `Parse error (code ${errorCode})`;\n throw new SyntaxError(`VectorJSON: ${msg}`);\n }\n return buildDocRoot(docId);\n },\n\n getRemaining(): Uint8Array | null {\n if (destroyed) return null;\n const rPtr = (engine.stream_get_remaining_ptr(streamId) >>> 0);\n const rLen = engine.stream_get_remaining_len(streamId);\n if (rLen > 0) {\n const copy = new Uint8Array(rLen);\n copy.set(new Uint8Array(engine.memory.buffer, rPtr, rLen));\n return copy;\n }\n return null;\n },\n\n getStatus(): FeedStatus {\n if (destroyed) return \"error\";\n return FEED_STATUS[engine.stream_get_status(streamId)] || \"error\";\n },\n\n getRawBuffer(): ArrayBuffer | null {\n if (destroyed) return null;\n const bufPtr = engine.stream_get_buffer_ptr(streamId) >>> 0;\n const bufLen = engine.stream_get_buffer_len(streamId);\n if (bufLen === 0) return null;\n const copy = new ArrayBuffer(bufLen);\n new Uint8Array(copy).set(new Uint8Array(engine.memory.buffer, bufPtr, bufLen));\n return copy;\n },\n\n destroy(): void {\n if (!destroyed) {\n engine.stream_destroy(streamId);\n destroyed = true;\n }\n },\n };\n\n return self;\n },\n\n createParser(schema?: { safeParse: (v: unknown) => { success: boolean; data?: unknown } }): StreamingParser {\n const streamId = engine.stream_create();\n if (streamId < 0) {\n throw new Error(\"VectorJSON: Failed to create streaming parser (max 4 concurrent)\");\n }\n\n let destroyed = false;\n let cachedValue: unknown = UNCACHED;\n let cachedRemaining: Uint8Array | null | undefined; // undefined = not yet cached\n\n // --- Live document builder state (same approach as EventParser) ---\n let ldRoot: unknown = undefined;\n let ldStack: (Record<string, unknown> | unknown[])[] = [];\n let ldCurrentKey: string | null = null;\n let ldActiveKey: string | null = null;\n let ldStringAccum = '';\n let ldInStringValue = false;\n let ldScalarAccum = '';\n\n // Byte scanner state\n let scanInString = false;\n let scanEscapeNext = false;\n let scanDepth = 0;\n let scanContext: ('o' | 'a')[] = [];\n let scanExpectingKey = false;\n let scanAfterColon = false;\n let scanKeyAccum = '';\n let scanAccumulatingKey = false;\n let scanInScalar = false;\n\n function spSetValue(value: unknown) {\n if (ldStack.length === 0) { ldRoot = value; return; }\n const parent = ldStack[ldStack.length - 1];\n if (Array.isArray(parent)) { parent.push(value); }\n else if (ldCurrentKey !== null) { parent[ldCurrentKey] = value; ldActiveKey = ldCurrentKey; ldCurrentKey = null; }\n }\n\n function spUpdateString(str: string) {\n if (ldStack.length === 0) { ldRoot = str; return; }\n const parent = ldStack[ldStack.length - 1];\n if (Array.isArray(parent)) {\n if (parent.length > 0) parent[parent.length - 1] = str;\n else parent.push(str);\n } else if (ldActiveKey !== null) { parent[ldActiveKey] = str; }\n }\n\n /** Scan new bytes to incrementally build the live JS document */\n function spScan(buf: Uint8Array, from: number, to: number) {\n for (let i = from; i < to; i++) {\n const c = buf[i];\n\n if (scanInScalar) {\n if (c === 0x2C || c === 0x7D || c === 0x5D || c === 0x20 || c === 0x0A || c === 0x0D || c === 0x09) {\n try { spSetValue(JSON.parse(ldScalarAccum)); } catch { spSetValue(null); }\n ldScalarAccum = '';\n scanInScalar = false;\n i--; continue;\n }\n ldScalarAccum += B2C[c];\n continue;\n }\n\n if (scanEscapeNext) {\n scanEscapeNext = false;\n if (ldInStringValue) {\n let decoded: string;\n switch (c) {\n case 0x6E: decoded = '\\n'; break;\n case 0x72: decoded = '\\r'; break;\n case 0x74: decoded = '\\t'; break;\n case 0x22: decoded = '\"'; break;\n case 0x5C: decoded = '\\\\'; break;\n case 0x2F: decoded = '/'; break;\n case 0x62: decoded = '\\b'; break;\n case 0x66: decoded = '\\f'; break;\n default: decoded = B2C[c]; break;\n }\n ldStringAccum += decoded;\n }\n if (scanAccumulatingKey) scanKeyAccum += B2C[c];\n continue;\n }\n\n if (scanInString) {\n if (c === 0x5C) { scanEscapeNext = true; continue; }\n if (c === 0x22) {\n scanInString = false;\n if (scanAccumulatingKey) {\n scanAccumulatingKey = false;\n ldCurrentKey = scanKeyAccum;\n scanKeyAccum = '';\n continue;\n }\n if (ldInStringValue) {\n // Final update at string close (value already in parent from spSetValue('') at open)\n spUpdateString(ldStringAccum);\n ldStringAccum = '';\n ldInStringValue = false;\n }\n continue;\n }\n if (ldInStringValue) ldStringAccum += B2C[c];\n if (scanAccumulatingKey) scanKeyAccum += B2C[c];\n continue;\n }\n\n switch (c) {\n case 0x7B: {\n scanContext[scanDepth] = 'o';\n scanDepth++;\n scanExpectingKey = true;\n scanAfterColon = false;\n const obj: Record<string, unknown> = {};\n spSetValue(obj);\n ldStack.push(obj);\n break;\n }\n case 0x5B: {\n scanContext[scanDepth] = 'a';\n scanDepth++;\n scanExpectingKey = false;\n scanAfterColon = false;\n const arr: unknown[] = [];\n spSetValue(arr);\n ldStack.push(arr);\n break;\n }\n case 0x7D: case 0x5D: {\n scanDepth--;\n ldStack.pop();\n if (scanDepth > 0) {\n scanExpectingKey = scanContext[scanDepth - 1] === 'o';\n scanAfterColon = false;\n }\n break;\n }\n case 0x22: {\n scanInString = true;\n const isValue = scanAfterColon || scanDepth === 0 || (scanDepth > 0 && scanContext[scanDepth - 1] === 'a');\n if (scanExpectingKey) {\n scanAccumulatingKey = true;\n scanKeyAccum = '';\n } else if (isValue) {\n ldStringAccum = '';\n ldInStringValue = true;\n spSetValue('');\n scanAfterColon = false;\n }\n break;\n }\n case 0x3A: {\n scanExpectingKey = false;\n scanAfterColon = true;\n // Set null placeholder for the pending key — will be overwritten\n // when the real value arrives. This ensures getValue() during\n // incomplete streaming shows {\"key\": null} instead of {}.\n if (ldCurrentKey !== null && ldStack.length > 0) {\n const parent = ldStack[ldStack.length - 1];\n if (!Array.isArray(parent)) {\n (parent as Record<string, unknown>)[ldCurrentKey] = null;\n ldActiveKey = ldCurrentKey;\n }\n }\n break;\n }\n case 0x2C: {\n if (scanDepth > 0 && scanContext[scanDepth - 1] === 'o') {\n scanExpectingKey = true;\n }\n scanAfterColon = false;\n break;\n }\n default: {\n const isValuePos = scanAfterColon || scanDepth === 0 || (scanDepth > 0 && scanContext[scanDepth - 1] === 'a');\n if (isValuePos) {\n if (c >= 0x30 && c <= 0x39 || c === 0x2D || c === 0x74 || c === 0x66 || c === 0x6E) {\n let j = i + 1;\n while (j < to) {\n const sc = buf[j];\n if (sc === 0x2C || sc === 0x7D || sc === 0x5D || sc === 0x20 || sc === 0x0A || sc === 0x0D || sc === 0x09) break;\n j++;\n }\n if (j < to) {\n const scalarStr = utf8Decoder.decode(buf.slice(i, j));\n try { spSetValue(JSON.parse(scalarStr)); } catch { spSetValue(null); }\n i = j - 1;\n } else {\n scanInScalar = true;\n ldScalarAccum = utf8Decoder.decode(buf.slice(i, to));\n i = to;\n }\n scanAfterColon = false;\n }\n }\n break;\n }\n }\n }\n\n // End-of-chunk: flush accumulated string to parent (batched update)\n if (ldInStringValue && ldStringAccum) {\n spUpdateString(ldStringAccum);\n }\n\n // End-of-chunk: if we're still accumulating a scalar and stream says complete,\n // finalize it now (root-level scalars like \"42\" end at end-of-buffer)\n if (scanInScalar) {\n const status = engine.stream_get_status(streamId);\n if (status === 1 || status === 3) { // complete or end_early\n // Autocomplete partial keywords (e.g., \"tr\" → \"true\")\n const s = ldScalarAccum;\n const completed = s.startsWith('t') ? 'true'\n : s.startsWith('f') ? 'false'\n : s.startsWith('n') ? 'null' : s;\n try { spSetValue(JSON.parse(completed)); } catch { spSetValue(null); }\n ldScalarAccum = '';\n scanInScalar = false;\n }\n }\n }\n\n const ensureRemaining = () => {\n if (cachedRemaining !== undefined) return;\n const rPtr = (engine.stream_get_remaining_ptr(streamId) >>> 0);\n const rLen = engine.stream_get_remaining_len(streamId);\n if (rLen > 0) {\n cachedRemaining = new Uint8Array(rLen);\n cachedRemaining.set(new Uint8Array(engine.memory.buffer, rPtr, rLen));\n } else {\n cachedRemaining = null;\n }\n };\n\n let prevLen = 0;\n\n return {\n feed(chunk: Uint8Array | string): FeedStatus {\n if (destroyed) throw new Error(\"Parser already destroyed\");\n const chunkLen = typeof chunk === \"string\" ? chunk.length : chunk.byteLength;\n if (chunkLen === 0) return FEED_STATUS[engine.stream_get_status(streamId)]!;\n const { ptr, len } = writeToWasm(chunk, feedBuf, 0, 4096);\n const rawStatus = engine.stream_feed(streamId, ptr, len);\n // Scan new bytes for live document building\n const newLen = engine.stream_get_buffer_len(streamId);\n if (newLen > prevLen) {\n const bufPtr = (engine.stream_get_buffer_ptr(streamId) >>> 0);\n // For end_early/complete: only scan up to the value boundary, not trailing data\n const scanEnd = (rawStatus === 1 || rawStatus === 3)\n ? Math.min(newLen, engine.stream_get_value_len(streamId))\n : newLen;\n if (scanEnd > prevLen) {\n const wasmBuf = new Uint8Array(engine.memory.buffer, bufPtr, scanEnd);\n spScan(wasmBuf, prevLen, scanEnd);\n }\n prevLen = newLen;\n }\n return FEED_STATUS[rawStatus] || \"error\";\n },\n\n getValue(): unknown | undefined {\n if (destroyed) throw new Error(\"Parser already destroyed\");\n if (cachedValue !== UNCACHED) return cachedValue;\n\n const status = engine.stream_get_status(streamId);\n if (status === 2) {\n throw new SyntaxError(\"VectorJSON: Parse error in stream\");\n }\n\n if (status === 0) {\n // incomplete — return the incrementally-built live document\n // The returned object IS the live object — it grows as more data arrives.\n // Callers get a reference that automatically reflects future feed() calls.\n let value: unknown = ldRoot;\n\n // Handle pending partial values that haven't been committed to ldRoot yet:\n if (scanInScalar && ldScalarAccum) {\n // Pending scalar: try to autocomplete (e.g., \"tr\" → true)\n const partial = ldScalarAccum;\n const completed = partial.startsWith('t') ? 'true'\n : partial.startsWith('f') ? 'false'\n : partial.startsWith('n') ? 'null'\n : partial;\n try {\n const parsed = JSON.parse(completed);\n if (ldStack.length === 0) value = parsed;\n } catch { /* partial number like \"1.\" — leave as-is */ }\n } else if (ldInStringValue && ldStack.length === 0) {\n // Root-level string still being accumulated\n value = ldStringAccum;\n }\n\n if (value === undefined) return undefined;\n // Incomplete: return partial value without schema gating.\n // User checks getStatus() to know it's not final.\n return value;\n }\n\n // complete or end_early — finalize any pending scalar\n if (scanInScalar && ldScalarAccum) {\n try { spSetValue(JSON.parse(ldScalarAccum)); } catch { spSetValue(null); }\n ldScalarAccum = '';\n scanInScalar = false;\n }\n ensureRemaining();\n\n let value: unknown = ldRoot;\n if (schema) {\n const result = schema.safeParse(value);\n if (!result.success) return (cachedValue = undefined) as undefined;\n value = result.data;\n }\n return (cachedValue = value);\n },\n\n getRemaining(): Uint8Array | null {\n if (destroyed) return null;\n ensureRemaining();\n return cachedRemaining!;\n },\n\n getStatus(): FeedStatus {\n if (destroyed) return \"error\";\n const status = engine.stream_get_status(streamId);\n return FEED_STATUS[status] || \"error\";\n },\n\n getRawBuffer(): ArrayBuffer | null {\n if (destroyed) return null;\n const bufPtr = engine.stream_get_buffer_ptr(streamId) >>> 0;\n const bufLen = engine.stream_get_buffer_len(streamId);\n if (bufLen === 0) return null;\n const copy = new ArrayBuffer(bufLen);\n new Uint8Array(copy).set(new Uint8Array(engine.memory.buffer, bufPtr, bufLen));\n return copy;\n },\n\n destroy(): void {\n if (!destroyed) {\n engine.stream_destroy(streamId);\n destroyed = true;\n cachedValue = UNCACHED;\n }\n },\n };\n },\n };\n\n return _instance;\n}\n\n/**\n * Convenience: parse JSON using a pre-initialized instance.\n * Initializes on first call.\n */\nexport async function parse(input: string | Uint8Array): Promise<ParseResult> {\n const vj = await init();\n return vj.parse(input);\n}\n\n/**\n * Convenience: parse partial JSON using a pre-initialized instance.\n * Drop-in replacement for AI SDK partial JSON parsers.\n * Initializes on first call.\n *\n * ```ts\n * import { parsePartialJson } from 'vectorjson';\n * const { value, state } = await parsePartialJson('{\"a\": 1, \"b\": ');\n * ```\n */\nexport async function parsePartialJson(input: string): Promise<PartialJsonResult>;\nexport async function parsePartialJson<T>(input: string, schema: { safeParse: (v: unknown) => { success: boolean; data?: T } }): Promise<PartialJsonResult<DeepPartial<T>>>;\nexport async function parsePartialJson(input: string, schema?: { safeParse: (v: unknown) => { success: boolean; data?: unknown } }): Promise<PartialJsonResult> {\n const vj = await init();\n if (schema) return vj.parsePartialJson(input, schema);\n return vj.parsePartialJson(input);\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "3E3F6A9010F3273664756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|