Skip to content

Perf/shiki singleton - #74

Merged
mind-murtaza merged 2 commits into
devfrom
perf/shiki-singleton
May 26, 2026
Merged

mind-murtaza merged 2 commits into
devfrom
perf/shiki-singleton

Conversation

@Ashminita28

@Ashminita28 Ashminita28 commented May 26, 2026 •

Copy link
Copy Markdown
Collaborator

Description

This PR solves the issue(#73 ) , by refactoring shiki highlighter initialization and escaping HTML characters in heading content before rendering.

Type of Change

  • Bug fix
  • New feature
  • Refactor (no functional change)
  • Documentation update
  • Style / UI change
  • Build / CI change

Related Issue

Closes #73

Changes Made

  • Updated shiki setup to reuse the same initialization process by preventing simultaneous async creation during markdown parsing.
  • Added HTML escaping for heading content

Checklist

  • My code follows the project's coding guidelines
  • I have tested my changes locally
  • I have used conventional commit messages
  • I have updated documentation if needed
  • My changes do not introduce new warnings or errors

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for exporting markdown as HTML, PDF, and DOCX formats via File menu
    • Implemented automatic update checking with download and installation notifications
    • Added visual drag-and-drop overlay feedback when dropping files
    • Introduced new reader toolbar with zoom controls and theme toggle
  • Improvements

    • Enhanced security with CSS and HTML sanitization for exports
    • Improved UI/UX with consolidated toolbar and update banner components
  • Tests

    • Added comprehensive test coverage for export functionality and HTML sanitization

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 26, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: acb2b612-69b7-4db8-90e6-d0904fab7a5c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request adds a complete document export system (HTML, PDF, DOCX) to the Electron markdown reader, refactors the renderer UI layer into composable hooks, fixes a Shiki instance-caching bug and heading HTML escaping vulnerability, and updates the documentation website.

Changes

Document Export Feature

Layer / File(s) Summary
Export constants and shared types
packages/shared-constants/src/*, packages/shared-types/src/markdown-type.ts
Defines EXPORT_CONST with HTML title, image regex, and dangerous CSS patterns; adds MARKDOWN_FILE_PATTERN; extends MarkdownReaderAPI with export/dialog/update methods; adds IPC constants and menu labels for export actions.
Export core utilities
apps/main-processor/src/utils/helper/html-template.ts, apps/main-processor/src/utils/helper/path-helper.ts, apps/main-processor/src/export/buildDocument.ts, apps/main-processor/src/export/sanitizeCss.ts, apps/main-processor/src/export/getImage.ts, apps/main-processor/src/export/inlineImage.ts
Implements HTML template assembly, CSS sanitization (removes dangerous patterns like behavior: and javascript:), MIME type detection for images, image path normalization for file:// URLs, and base64 inlining of images into HTML.
HTML/PDF/DOCX export handlers
apps/main-processor/src/export/exportHtml.ts, apps/main-processor/src/export/exportPdf.ts, apps/main-processor/src/export/exportDocx.ts, apps/main-processor/tests/export.test.ts, apps/main-processor/tests/docx.test.ts
exportHTML sanitizes CSS, inlines images, and writes UTF-8 files. exportPDF creates hidden Electron window, loads HTML via data: URL, waits for font readiness, and prints with A4 margins. exportDOCX uses html-to-docx library and normalizes Buffer output. Includes tests for HTML structure, CSS sanitization, MIME types, and DOCX file creation.
Main process export wiring
apps/main-processor/package.json, apps/main-processor/src/index.ts, apps/main-processor/src/ipc.ts, apps/main-processor/src/menu.ts, apps/main-processor/src/updater.ts, apps/main-processor/src/cli.ts, apps/main-processor/src/recent/getUniqueRecentFile.ts, electron.vite.config.ts
Adds npm dependencies (html-to-docx, core-util-is, electron-updater, @types/html-to-docx, playwright). Wires IPC handlers for export/save-dialog, adds auto-updater setup and startup check, inserts three File menu export items (HTML/PDF/DOCX), updates import paths to new constants structure, and marks external dependencies in Rollup config.
Preload API exposure
apps/preload/src/index.ts
Exposes exportHTML, exportPDF, exportDOCX, showSaveDialog, getPathForFile, onUpdateAvailable, and downloadUpdate on the renderer-accessible bridge.
Renderer export UI
apps/renderer/src/hooks/useExport.ts, apps/renderer/src/styles/export.css, apps/renderer/src/hooks/useMenuEvents.ts
Implements useExport hook with dialog + API call logic for each format using bundled export.css. Adds print-friendly stylesheet (spacing, typography, centered content, hidden scrollbars). Wires export menu callbacks to listener registration.

Renderer UI Refactoring and Bug Fixes

Layer / File(s) Summary
Type system reorganization
apps/renderer/src/types/hook-types.ts, apps/renderer/src/types/component-types.ts
Creates new hook-types.ts module with FilePersistenceProps, FileActionProps, UseMenuEventsProps, UseShortcutsProps, UseSearchProps. Removes these from component-types.ts and adds new UI types (ElectronFile, ActiveTab, ReaderToolbarProps). Updates useSearch and useShortcuts imports.
Core layout and navigation hooks
apps/renderer/src/hooks/useLayout.ts, apps/renderer/src/hooks/useTabNavigation.ts, apps/renderer/src/hooks/useFileActions.ts, apps/renderer/src/hooks/useFilePersistence.ts, apps/renderer/src/hooks/useOpenFilePath.ts
useLayout manages sidebar/file-browser/focus-mode UI state with memoized toggles. useTabNavigation dispatches next/prev/close actions with wrap-around. useFileActions opens dialogs and dispatches file-load events. useFilePersistence debounces HTML/scroll updates and restores position on mount. useOpenFilePath listens for OS open-file events.
Drag-drop and UI components
apps/renderer/src/hooks/useDragDrop.ts, apps/renderer/src/renderer/drag-drop.ts, apps/renderer/src/components/DragDrop.tsx, apps/renderer/src/components/ReaderToolbar.tsx, apps/renderer/src/components/UpdateBanner.tsx, apps/renderer/tests/renderer/drag-drop.test.ts
useDragDrop hook tracks dragging, prevents defaults, extracts markdown paths. extractDroppedMdpath resolves file paths via ElectronFile.path or getPathForFile fallback. DragDrop component renders fixed overlay. ReaderToolbar displays zoom/theme controls with conditional Sun/Moon icons. UpdateBanner shows version and download button. Includes markdown path extraction tests.
App.tsx refactoring
apps/renderer/src/App.tsx
Delegates state/actions to hooks instead of inline implementations. Initializes all hooks (export, layout, nav, file, persistence, drag-drop, open-file). Wraps content with drag handlers and conditional overlay. Replaces inline toolbar JSX with ReaderToolbar. Adds UpdateBanner.
Bug fixes
apps/renderer/src/renderer/shiki.ts, apps/renderer/src/utils/helpers/heading-helper.ts, apps/renderer/tests/renderer/markdown.test.ts, apps/renderer/tests/renderer/sanitize.test.ts
Shiki now caches the createHighlighterCore promise to share in-flight initialization across concurrent calls. Heading now strips and escapes HTML before rendering to prevent injection. Tests verify iframe/event-handler preservation and DOMPurify sanitization of dangerous elements/URLs.
Documentation and website
docs/docusaurus.config.ts, docs/src/components/Homepage/hero.tsx
Updates social card image to markdown-social-card.png. Refactors hero layout for responsiveness, adds animated video panel with framer-motion, and adjusts typography.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • mind-murtaza

Poem

🐰 Exports dance through formats three,
HTML, PDF, and DOCX with glee!
Hooks refactored, promise cached bright,
Security fixed for heading height. 🎨

🚥 Pre-merge checks | ✅ 1 | ❌ 4

❌ Failed checks (3 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Perf/shiki singleton' references a legitimate change in the codebase (shiki highlighter caching refactor), but it does not capture the main scope of changes which includes export functionality (HTML, PDF, DOCX), auto-update support, and menu integration alongside the shiki fix. Revise the PR title to reflect the primary changes: 'Add export functionality and auto-updater, fix shiki singleton' or 'Add multi-format export and auto-update support' to accurately represent the substantial scope of work.
Out of Scope Changes check ⚠️ Warning The PR includes substantial out-of-scope changes beyond issue #73: export functionality (HTML/PDF/DOCX), electron auto-updater integration, IPC handlers, menu additions, and new React components/hooks that are unrelated to fixing the Shiki singleton or heading HTML-escaping. Either split this PR into separate focused changes (one for Shiki/heading fix, one for export features, one for auto-updater) or link all related issues to properly document the intended scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive While the PR addresses the Shiki singleton issue (#73) and heading HTML-escaping requirement, it contains extensive additional functionality (export methods, auto-updater, menu updates) not listed in the linked issue objectives. Clarify whether all added features (export, updater, menu) were intended as part of #73 or if additional issues should be linked to properly scope this work.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/shiki-singleton

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Ashminita28
Ashminita28 changed the base branch from main to dev May 26, 2026 06:22
@mind-murtaza
mind-murtaza merged commit f05593e into dev May 26, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 1, 2026
5 of 11 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Jun 24, 2026
5 of 11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: fix shiki multiple instances issue

2 participants