March Docs

JsonStream

JsonStream: resumable, total, constant-memory streaming JSON tokenizer.

Design: specs/2026-07-30-json-streaming-design.md. Feed chunks with feed, close with finish. Every failure is an Err with an absolute byte offset; no input can panic, crash, or grow memory beyond the configured limits. The per-byte loop is strictly tail-recursive — keep it that way (see the design's "why a state machine" section).

All constructor names are prefixed (Ev/E/M/P/S/Js/St*): the ctor namespace is flat across modules, and Json.JsonValue already owns the natural names. Do not rename until FQN type identity lands.

Types

typeEventEvent =#
typeJsonStreamErrorJsonStreamError =#
typeJsonLimitsJsonLimits = JsonLimits(Int, Int)#
ptypeJsModeJsMode =#
ptypeJsEscJsEsc = SPlain | SEsc | SHex(Int, Int)#
ptypeJsPartialJsPartial =#
ptypeJsCfgJsCfg = JsCfg(Int, Int, Bool, Bool)#
ptypeJsStateJsState = StOk(JsCfg, JsMode, List(JsMode), Int, JsPartial, Int)#
ptypeJsFrameJsFrame =#

Functions

fnbuildbuild(chunks)#
fndefault_limitsdefault_limits() do JsonLimits(512, 8000000) end#
fneach_typedeach_typed(path, cb)#
fneach_valueeach_value(path, cb)#
fnerr_to_stringerr_to_string(e)#
fnfeedfeed(st, chunk)#
fnfinishfinish(st)#
fnfoldfold(chunks, z, f)#
fnstartstart() do StOk(cfg_of(default_limits(), false), MTop, Nil, 0, PNone, 0) end#
fnstart_ndjsonstart_ndjson() do StOk(cfg_of(default_limits(), true), MTop, Nil, 0, PNone, 0) end#
fnstart_ndjson_withstart_ndjson_with(l) do StOk(cfg_of(l, true), MTop, Nil, 0, PNone, 0) end#
fnstart_withstart_with(l) do StOk(cfg_of(l, false), MTop, Nil, 0, PNone, 0) end#
fnwith_raw_numberswith_raw_numbers(st)#

Emit EvNumRaw(lexeme) instead of EvNum(float), preserving integers above 2^53 that a Float cannot represent.

Composes with every constructor:

    let st = JsonStream.with_raw_numbers(JsonStream.start_ndjson())

Validation is unchanged -- a malformed number is still rejected with the
same error at the same offset.  Intended for a fresh state; applied
mid-stream it affects only numbers completed after the call.