Repository navigation
Refactor code structure for improved readability and maintainability #142
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| quality: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: [20, 22] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Production dependency audit | |
| if: matrix.node == 20 | |
| run: pnpm run audit:prod | |
| - name: Lint | |
| if: matrix.node == 20 | |
| run: pnpm run lint | |
| - name: Typecheck | |
| run: pnpm run typecheck | |
| - name: Type smoke | |
| if: matrix.node == 20 | |
| run: pnpm run test:types | |
| - name: Test | |
| run: pnpm test -- --run | |
| env: | |
| CI: true | |
| - name: Plugin compatibility matrix | |
| if: matrix.node == 20 | |
| run: pnpm run test:plugins | |
| env: | |
| CI: true | |
| - name: Slow stream correctness test | |
| if: matrix.node == 20 | |
| run: pnpm run test:stream:slow | |
| env: | |
| CI: true | |
| - name: Parser performance threshold | |
| if: matrix.node == 20 | |
| run: pnpm run test:perf-threshold | |
| env: | |
| CI: true | |
| - name: Build | |
| if: matrix.node == 20 | |
| run: pnpm run build | |
| - name: Package export/type lint | |
| if: matrix.node == 20 | |
| run: pnpm run test:package-lint | |
| - name: Pack package | |
| if: matrix.node == 20 | |
| run: | | |
| mkdir -p /tmp/markdown-it-ts-pack | |
| pnpm pack --pack-destination /tmp/markdown-it-ts-pack | |
| - name: Smoke test packed package | |
| if: matrix.node == 20 | |
| run: | | |
| PKG="$(ls /tmp/markdown-it-ts-pack/markdown-it-ts-*.tgz)" | |
| mkdir -p /tmp/markdown-it-ts-smoke | |
| cd /tmp/markdown-it-ts-smoke | |
| printf '{"type":"module"}\n' > package.json | |
| pnpm add "$PKG" | |
| cat > smoke.mjs <<'EOF' | |
| import MarkdownIt, { | |
| Token as RootToken, | |
| parse as rootParse, | |
| parseInline as rootParseInline, | |
| withRenderer as rootWithRenderer, | |
| } from 'markdown-it-ts' | |
| import { withRenderer } from 'markdown-it-ts/plugins/with-renderer' | |
| import Renderer from 'markdown-it-ts/render/renderer' | |
| import { StreamBuffer as StreamBufferSubpath } from 'markdown-it-ts/stream/buffer' | |
| import { chunkedParse as chunkedParseSubpath } from 'markdown-it-ts/stream/chunked' | |
| import { | |
| DebouncedStreamParser, | |
| ThrottledStreamParser, | |
| } from 'markdown-it-ts/stream/debounced' | |
| import { | |
| recommendFullChunkStrategy, | |
| recommendStreamChunkStrategy, | |
| } from 'markdown-it-ts/support/chunk_recommend' | |
| import { | |
| ParserCore, | |
| Token as CoreToken, | |
| } from 'markdown-it-ts/core' | |
| import { | |
| EditableBuffer as ExperimentalEditableBuffer, | |
| PieceTable as ExperimentalPieceTable, | |
| StreamBuffer as ExperimentalStreamBuffer, | |
| UnboundedBuffer as ExperimentalUnboundedBuffer, | |
| parseAsyncIterable as experimentalParseAsyncIterable, | |
| parseAsyncIterableToSink as experimentalParseAsyncIterableToSink, | |
| parseIterable as experimentalParseIterable, | |
| parseIterableToSink as experimentalParseIterableToSink, | |
| chunkedParse as experimentalChunkedParse, | |
| } from 'markdown-it-ts/experimental' | |
| import { Token } from 'markdown-it-ts/common/token' | |
| import { countLines, escapeHtml } from 'markdown-it-ts/common/utils' | |
| const md = MarkdownIt() | |
| const html = md.render('# ok') | |
| const rootExports = await import('markdown-it-ts') | |
| if (html !== '<h1>ok</h1>\n') | |
| throw new Error(`unexpected render output: ${html}`) | |
| for (const name of [ | |
| 'chunkedParse', | |
| 'StreamBuffer', | |
| 'UnboundedBuffer', | |
| 'EditableBuffer', | |
| 'PieceTable', | |
| 'parseIterable', | |
| 'parseAsyncIterable', | |
| 'parseIterableToSink', | |
| 'parseAsyncIterableToSink', | |
| 'recommendFullChunkStrategy', | |
| 'recommendStreamChunkStrategy', | |
| 'DebouncedStreamParser', | |
| 'ThrottledStreamParser', | |
| 'getParseDiagnostics', | |
| ]) { | |
| if (name in rootExports) | |
| throw new Error(`${name} should be imported from markdown-it-ts/experimental or a subpath`) | |
| } | |
| if (typeof Renderer !== 'function') | |
| throw new Error('Renderer default export is not a function') | |
| if (typeof RootToken !== 'function') | |
| throw new Error('root Token export is not a function') | |
| if (typeof rootParse !== 'function') | |
| throw new Error('root parse export is not a function') | |
| if (typeof rootParseInline !== 'function') | |
| throw new Error('root parseInline export is not a function') | |
| if (typeof rootWithRenderer !== 'function') | |
| throw new Error('root withRenderer export is not a function') | |
| if (typeof withRenderer !== 'function') | |
| throw new Error('withRenderer subpath export is not a function') | |
| if (typeof StreamBufferSubpath !== 'function') | |
| throw new Error('stream/buffer subpath export is not a function') | |
| if (typeof chunkedParseSubpath !== 'function') | |
| throw new Error('stream/chunked subpath export is not a function') | |
| if (typeof DebouncedStreamParser !== 'function') | |
| throw new Error('DebouncedStreamParser subpath export is not a function') | |
| if (typeof ThrottledStreamParser !== 'function') | |
| throw new Error('ThrottledStreamParser subpath export is not a function') | |
| if (typeof recommendFullChunkStrategy !== 'function') | |
| throw new Error('recommendFullChunkStrategy subpath export is not a function') | |
| if (typeof recommendStreamChunkStrategy !== 'function') | |
| throw new Error('recommendStreamChunkStrategy subpath export is not a function') | |
| if (typeof ParserCore !== 'function') | |
| throw new Error('core ParserCore export is not a function') | |
| if (typeof CoreToken !== 'function') | |
| throw new Error('core Token export is not a function') | |
| if (typeof experimentalChunkedParse !== 'function') | |
| throw new Error('experimental chunkedParse export is not a function') | |
| if (typeof ExperimentalStreamBuffer !== 'function') | |
| throw new Error('experimental StreamBuffer export is not a function') | |
| if (typeof ExperimentalEditableBuffer !== 'function') | |
| throw new Error('experimental EditableBuffer export is not a function') | |
| if (typeof ExperimentalPieceTable !== 'function') | |
| throw new Error('experimental PieceTable export is not a function') | |
| if (typeof ExperimentalUnboundedBuffer !== 'function') | |
| throw new Error('experimental UnboundedBuffer export is not a function') | |
| if (typeof experimentalParseIterable !== 'function') | |
| throw new Error('experimental parseIterable export is not a function') | |
| if (typeof experimentalParseAsyncIterable !== 'function') | |
| throw new Error('experimental parseAsyncIterable export is not a function') | |
| if (typeof experimentalParseIterableToSink !== 'function') | |
| throw new Error('experimental parseIterableToSink export is not a function') | |
| if (typeof experimentalParseAsyncIterableToSink !== 'function') | |
| throw new Error('experimental parseAsyncIterableToSink export is not a function') | |
| if (typeof Token !== 'function') | |
| throw new Error('Token export is not a function') | |
| if (escapeHtml('<>&"') !== '<>&"') | |
| throw new Error('common/utils escapeHtml subpath export returned unexpected output') | |
| if (countLines('a\nb\nc') !== 2) | |
| throw new Error('common/utils countLines subpath export returned unexpected output') | |
| EOF | |
| node smoke.mjs | |
| node "$GITHUB_WORKSPACE/scripts/package-type-smoke.mjs" "$PKG" | |
| - name: Bundler smoke packed package | |
| if: matrix.node == 20 | |
| run: | | |
| PKG="$(ls /tmp/markdown-it-ts-pack/markdown-it-ts-*.tgz)" | |
| MDTS_PACKAGE_SPEC="$PKG" node scripts/bundler-smoke.mjs | |
| - name: Upload packed package | |
| if: matrix.node == 20 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: markdown-it-ts-pack | |
| path: /tmp/markdown-it-ts-pack/*.tgz | |
| if-no-files-found: error | |
| runtime-smoke: | |
| needs: quality | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| node: [18, 20, 22] | |
| steps: | |
| - name: Download packed package | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: markdown-it-ts-pack | |
| path: /tmp/markdown-it-ts-pack | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Runtime smoke test | |
| run: | | |
| PKG="$(ls /tmp/markdown-it-ts-pack/markdown-it-ts-*.tgz)" | |
| mkdir -p /tmp/markdown-it-ts-runtime-smoke | |
| cd /tmp/markdown-it-ts-runtime-smoke | |
| npm init -y | |
| npm pkg set type=module | |
| npm install "$PKG" | |
| cat > smoke.mjs <<'EOF' | |
| import MarkdownIt, { | |
| Token as RootToken, | |
| parse as rootParse, | |
| parseInline as rootParseInline, | |
| withRenderer as rootWithRenderer, | |
| } from 'markdown-it-ts' | |
| import { withRenderer } from 'markdown-it-ts/plugins/with-renderer' | |
| import Renderer from 'markdown-it-ts/render/renderer' | |
| import { StreamBuffer as StreamBufferSubpath } from 'markdown-it-ts/stream/buffer' | |
| import { chunkedParse as chunkedParseSubpath } from 'markdown-it-ts/stream/chunked' | |
| import { | |
| DebouncedStreamParser, | |
| ThrottledStreamParser, | |
| } from 'markdown-it-ts/stream/debounced' | |
| import { | |
| recommendFullChunkStrategy, | |
| recommendStreamChunkStrategy, | |
| } from 'markdown-it-ts/support/chunk_recommend' | |
| import { | |
| ParserCore, | |
| Token as CoreToken, | |
| } from 'markdown-it-ts/core' | |
| import { | |
| EditableBuffer as ExperimentalEditableBuffer, | |
| PieceTable as ExperimentalPieceTable, | |
| StreamBuffer as ExperimentalStreamBuffer, | |
| UnboundedBuffer as ExperimentalUnboundedBuffer, | |
| parseIterable as experimentalParseIterable, | |
| chunkedParse as experimentalChunkedParse, | |
| } from 'markdown-it-ts/experimental' | |
| import { Token } from 'markdown-it-ts/common/token' | |
| import { countLines, escapeHtml } from 'markdown-it-ts/common/utils' | |
| const md = MarkdownIt() | |
| const html = md.render('# ok') | |
| const rootExports = await import('markdown-it-ts') | |
| if (html !== '<h1>ok</h1>\n') | |
| throw new Error(`unexpected render output: ${html}`) | |
| for (const name of [ | |
| 'chunkedParse', | |
| 'StreamBuffer', | |
| 'UnboundedBuffer', | |
| 'EditableBuffer', | |
| 'PieceTable', | |
| 'parseIterable', | |
| 'parseAsyncIterable', | |
| 'parseIterableToSink', | |
| 'parseAsyncIterableToSink', | |
| 'recommendFullChunkStrategy', | |
| 'recommendStreamChunkStrategy', | |
| 'DebouncedStreamParser', | |
| 'ThrottledStreamParser', | |
| 'getParseDiagnostics', | |
| ]) { | |
| if (name in rootExports) | |
| throw new Error(`${name} should be imported from markdown-it-ts/experimental or a subpath`) | |
| } | |
| if (typeof Renderer !== 'function') | |
| throw new Error('Renderer default export is not a function') | |
| if (typeof RootToken !== 'function') | |
| throw new Error('root Token export is not a function') | |
| if (typeof rootParse !== 'function') | |
| throw new Error('root parse export is not a function') | |
| if (typeof rootParseInline !== 'function') | |
| throw new Error('root parseInline export is not a function') | |
| if (typeof rootWithRenderer !== 'function') | |
| throw new Error('root withRenderer export is not a function') | |
| if (typeof withRenderer !== 'function') | |
| throw new Error('withRenderer subpath export is not a function') | |
| if (typeof StreamBufferSubpath !== 'function') | |
| throw new Error('stream/buffer subpath export is not a function') | |
| if (typeof chunkedParseSubpath !== 'function') | |
| throw new Error('stream/chunked subpath export is not a function') | |
| if (typeof DebouncedStreamParser !== 'function') | |
| throw new Error('DebouncedStreamParser subpath export is not a function') | |
| if (typeof ThrottledStreamParser !== 'function') | |
| throw new Error('ThrottledStreamParser subpath export is not a function') | |
| if (typeof recommendFullChunkStrategy !== 'function') | |
| throw new Error('recommendFullChunkStrategy subpath export is not a function') | |
| if (typeof recommendStreamChunkStrategy !== 'function') | |
| throw new Error('recommendStreamChunkStrategy subpath export is not a function') | |
| if (typeof ParserCore !== 'function') | |
| throw new Error('core ParserCore export is not a function') | |
| if (typeof CoreToken !== 'function') | |
| throw new Error('core Token export is not a function') | |
| if (typeof experimentalChunkedParse !== 'function') | |
| throw new Error('experimental chunkedParse export is not a function') | |
| if (typeof ExperimentalStreamBuffer !== 'function') | |
| throw new Error('experimental StreamBuffer export is not a function') | |
| if (typeof ExperimentalEditableBuffer !== 'function') | |
| throw new Error('experimental EditableBuffer export is not a function') | |
| if (typeof ExperimentalPieceTable !== 'function') | |
| throw new Error('experimental PieceTable export is not a function') | |
| if (typeof ExperimentalUnboundedBuffer !== 'function') | |
| throw new Error('experimental UnboundedBuffer export is not a function') | |
| if (typeof experimentalParseIterable !== 'function') | |
| throw new Error('experimental parseIterable export is not a function') | |
| if (typeof Token !== 'function') | |
| throw new Error('Token export is not a function') | |
| if (escapeHtml('<') !== '<') | |
| throw new Error('common/utils escapeHtml subpath export returned unexpected output') | |
| if (countLines('a\nb') !== 1) | |
| throw new Error('common/utils countLines subpath export returned unexpected output') | |
| EOF | |
| node smoke.mjs |