@kruzer/toolkit
v0.0.3
Published
Kruzer non-visual toolkit — utils, runtime infra and domain logic in one package, split by domain via subpath exports.
Downloads
509
Readme
@kruzer/toolkit
Pacote não-visual do ecossistema Kruzer. Reúne tudo o que um app precisa mas que não é componente de design system: utilitários puros, infraestrutura de runtime e lógica de domínio.
É o par natural do @kruzer/ds — consumido do mesmo jeito (pacote @kruzer/*, imports
por subpath), mas do outro lado da linha:
| | Responsabilidade |
|---|---|
| @kruzer/ds | aparência — pixel + estado de UI (Modal, Sidebar, Layout, tokens) |
| @kruzer/toolkit | o resto — funções puras, infra de runtime, lógica de domínio/SDK |
Regra mental que decide onde uma coisa mora: "Isso importa o DS, renderiza pixel ou é estado de UI de um componente visual?" Sim → é
@kruzer/ds. Não (função pura, infra, lógica, tipo de dado) → é toolkit.
Status: Alpha · Runtime alvo: browser (React 18) · Build: tsup (ESM + .d.ts por domínio).
Instalação
pnpm add @kruzer/toolkitAs dependências pesadas (react, @azure/msal-browser, axios, jotai, i18next,
react-router-dom, …) são peerDependencies opcionais: você só precisa instalar as que
o domínio que usar exigir. Quem consome só /utils ou /types não baixa nada disso.
Domínios (um pacote, um subpath por domínio)
Cada domínio é exposto como um subpath export próprio. O consumidor só carrega — e só
acopla, no nível de bundle — o que importa. Não existe barrel raiz: nunca se importa
@kruzer/toolkit inteiro.
| Import | Papel | Conteúdo | Peers |
|---|---|---|---|
| @kruzer/toolkit/types | Dados (puro) | GeneratedDefault, GetResponse<T>, Meta, PostResponse, DefaultParams, RequestParams | — |
| @kruzer/toolkit/utils | Puro | masks, formatters, datas, locale, multi-select | — |
| @kruzer/toolkit/runtime | Infra (sem pixel) | i18n, ModalProvider, PubSubProvider, hooks | react |
| @kruzer/toolkit/auth | Domínio/SDK | useAuth, permissões, api client, MSAL/SSO | react, jotai, axios, msal, … |
| @kruzer/toolkit/auth/session-boot | Side-effect | boot da sessão (import único, antes do store) | — |
import type { GetResponse, GeneratedDefault } from '@kruzer/toolkit/types'
import { maskCPF, formatDate, parseDateSafe } from '@kruzer/toolkit/utils'
import { PubSubProvider, useModal } from '@kruzer/toolkit/runtime'
import { useAuth, usePermissions } from '@kruzer/toolkit/auth'Superfície por domínio
/types— contratos de dado puros (zero runtime).GeneratedDefault(base de entidade:_id,created_at, soft-delete…), o envelope de paginaçãoGetResponse<T>+Meta,PostResponse, e os params (DefaultParams,RequestParams)./utils—maskCPF/maskCNPJ/maskCEP/maskPhoneBR;formatBRL,truncate; datas (formatDate,parseDate,parseDateSafe,formatCustomDate,isOutdated); locale (LocaleKeys,normalizeLocale,toShortLang,Locale,LocaleResponse);MultiSelectItem/MultiSelectOptions./runtime—createI18n(factory, não singleton);ModalProvider/useModal(stack headless — o renderer/pixel é do DS);PubSubProvider/usePubSub(bus de tópicos in-memory); hooksuseLocalStorage,useDebounce./auth—useAuth(+ store Jotai,StorageKeys);usePermissions,AccessControl,PermissionsScope(RBAC headless);createApiService(axios + interceptors);useMicrosoftSSO(MSAL);OAuthCallback,ProtectedRoute.
Boas práticas
Para quem consome:
- Importe sempre pelo subpath, nunca de um caminho profundo (
@kruzer/toolkit/dist/...). - Use
import typepara os tipos (/typese os tipos dos outros domínios) — deixa o bundler apagar tudo em runtime. - Instale só as peers do domínio que usar.
/utilse/typesnão exigem nenhuma. createI18ndevolve uma instância por app/MFE — não compartilhe singletons de estado entre MFEs (o estado sincroniza via storage + evento de janela).- O
ModalProvidersó guarda a pilha; quem desenha o modal é o@kruzer/ds. @kruzer/toolkit/auth/session-boottem side-effect e deve ser importado uma vez, no bootstrap, antes de tocar o store da sessão.
Para quem contribui (mantém o pacote "divisível"):
- Subpath por domínio. Domínio novo =
src/<dominio>/index.ts+ entry notsup.config.ts+ subpath nopackage.json > exports. - Direção de dependência única (travada no ESLint via
import/no-restricted-paths):
Todos podem importartypes → (ninguém) ← folha de dados utils → (ninguém) runtime → utils auth → utils, runtimetypes;typesnão importa ninguém. Nunca o contrário. - Entre domínios, importe pelo subpath público (
@kruzer/toolkit/utils); dentro do domínio, use relativo (./). É isso que torna o split futuro "mover a pasta e pronto". - Sem pixel aqui. Nada que renderize UI estilizada ou importe o
@kruzer/ds— isso é DS. - Deps pesadas entram como
peerDependencyopcional, nuncadependency(quebraria o isolamento do/utils). - Ao portar da
@kruzer/lib-ui: o toolkit é superset do comportamento da lib-ui, validado contra o PIM (consumidor mais maduro). O OMS é referência de forma, mas dropou comportamentos — não copie cru.
Publicação
Pacote público scoped (@kruzer/toolkit), no npm público, igual ao @kruzer/ds.
- Versão → dist-tag:
*-alpha.*/beta/rcpublicam nessa tag; versão limpa vai pralatest. O CI deriva a tag da versão automaticamente. - CI:
.github/workflows/publish.ymldispara em release published (ou manual viaworkflow_dispatch):pnpm install --frozen-lockfile→ type-check + lint → build →pnpm publish --access public(auth via secretNPM_TOKEN_PUBLISH). --access publicé obrigatório: pacote scoped nasce restrito por padrão.- Publicação manual (quando necessário):
pnpm run build:publish.
Scripts
pnpm build # tsup → dist/<domain>/index.js (+ .d.ts)
pnpm dev # tsup --watch
pnpm type-check # tsc --noEmit
pnpm lint # eslint (inclui a checagem de fronteira entre domínios)
pnpm format # prettier
pnpm build:publish # build + pnpm publish --tag alpha --access publicAntes de mergear: type-check, lint e build limpos; código no domínio certo; imports
entre domínios pelo subpath público; nada de pixel; dep pesada como peer opcional.
Documentação
- AGENTS.md — guia canônico para contribuidores/agentes: arquitetura,
guardrails, armadilhas de runtime, contrato de sessão, estado da migração e handoff pro
@kruzer/ds. (O CLAUDE.md é só um ponteiro para ele.) - docs/lib-ui-migration-map.md — rastro de migração dos
consumidores do
@kruzer/lib-ui: quem consome o quê e por onde começar. - docs/ — demais documentos de apoio.
