npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-dash

v0.1.1

Published

A lightweight TypeScript toolkit for AI output parsing — extract code blocks from Markdown and parse streaming XML from LLM responses.

Readme

ai-dash

English

轻量级 TypeScript 工具库,用于解析 AI 输出 —— 从 Markdown 中提取代码块,以及流式解析 LLM 响应中的 XML 标签。

特性

  • Markdown 代码块提取 — 提取、过滤和操作 fenced code blocks
  • 流式 XML 解析器 — 增量解析 LLM 输出中嵌入的 XML 标签,支持回调实时处理
  • 双格式输出 — 同时提供 ESM 和 CJS 构建产物
  • 零依赖 — 无运行时依赖
  • TypeScript 优先 — 内置完整类型定义

安装

pnpm install ai-dash

npm install ai-dash

使用

代码块工具

import { extractCodeBlocks, extractCodeBlocksByLangs, fastExtractCodeInFirstBlock, getCodeBlockLangs, removeCodeBlocks, extractJSON } from 'ai-dash';

const markdown = `
# My Document

\`\`\`javascript
console.log('Hello, World!');
\`\`\`

\`\`\`python
print("Hello from Python!")
\`\`\`
`;

// 提取所有代码块
const blocks = extractCodeBlocks(markdown);
// [{ lang: 'javascript', code: "console.log('Hello, World!');", startLine: 4, endLine: 6 }, ...]

// 按语言过滤(不区分大小写)
const jsBlocks = extractCodeBlocksByLangs(markdown, ['javascript']);

// 获取第一个匹配块的代码(无匹配时返回 undefined)
const firstCode = fastExtractCodeInFirstBlock(markdown, ['javascript', 'python']);

// 获取唯一语言列表
const langs = getCodeBlockLangs(markdown);
// ['javascript', 'python']

// 移除所有代码块,保留周围文本
const textOnly = removeCodeBlocks(markdown);

// 提取并解析第一个 JSON 代码块
const data = extractJSON(markdownWithJSON);

流式 XML 解析器

解析 LLM 输出中嵌入的 XML 标签(如 <plan><file><function_call>)。解析器支持处理不完整的分块、自闭合标签、嵌套元素,以及属性值中包含 > 的情况。

import { createParserState, parseStreamXML, parseXML, getInnerText, fastExtractCodeInFirstXMLTag } from 'ai-dash';

// 一次性解析
const root = parseXML(content, new Set(['plan', 'file', 'progress']));
for (const child of root.children) {
    if (child.type === 1 /* ELEMENT */) {
        console.log(child.tag, child.attrs, child.completed);
    }
}

// 流式解析(带回调)
const state = createParserState();
const opts = {
    limitTagSet: new Set(['plan', 'file']),
    onElementStart: (node) => console.log('open', node.tag),
    onElementEnd: (node) => console.log('close', node.tag),
    onTextProgress: (node, delta) => process.stdout.write(delta),
};

for await (const chunk of stream) {
    parseStreamXML(state, chunk, opts);
}
state.status = 'end';
parseStreamXML(state, '', opts);

// 快速提取:获取第一个匹配 XML 标签的文本
const code = fastExtractCodeInFirstXMLTag(content, new Set(['code', 'file']));

API 参考

代码块函数

| 函数 | 说明 | |---|---| | extractCodeBlocks(md) | 提取所有 fenced 代码块 → CodeBlock[] | | extractCodeBlocksByLangs(md, langs) | 按语言过滤代码块(不区分大小写) | | fastExtractCodeInFirstBlock(md, langs) | 获取第一个匹配块的代码 → string \| undefined | | getCodeBlockLangs(md) | 获取代码块中的唯一语言列表 | | removeCodeBlocks(md) | 移除所有代码块,返回剩余文本 | | extractJSON(md) | 解析第一个 ```json 块为 JSON 对象 |

CodeBlock

interface CodeBlock {
    lang: string;
    langExtra?: string;  // 语言后的附加信息(如路径、标题)
    code: string;
    startLine: number;
    endLine: number;
}

流式 XML 函数

| 函数 | 说明 | |---|---| | createParserState() | 创建流式解析器状态 | | parseStreamXML(state, chunk, opts?) | 向解析器输入一个分块 | | parseXML(content, limitTagSet?) | 一次性解析(便捷封装) | | fastExtractCodeInFirstXMLTag(content, limitTagSet) | 获取第一个匹配标签的文本 → string | | getInnerText(node) | 递归获取节点的所有文本内容 | | getOnlyText(node) | 仅获取直接文本子节点(跳过嵌套元素) |

XMLParserOptions

interface XMLParserOptions {
    limitTagSet?: Set<string>;  // 仅解析指定标签为 XML,其余视为文本
    onElementStart: (node: XMLElement) => void;
    onElementEnd: (node: XMLElement) => void;
    onTextStart: (node: XMLText, delta: string) => void;
    onTextProgress: (node: XMLText, delta: string) => void;
    onTextEnd: (node: XMLText, delta: string) => void;
}

开发

# 安装依赖
pnpm install

# 构建(ESM + CJS)
pnpm build

# 类型检查(不输出文件)
pnpm typecheck

# 运行测试
pnpm test

# 监听模式运行测试
pnpm test:watch

# 测试覆盖率
pnpm test:coverage

# 代码检查
pnpm lint

项目结构

src/
├── index.ts            # 公共导出
├── codeBlock.ts        # Markdown 代码块工具
└── parseStreamXML.ts   # 流式 XML 解析器

tests/
├── testUtils.ts            # 共享测试工具(loadCase, runStreamParser)
├── codeBlock.test.ts       # 代码块测试
├── codeBlock-cases/        # 代码块测试用的 Markdown fixture
├── parseStreamXML.test.ts  # XML 解析器测试(一次性 + 流式)
└── parseStreamXML-cases/   # XML 解析器测试用的 fixture

许可证

MIT © Forrest