@elcrm/router
v0.0.60
Published
React state router for elCRM: global Router.data, encrypted session persistence, lazy-loaded pages/features (import.meta.glob), optional URL/history sync.
Readme
@elcrm/router
React state router для elCRM: глобальное состояние (Router.data), опциональный URL поверх него, ленивая загрузка чанков (import.meta.glob / Vite), шифрованный persist в sessionStorage.
Это не полный аналог React Router: URL — опциональный слой. Есть GuardRoute, RouteLoader, RouterOutletStack, LoadRoute.
Содержание
- Установка
- Быстрый старт
[Router.createRouter— опции](#routercreaterouter--опции)- API состояния
- Типизация
- [Загрузка чанков и
paths](#загрузка-чанков-и-paths) - URL-router
- Опционально: guard, loader, outlet
- Сессия и шифрование
- Сборка UMD
- Тестовый стенд
- Подробнее про импорт чанков
- Лицензия
Установка
npm install @elcrm/router @elcrm/crypto react| Peer | Версия |
| --------------- | ---------- |
| react | >=18.2.0 |
| @types/react | >=18.2.0 |
| @elcrm/crypto | ^0.0.1 |
react-dom подключает приложение (тот же major, что у react).
Быстрый старт
Минимум для Vite: один glob в createRouter. LoadRoute сам берёт чанки из него.
import { Router, LoadRoute } from "@elcrm/router";
Router.createRouter({
defaults: { page: "Main", module: "Home" },
auth: "Auth",
glob: import.meta.glob("./{pages,modules}/**/*.{tsx,ts}", { eager: false }),
});
export function App() {
return <LoadRoute variant="page" />;
}variant="page" → src/pages/{segment}.tsx.variant="module" → src/modules/{segment}/index.tsx.
Тот же glob: Modal.Open("Home", "Demo") → modules/Home/modal/Demo.tsx. Не вызывайте отдельно importModules / второй glob.
paths и resolveLazyPage нужны только если папки другие.children у LoadRoute — вложенный роут (страница → модуль), не заглушка.
Дальше: Router.useRouter, setRouter, mergeRouter, LoadRoute, RouterOutletStack — см. таблицы ниже.
Идея: после createRouter вызываются восстановление сессии (Load) и при необходимости разбор URL (urlTemplate). useRouter / emitRouter реагируют на обновления data.
Router.createRouter — опции
Все поля опциональны; при повторном вызове подмешиваются значения из текущего конфига.
| Опция | Назначение |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| defaults | Начальный Router.data и initialData |
| auth, authKey, authFlagStorageKey, authFlagStorage | Ветка «вход без сессии» и флаг в storage |
| debug | Логи |
| dir | База для путей чанков (по умолчанию ".") |
| importLoader / устар. importModules | (path) => import(...) |
| glob, pages, features / устар. modules | Glob или база для страниц/фич |
| persist, persistSession | Запись в sessionStorage или своё хранилище |
| urlTemplate, urlBase, urlNavigateMode, onUrlMismatch | Синхронизация с адресной строкой |
| paths | Шаблоны путей к chunk по variant, напр. ./pages или ./settings/{segment}/index |
| loadSegmentLayouts | Устар.; для миграций / label |
Сегменты из URL попадают в Router.data как в строке (регистр библиотека не нормализует).
API состояния
Объект Router и одноимённые функции: setRouter, getRouter, mergeRouter, matchesRouter, hasRouter, prevRouter, getRouterData, pickRouter, useRouter, emitRouter, resetRouter, flushPersistToSession, createImportLoader, getImportLoader, requireImportLoader, importFromRouter.
Типизация
Один раз опишите **RouterDataMap**: ключ = имя сегмента (то же, что variant / stateKey в LoadRoute), тип значения = допустимые значения (страницы, секции, произвольное число для id и т.д.).
declare module "@elcrm/router" {
interface RouterDataMap {
page: "login" | "recover" | "passkey" | "main";
modules:
| "home"
| "promotions"
| "calendar"
| "telegram"
| "inn"
| "requests"
| "companies"
| "questions"
| "analytics"
| "users"
| "settings";
settingsSection: "profile" | "notifications" | "ui" | "security";
id: number;
}
}LoadRoute и paths в createRouter получают проверку variant по ключам этой схемы. Отдельный RouterLoadSegmentKinds не нужен (он только резерв, если RouterDataMap не задаёте — тогда доступны встроенные page | feature).
Кастомные папки для чанков:
Router.createRouter({
defaults: { page: "main", modules: "home", settingsSection: "profile" },
paths: {
page: "./pages",
modules: "./modules/{segment}/index",
settingsSection: "./settings/{segment}/index",
},
glob,
});createRouterApi<T>() — типизированный API без глобального augmentation. defineRouterConfig = createRouter.
Загрузка чанков и paths
LoadRoute:variantзадаёт шаблон пути. По умолчаниюpage→pages/{segment},module→modules/{segment}/index,feature→features/{segment}/index.- С
createRouter({ glob })resolveLazyPageне нужен. createPageLazyResolverFromImportMeta— если хотите ручнойimport()в файле приложения.
Рекомендуется import.meta.glob и поле glob в createRouter. Для корректных относительных импортов из приложения — createImportLoaderFromImportMeta(import.meta.url).
URL-router
Непустой urlTemplate в createRouter включает синхронизацию с history. Утилиты: matchUrlTemplate, buildUrlFromTemplate, syncDataToUrl, applyPathnameToRouterData.
Опционально: guard, loader, outlet
- GuardRoute — условия, редирект,
watchKey(см.GuardRouteProps). - RouteLoader — асинхронные данные в
Router.data. - RouterOutletStack — цепочка
LoadRouteпо массиву{ stateKey, variant }.
Лицензия
MIT — файл LICENSE.
Полный список типов и экспортов — в автодополнении IDE и в **dist/*.d.ts** после сборки.
