mdz_stream_parser_state.ts

Streaming parser state and low-level operations.

Free functions take a MdzStreamParserState first parameter so handlers can live in separate sibling modules — JS private (#) fields can't cross module boundaries.

Declarations
#

21 declarations

view source

accumulate_text
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState, text: string, start_offset: number): void import {accumulate_text} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Accumulate text, tracking the start offset for the first character.

state

text

type string

start_offset

type number

returns

void

alloc_id
#

close_codeblock_at_eof
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState): void import {close_codeblock_at_eof} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Close an unclosed codeblock at EOF by reverting it to a paragraph wrapper.

Unlike revert_empty_codeblock (which pushes the wrapper onto the stack because parsing continues), this is terminal — called only from finish() after no further emits happen — so it skips the push_stack_entry / in_paragraph / paragraph_stack_idx bookkeeping. The wrapper exists only in the opcode stream; the parser state's stack stays untouched.

state

returns

void

close_heading
#

close_paragraph
#

CodeblockState
#

mdz_stream_parser_state.ts view source

CodeblockState import type {CodeblockState} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

id

type MdzNodeId

backtick_count

type number

text_id

type MdzNodeId | null

delimiter

The full opening fence line (e.g. "``ts\n"), used as replacement_text` on revert.

type string

start

Global byte offset of the opening fence.

type number

create_state
#

emit
#

ensure_paragraph
#

find_open
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState, type: MdzContainerNodeType): number import {find_open} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Find the innermost open container of a given type. Returns stack index, or -1 if not found. Does not cross block boundaries (Paragraph, Heading).

state

type

returns

number

flush_text
#

handle_paragraph_break
#

MdzStreamParserState
#

mdz_stream_parser_state.ts view source

MdzStreamParserState import type {MdzStreamParserState} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Mutable state for the streaming parser. One instance per MdzStreamParser. Handlers in sibling modules take this as their first parameter — the streaming parser uses free functions, not class methods, so state crosses module boundaries.

buffer

type string

pos

type number

opcodes

type Array<MdzOpcode>

next_id

type MdzNodeId

stack

type Array<StackEntry>

column

type number

prev_char

type number

active_text_id

type MdzNodeId | null

accumulated_text

type string

accumulated_text_start

type number

codeblock

type CodeblockState | null

base_offset

Global byte offset of the start of buffer.

type number

in_heading

Whether we're inside a heading (newline ends it).

type boolean

in_code

Whether we're inside an optimistic inline Code container.

type boolean

in_paragraph

Cached flag: whether a Paragraph is open on the stack.

type boolean

pending_url

type PendingUrl | null

heading_text_parts

Stack of text segments for heading ID computation. Each open container inside a heading pushes a new segment. On close: pop and append to parent (children's text is part of heading). On revert: pop, prepend replacement_text, append to parent (document order: delimiter text comes before children's text).

type Array<string>

skip_leading_newlines

When true, skip leading newlines at the start of the next processing pass. Set after block element closes (codeblock, heading, HR) when trailing newlines couldn't be absorbed within the same buffer — needed for char-by-char streaming where post-block newlines arrive in later chunks.

type boolean

paragraph_stack_idx

Stack index of the innermost open Paragraph, or -1 when none. Lets mark_paragraph_non_whitespace skip the stack walk that runs on every non-whitespace emit. Updated only on Paragraph push/pop (block boundaries — only one of Paragraph/Heading can be on the stack at a time, so the cache is stable across inline pushes/pops).

type number

last_text_id

Id of the most-recent text/append_text emission, used by trim_trailing_newline to target the right opcode after take_opcodes() has drained the queue. null after a structural emit (open/close/revert) sealed the prior text run.

type MdzNodeId | null

last_text_ended_with_newline

Whether the most recent text emission's content ended in '\n'.

type boolean

last_text_was_singleton_newline

Whether the most recent text emission was a text opcode (not append_text) with content exactly '\n' — trimming the trailing \n would leave the text node empty, so active_text_id must be cleared to keep subsequent content from merging into a deleted node.

type boolean

offset
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState, pos?: number): number import {offset} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Global byte offset for a local buffer position.

state

pos

type number
default state.pos

returns

number

PendingUrl
#

mdz_stream_parser_state.ts view source

PendingUrl import type {PendingUrl} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Pending auto-link URL/path state for text-first rendering. When set, URL chars flow as visible text. On terminator, a wrap opcode retroactively wraps the text node in a Link.

For URLs, confirmed starts false during speculative prefix matching (chars stream as text while we verify https:// or http://). For paths, confirmed starts true (prefix already validated by hold).

url_text

type string

start

type number

link_type

type 'external' | 'internal'

confirmed

Whether the URL/path prefix has been fully confirmed.

type boolean

viable_https

Prefix match tracking — only used when !confirmed.

type boolean

viable_http

type boolean

push_stack_entry
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState, id: number, node_type: MdzContainerNodeType, start: number, optimistic?: boolean, delimiter?: string, tag_name?: string | undefined): void import {push_stack_entry} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Push a new container frame onto the stack. Fills the boilerplate fields (has_children, has_non_whitespace_content) so call sites only spell out what varies per container type. Keeping the object literal in one place also gives V8 a single monomorphic creation site for StackEntry.

state

id

type number

node_type

start

type number

optimistic

type boolean
default false

delimiter

type string
default ''

tag_name?

type string | undefined
optional

returns

void

revert_above
#

revert_all_optimistic
#

StackEntry
#

mdz_stream_parser_state.ts view source

StackEntry import type {StackEntry} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

id

type MdzNodeId

node_type

type MdzContainerNodeType

optimistic

Whether this was opened speculatively (will be reverted if not closed).

type boolean

delimiter

The opening delimiter text, used as replacement_text on revert.

type string

tag_name

Tag name for Element/Component entries, undefined for all others.

type string | undefined

has_children

Whether any child content has been emitted inside this container.

type boolean

has_non_whitespace_content

Whether any non-whitespace text or non-text child has been emitted inside this container. Only tracked for Paragraph entries to detect whitespace-only paragraphs that should be dropped at close.

type boolean

start

Global byte offset of the opening delimiter.

type number

trim_trailing_newline
#

mdz_stream_parser_state.ts view source

(state: MdzStreamParserState): void import {trim_trailing_newline} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Trim a trailing newline from paragraph content. Checks unflushed accumulated text first; otherwise emits a trim_text opcode targeting the most recent text/append_text via the tracking fields on state (which survive take_opcodes() drains). The opcode stream stays append-only — no retroactive opcode mutation.

state

returns

void

TryResult
#

mdz_stream_parser_state.ts view source

TryResult import type {TryResult} from '@fuzdev/fuz_ui/mdz_stream_parser_state.js';

Tri-state result for try_* parser handlers. - 'consumed': input matched and the parser advanced - 'need_more': input is potentially valid but more bytes are required to decide - 'not_match': input definitely doesn't match — caller falls through to the next handler

Depends on
#

Imported by
#