Skip to content

MdFlow Class

The main entry point for the library. Creates a streaming markdown parser and renderer bound to a container element.

Import

ts
import { MdFlow } from '@mdflow/core';

Constructor

ts
new MdFlow(options: MdFlowOptions)

MdFlowOptions

ts
interface MdFlowOptions {
  /** The DOM element that MdFlow will render into. */
  container: HTMLElement;

  /** Minimum interval in milliseconds between renders. Default: 16 (~1 frame). */
  debounceMs?: number;

  /** Container width in CSS pixels, 'auto' to fill parent, or undefined for no override. */
  width?: number | 'auto';

  /** Container height in CSS pixels, 'auto' to grow with content, or undefined for no override. */
  height?: number | 'auto';

  /** Plugins to register. Order matters for priority ties. */
  plugins?: MdFlowPlugin[];
}

Width and Height Behavior

ValueEffect
numberSets the container to that many CSS pixels. Overflow is handled by scrolling.
'auto'Width: fills parent (width: 100%). Height: grows with content (height: auto).
undefinedMdFlow does not modify the container's dimensions. External CSS controls sizing.

These values are applied as inline styles on the container during construction and cleared on destroy(). They are also available to plugins via GlobalSettings.

Methods

push

ts
push(chunk: string): void

Feed the next chunk of markdown text. The chunk is appended to the internal buffer and a render is scheduled. Chunks can be any size -- a single character, a word, a line, or an entire document.

flush

ts
flush(): void

Force an immediate render of all buffered content, bypassing the debounce timer. Call this at the end of a stream to ensure the final content is displayed.

reset

ts
reset(): void

Clear all state and the container contents. Plugins remain registered and the object pool is preserved. Use this to start rendering a new document without creating a new instance.

destroy

ts
destroy(): void

Full cleanup. Releases the object pool, removes event listeners, calls destroy() on all plugins (in reverse priority order), and clears the container. The instance cannot be reused after calling this.

register

ts
register(plugin: MdFlowPlugin): void

Add a plugin after construction. Triggers init() on the new plugin and re-sorts the plugin list by priority. Throws if a plugin with the same name is already registered.

on

ts
on(event: string, handler: (data: unknown) => void): void

Subscribe to a plugin event. Event names are namespaced as "pluginName:eventName".

off

ts
off(event: string, handler: (data: unknown) => void): void

Unsubscribe from a plugin event. The handler reference must be the same one passed to on().

Example

ts
import { MdFlow } from '@mdflow/core';
import { markdownBase, markdownInline, markdownHeading } from '@mdflow/plugins';

const md = new MdFlow({
  container: document.getElementById('output')!,
  plugins: [markdownBase(), markdownInline(), markdownHeading()],
  debounceMs: 32,
  width: 'auto',
});

md.on('events:progress', (data) => {
  console.log('Progress:', data);
});

const response = await fetch('/api/stream');
const reader = response.body!.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  md.push(decoder.decode(value, { stream: true }));
}

md.flush();

// Later, clean up:
md.destroy();