UNPKG

permix

Version:

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

79 lines (77 loc) 2.23 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 };