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
JavaScript
'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 };