2mqjs
v0.1.1
Published
A tiny performance-first architecture toolkit for framework-free web apps: lazy components, event ports, workers, tasks, and an off-main-thread store.
Maintainers
Readme
2mqjs
Что это?
2mqjs помогает разбить vanilla TypeScript/JavaScript сайт на небольшие runtime-слои:
- UI-компоненты загружаются только тогда, когда они реально нужны.
- Бизнес-логика может уехать в Web Workers.
- События идут через явные ports, а не через скрытые связи между модулями.
- Tasks управляют порядком запуска, видимостью, idle-временем, готовностью данных и воркеров.
- Store может жить вне main thread и сохраняться между перезагрузками.
Библиотека нужна для страниц, где важны маленький initial JS, меньше работы в main thread и предсказуемый порядок инициализации.
Установка
npm i 2mqjs
# или
pnpm add 2mqjs
# или
yarn add 2mqjsПроект должен использовать ESM:
{
"type": "module"
}Импортируйте только нужное
2mqjs публикует subpath exports, чтобы bundler мог не тянуть лишнее:
import { registerComponent } from '2mqjs/components';
import { emitPort, onPort } from '2mqjs/ports';
import { registerTask } from '2mqjs/tasks';Корневой экспорт тоже доступен, если удобнее:
import { registerComponent, emitPort, registerTask } from '2mqjs';Быстрый старт
1. Ленивые UI-компоненты
import { registerComponent, runComponentLoader } from '2mqjs/components';
registerComponent({
name: 'product-card',
load: () => import('./components/product-card.js'),
when: 'visible',
hasDisplay: true,
});
runComponentLoader();<article data-component="product-card"></article>Модуль компонента:
export function display(el: Element) {
el.innerHTML = '<button data-add>Добавить в корзину</button>';
}
export function boot(el: Element) {
el.querySelector('[data-add]')?.addEventListener('click', () => {
// Тяжёлая логика стартует только после появления компонента.
});
}2. Ports: явные события приложения
import { emitPort, onPort } from '2mqjs/ports';
const off = onPort<{ id: string }>('cart:add', ({ id }) => {
console.log('Добавить товар', id);
});
emitPort('cart:add', { id: 'sku-42' });
off();3. Tasks: предсказуемый порядок запуска
import { registerTask, runTasks } from '2mqjs/tasks';
registerTask({
id: 'hydrate-products',
stage: 'bootstrap',
when: 'idle',
run: async () => {
// Некритичная работа ждёт idle-времени.
},
});
await runTasks('bootstrap');4. Workers: тяжёлая логика вне main thread
import { registerWorker, emitPort } from '2mqjs/workers';
await registerWorker({
name: 'productData',
src: () => import('./workers/productData.worker.js'),
});
emitPort('productData:init', { page: 'catalog' });5. Store: состояние в dedicated worker
import { defineGlobalStore } from '2mqjs/store';
const app = defineGlobalStore({
name: 'shop',
initial: { cart: [] as string[] },
persist: ['cart'],
});
await app.ready;
app.watch('cart', cart => {
console.log('Корзина изменилась', cart);
});
app.add('cart', 'sku-42');Модули
| Модуль | Для чего | Импорт |
| --- | --- | --- |
| Components | Ленивые UI-модули, display/boot, запуск по видимости и взаимодействию | 2mqjs/components |
| Ports | Лёгкий pub/sub со snapshot/replay | 2mqjs/ports |
| Workers | Регистрация воркеров и port-based messaging | 2mqjs/workers |
| Tasks | Оркестрация запуска, зависимости и runtime-условия | 2mqjs/tasks |
| Store | Глобальное состояние вне main thread + persist | 2mqjs/store |
| Events | DOM-утилиты: делегирование событий и resize subscriptions | 2mqjs/events |
Принципы runtime
- Откладывать по умолчанию. Запускать дорогой UI и логику только когда они нужны.
- Держать слои явными. UI, данные, воркеры и orchestration общаются через маленькие контракты.
- Не привязывать к фреймворку. Можно использовать рядом с SSR, islands, виджетами или обычным HTML.
- Следить за размером. Subpath exports и release smoke checks защищают package shape и bundle budgets.
Текущий roadmap
Следующий цикл разработки сфокусирован на production-grade производительности:
- lazy components без потери первого interaction;
- shared observers и cache в component loader;
- cleanup жизненного цикла listeners в ports/tasks/events/workers;
- patch-based store updates вместо отправки всего state;
SharedWorkermode для синхронизации стора между вкладками;- улучшение scheduler: DAG validation, cancellation, timeouts, concurrency limits;
- browser smoke tests, benchmarks и bundle-size budgets.
Подробный backlog — в open issues.
Релизы
2mqjs теперь использует GitHub automation:
- CI гоняет release gate на поддерживаемых версиях Node.js.
- CodeQL сканирует JavaScript/TypeScript код.
- Dependabot группирует обновления npm и GitHub Actions.
- Release Please создаёт release PR из Conventional Commits.
- npm-публикация идёт через GitHub Actions с provenance.
Локальная проверка перед релизом:
npm run release:check