UNPKG

permix

Version:

Permix is a lightweight, framework-agnostic, type-safe permissions management library for JavaScript applications on the client and server sides.

85 lines (83 loc) 2.27 kB
'use client'; import { createCheck } from "../core/index.mjs"; import * as React from "react"; import { jsx } from "react/jsx-runtime"; //#region src/react/hooks.ts const Context = React.createContext(null); function usePermixContext() { const context = React.useContext(Context); if (!context) throw new Error("[Permix]: Looks like you forgot to wrap your app with <PermixProvider>"); return context; } /** * Access Permix check and readiness state inside a React component. * * @link https://permix.letstri.dev/docs/integrations/react */ function usePermix(permix) { const { isReady, rules } = usePermixContext(); return { check: React.useCallback((...args) => createCheck(() => rules ?? permix.getRules())(...args), [rules, permix]), isReady }; } //#endregion //#region src/react/components.tsx /** * Provides Permix context to the React component tree. * * @link https://permix.letstri.dev/docs/integrations/react */ function PermixProvider({ children, permix }) { const [context, setContext] = React.useState(() => ({ permix, isReady: permix.isReady(), rules: permix.getRules() })); React.useEffect(() => { const syncRules = () => { queueMicrotask(() => { setContext((c) => ({ ...c, rules: permix.getRules() })); }); }; const syncReady = () => { queueMicrotask(() => { setContext((c) => ({ ...c, isReady: permix.isReady() })); }); }; const setup = permix.hook("setup", syncRules); const ready = permix.hook("ready", syncReady); return () => { setup(); ready(); }; }, [permix]); return /* @__PURE__ */ jsx(Context.Provider, { value: context, children }); } function PermixHydrate({ children, state }) { const { permix } = usePermixContext(); React.useMemo(() => { permix.hydrate(state); }, [permix, state]); return children; } function createComponents(permix) { function Check({ children, path, data, otherwise = null, reverse = false }) { const { check } = usePermix(permix); const hasPermission = check(...[path, data]); return reverse ? hasPermission ? otherwise : children : hasPermission ? children : otherwise; } Check.displayName = "Check"; return { Check }; } //#endregion export { PermixHydrate, PermixProvider, createComponents, usePermix };