Справочник
Архитектура
Четыре пакета, построенные по единому принципу: @macrulez/inview-core делает всю реальную работу вообще без зависимости от фреймворка — createScrollEngine, createVisibilityEngine, createElementTracker. Все три читают из одного общего rafLoop (один callback requestAnimationFrame на весь движок, вместо того чтобы каждая подписка на скролл/трекер запускала свой собственный), а наблюдение за видимостью идёт через общий пулящийся ObserverPool (нативные инстансы IntersectionObserver, пулящиеся по (root, rootMargin, threshold)). @macrulez/inview-vue и @macrulez/inview-react — оба тонкие адаптеры поверх этих же трёх движков: реактивные Ref для Vue, useSyncExternalStore для React — с useParallaxLayer как единственным composable/хуком по обе стороны, который добавляет собственную логику поверх, а не просто прокидывает состояние движка. @macrulez/inview-nuxt не добавляет ничего своего, кроме авто-импортов и клиентского плагина, который применяет общие значения по умолчанию Vue-пакета из nuxt.config.ts.
Совместимость с SSR
Каждый движок ядра и каждый composable/хук сам по себе SSR-safe: без window (или без IntersectionObserver) каждый из них возвращает статичный нулевой снапшот вместо ошибки, и запускает реальную подписку только тогда, когда реально оказывается на клиенте. Ни одному пакету не требуется <ClientOnly> где бы то ни было — включая модуль Nuxt, чей клиентский плагин только применяет значения по умолчанию, а не обеспечивает базовую SSR-безопасность composables.
Размер бандла и peer-зависимости
У @macrulez/inview-core вообще нет peer-зависимостей — он пригоден для самостоятельного использования в любом окружении, в том числе вообще без фреймворка. @macrulez/inview-vue зависит от @macrulez/inview-core и указывает peer на vue: ^3.3.0. @macrulez/inview-react зависит от @macrulez/inview-core и указывает peer на react: ^18.0.0 || ^19.0.0. @macrulez/inview-nuxt зависит от @macrulez/inview-vue и @nuxt/kit, и указывает peer на nuxt: ^3.9.0 || ^4.0.0. Все четыре поставляются с sideEffects: false.
Разработка
Монорепо на pnpm workspaces (packages/* + playground на Vite + Vue).
pnpm install
pnpm test # тесты для каждого пакета (vitest)
pnpm build # сборка core/vue/react/nuxt (tsup)
pnpm dev # playground на Vite
pnpm typecheck # сборка + tsc/vue-tsc по всем пакетамПакеты связаны через workspace:* — pnpm build сначала собирает core, а потом пакеты, которые от него зависят, автоматически (в топологическом порядке pnpm). Тестовые наборы vue/react резолвят @macrulez/inview-core прямо из его src/ через алиас в Vitest, так что pnpm test не требует предварительной сборки — но тайпчекинг адаптеров резолвит core через собранный dist, так что после правок в core перед pnpm typecheck нужно выполнить pnpm build.
Лицензия
MIT.