Кейс · Веб-приложение · TypeScript
scratch-notes: «Черновик», офлайн-редактор заметок в Markdown
Демо-концепт офлайн-редактора заметок в Markdown на SolidJS: данные в IndexedDB, сервера и аккаунтов нет. Живой предпросмотр, собственный полнотекстовый поиск (BM25, стемминг RU/EN, исправление раскладки), история правок с построчным diff, шифрование отдельной заметки паролем (PBKDF2 600 000 итераций + AES-256-GCM, WebCrypto), импорт и экспорт .md и .zip со своим ZIP-писателем.
- SolidJS
- TypeScript
- Vite
- IndexedDB
- WebCrypto
- PWA
- fast-check
- vitest
- axe
- Cloudflare Pages
- GitHub Actions
01 · Как выглядит
Скриншоты


02 · О проекте
Что это и зачем
Задача: офлайн-редактор заметок, которому не нужен сервер и в котором отдельную заметку можно зашифровать паролем, честно описав, от чего это защищает, а от чего нет.
Решение: SolidJS + TypeScript, данные в IndexedDB, все записи идут через последовательную очередь. Markdown-парсер и санитайзер взяты из md-safe вместе с корпусом XSS-векторов.
Ограничения
Нет синхронизации и совместной работы; две вкладки с одной заметкой пишут «последний выигрывает».
Поиск по тексту зашифрованных заметок работает только пока они открыты.
Шифрование не защищает от вредоносных расширений, кейлоггеров, слабого пароля и его потери (сброса нет), метаданные открыты.
Демо-концепт, не замена менеджеру паролей.
Что внутри
- Шифрование заметки: PBKDF2-HMAC-SHA-256 600 000 итераций, соль 16 байт, AES-256-GCM, новый IV на каждое сохранение, в AAD идентификатор заметки; шифруются текст и снимки истории
- Свой полнотекстовый индекс в памяти: токенизация RU/EN, простой стемминг, BM25 с весами полей, префикс, «фразы», #теги, исправление неверной раскладки
- История правок: до 50 снимков на заметку, слияние частых правок, построчный diff, откат
- Свой ZIP-писатель (store, CRC-32) и читатель (store и deflate) с лимитами против «бомб»; импорт и экспорт .md, .zip, JSON-бэкап
- 777 тестов, в том числе корпус XSS из md-safe; горячие клавиши по e.code на любой раскладке; axe 0
- Выложено на Cloudflare Pages, service worker с версионированным кэшем, CSP без inline-кода
03 · Как запустить
Запуск одной командой
git clone <репозиторий по запросу> scratch-notes
cd scratch-notes
npm ci
npm run dev04 · Код
Репозиторий приватный
Исходники лежат в приватном репозитории. Напишите в Telegram, открою доступ.
Запросить код