@shield-acl/react
Version:
Sistema ACL (Access Control List) inteligente e granular para aplicações React
1 lines • 34.2 kB
Source Map (JSON)
{"version":3,"sources":["../src/context.tsx","../src/hooks/internal.ts","../src/hooks/useAcl.ts","../src/hooks/useCan.ts","../src/hooks/useEvaluate.ts","../src/hooks/useCanAsync.ts","../src/hooks/useChecks.ts","../src/hooks/useResource.ts","../src/hooks/useRoles.ts","../src/hooks/usePermissions.ts","../src/hooks/useSync.ts","../src/components.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useState,\n useEffect,\n useCallback,\n useMemo,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport type {\n ACL,\n Action,\n Environment,\n EvalOptions,\n EvaluationResult,\n Resource,\n Scope,\n User,\n} from \"@shield-acl/core\";\nimport { mergeEnv } from \"./hooks/internal\";\n\n/**\n * Opções de uma checagem no React.\n *\n * - `scope`: override do scope do Provider (checar OUTRO app).\n * - `record`: INSTÂNCIA do recurso (owner, status...) → vira `ctx.resource`.\n * - `environment`: sobrepõe (merge raso) o environment do Provider.\n */\nexport interface CheckOptions<TRecord = unknown> {\n scope?: Scope;\n record?: TRecord;\n environment?: Environment;\n}\n\nexport interface ACLContextValue {\n engine: ACL;\n scope: Scope;\n environment: Environment | undefined;\n user: User | null;\n setUser: (user: User | null) => void;\n /** Revisão reativa do engine (bumpa quando roles mudam). */\n revision: number;\n can: (action: Action, resource?: Resource, opts?: CheckOptions) => boolean;\n evaluate: (\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n ) => EvaluationResult;\n canAsync: (\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n ) => Promise<EvaluationResult>;\n}\n\nconst ACLContext = createContext<ACLContextValue | undefined>(undefined);\n\nexport interface ACLProviderProps {\n engine: ACL;\n /** Usuário: use como inicial (não-controlado) ou atualize a prop (controlado). */\n user?: User | null;\n /** Scope default da subárvore. Default \"*\". */\n scope?: Scope;\n /** Environment default (reativo: MFA/hora/IP). */\n environment?: Environment;\n children: ReactNode;\n}\n\n/**\n * Provider do ACL — scope + environment reativos e engine observável.\n */\nexport function ACLProvider({\n engine,\n user: userProp,\n scope = \"*\",\n environment,\n children,\n}: ACLProviderProps) {\n // Estado interno semeado pela prop; ressincroniza se a prop mudar (controlado).\n const [user, setUser] = useState<User | null>(userProp ?? null);\n useEffect(() => {\n if (userProp !== undefined) setUser(userProp);\n }, [userProp]);\n\n // Reatividade a mudanças de roles: assina a revisão do engine.\n const revision = useSyncExternalStore(\n engine.subscribe,\n () => engine.revision,\n () => engine.revision,\n );\n\n const can = useCallback(\n (action: Action, resource?: Resource, opts?: CheckOptions): boolean => {\n if (!user) return false;\n return engine.can(\n user,\n opts?.scope ?? scope,\n action,\n resource,\n toEval(opts, environment),\n );\n },\n // revision garante reavaliação quando o catálogo de roles muda\n [engine, user, scope, environment, revision],\n );\n\n const evaluate = useCallback(\n (\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n ): EvaluationResult => {\n const activeScope = opts?.scope ?? scope;\n if (!user) {\n return {\n allowed: false,\n reason: \"No user authenticated\",\n scope: activeScope,\n };\n }\n return engine.evaluate(\n user,\n activeScope,\n action,\n resource,\n toEval(opts, environment),\n );\n },\n [engine, user, scope, environment, revision],\n );\n\n const canAsync = useCallback(\n (\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n ): Promise<EvaluationResult> => {\n const activeScope = opts?.scope ?? scope;\n if (!user) {\n return Promise.resolve({\n allowed: false,\n reason: \"No user authenticated\",\n scope: activeScope,\n });\n }\n return engine.evaluateAsync(\n user,\n activeScope,\n action,\n resource,\n toEval(opts, environment),\n );\n },\n [engine, user, scope, environment, revision],\n );\n\n const value = useMemo<ACLContextValue>(\n () => ({\n engine,\n scope,\n environment,\n user,\n setUser,\n revision,\n can,\n evaluate,\n canAsync,\n }),\n [engine, scope, environment, user, revision, can, evaluate, canAsync],\n );\n\n return <ACLContext.Provider value={value}>{children}</ACLContext.Provider>;\n}\n\nfunction toEval(\n opts: CheckOptions | undefined,\n providerEnv: Environment | undefined,\n): EvalOptions {\n return {\n resource: opts?.record,\n environment: mergeEnv(providerEnv, opts?.environment),\n };\n}\n\nexport function useACLContext(): ACLContextValue {\n const context = useContext(ACLContext);\n if (!context) {\n throw new Error(\"useACLContext must be used within an ACLProvider\");\n }\n return context;\n}\n","import type { Action, Environment, Resource } from \"@shield-acl/core\";\nimport type { CheckOptions } from \"../context\";\n\n/** Especificação de uma checagem: [action, resource?, options?]. */\nexport type CheckSpec = [Action, Resource?, CheckOptions?];\n\n/** Chave estável para memoização (funções são ignoradas). */\nexport function stableKey(value: unknown): string {\n try {\n return JSON.stringify(value) ?? \"undefined\";\n } catch {\n return \"unserializable\";\n }\n}\n\n/** Merge raso de environments (opts sobrepõe o do Provider). */\nexport function mergeEnv(\n base: Environment | undefined,\n override: Environment | undefined,\n): Environment | undefined {\n if (!base && !override) return undefined;\n return { ...base, ...override };\n}\n","import { useCallback } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport type { Action, Resource } from \"@shield-acl/core\";\n\n/**\n * Primitivo do ACL: expõe tudo do contexto (já escopado) + atalhos.\n *\n * @example\n * const { can, scope, setUser } = useAcl()\n * can(\"update\", \"posts\", { record: post })\n * can(\"read\", \"posts\", { scope: \"app:outro\" }) // override de scope\n */\nexport function useAcl() {\n const ctx = useACLContext();\n\n const cannot = useCallback(\n (action: Action, resource?: Resource, opts?: CheckOptions) =>\n !ctx.can(action, resource, opts),\n [ctx],\n );\n\n const clearCache = useCallback(() => ctx.engine.clearCache(), [ctx.engine]);\n\n return { ...ctx, cannot, clearCache };\n}\n","import { useMemo } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport type { Action, Resource } from \"@shield-acl/core\";\nimport { stableKey } from \"./internal\";\n\n/**\n * Verificação simples, memoizada. Reavalia quando user/roles/scope/opts mudam.\n *\n * @example\n * const canEdit = useCan(\"update\", \"posts\", { record: post })\n * const canInB = useCan(\"read\", \"posts\", { scope: \"app:B\" })\n */\nexport function useCan(\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n): boolean {\n const { can, user, revision } = useACLContext();\n const key = stableKey(opts);\n return useMemo(\n () => can(action, resource, opts),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [can, action, resource, key, user, revision],\n );\n}\n\nexport function useCannot(\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n): boolean {\n return !useCan(action, resource, opts);\n}\n","import { useMemo } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport type { Action, EvaluationResult, Resource } from \"@shield-acl/core\";\nimport { stableKey } from \"./internal\";\n\n/**\n * Avaliação detalhada (allowed, reason, matchedRule, scope) — para tooltips,\n * telas de admin e \"por que negado\".\n */\nexport function useEvaluate(\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n): EvaluationResult {\n const { evaluate, user, revision } = useACLContext();\n const key = stableKey(opts);\n return useMemo(\n () => evaluate(action, resource, opts),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [evaluate, action, resource, key, user, revision],\n );\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport type { Action, Resource } from \"@shield-acl/core\";\nimport { stableKey } from \"./internal\";\n\nexport interface AsyncCheck {\n /** undefined enquanto carrega ou em erro. */\n allowed: boolean | undefined;\n loading: boolean;\n error: unknown;\n refetch: () => void;\n}\n\n/**\n * Verificação assíncrona — destrava conditions async, `policySource` e ReBAC\n * na UI (ex.: consulta a banco).\n *\n * @example\n * const { allowed, loading } = useCanAsync(\"edit\", \"docs\", { record: doc })\n * if (loading) return <Spinner />\n * return allowed ? <Editor /> : <Denied />\n */\nexport function useCanAsync(\n action: Action,\n resource?: Resource,\n opts?: CheckOptions,\n): AsyncCheck {\n const { canAsync, user, revision } = useACLContext();\n const [state, setState] = useState<{\n allowed: boolean | undefined;\n loading: boolean;\n error: unknown;\n }>({ allowed: undefined, loading: true, error: null });\n const [nonce, setNonce] = useState(0);\n const refetch = useCallback(() => setNonce((n) => n + 1), []);\n const key = stableKey(opts);\n\n useEffect(() => {\n let alive = true;\n setState((s) => (s.loading ? s : { ...s, loading: true }));\n canAsync(action, resource, opts)\n .then((r) => {\n if (alive)\n setState({ allowed: r.allowed, loading: false, error: null });\n })\n .catch((e) => {\n if (alive) setState({ allowed: undefined, loading: false, error: e });\n });\n return () => {\n alive = false;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [canAsync, action, resource, key, user, revision, nonce]);\n\n return { ...state, refetch };\n}\n","import { useMemo } from \"react\";\nimport { useACLContext } from \"../context\";\nimport { stableKey, type CheckSpec } from \"./internal\";\n\n/**\n * Batch tipado de verificações. Substitui Multiple/Map/Array/Any/All.\n *\n * @example\n * const c = useChecks({\n * edit: [\"update\", \"posts\", { record: post }],\n * del: [\"delete\", \"posts\", { record: post }],\n * })\n * // c: { edit: boolean; del: boolean }\n * anyOf(c) // alguma\n * allOf(c) // todas\n */\nexport function useChecks<K extends string>(\n map: Record<K, CheckSpec>,\n): Record<K, boolean> {\n const { can, user, revision } = useACLContext();\n const key = stableKey(map);\n return useMemo(() => {\n const out = {} as Record<K, boolean>;\n (Object.keys(map) as K[]).forEach((k) => {\n const [action, resource, opts] = map[k];\n out[k] = can(action, resource, opts);\n });\n return out;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [can, key, user, revision]);\n}\n\n/** true se QUALQUER checagem passou. */\nexport const anyOf = (result: Record<string, boolean>): boolean =>\n Object.values(result).some(Boolean);\n\n/** true se TODAS passaram (vazio = true). */\nexport const allOf = (result: Record<string, boolean>): boolean =>\n Object.values(result).every(Boolean);\n","import { useMemo } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport type {\n Action,\n Environment,\n EvaluationResult,\n Resource,\n Scope,\n} from \"@shield-acl/core\";\nimport { stableKey } from \"./internal\";\n\nexport interface ResourceBinding<TRecord> {\n resource: Resource;\n record: TRecord;\n can: (action: Action, extra?: Omit<CheckOptions, \"record\">) => boolean;\n evaluate: (action: Action) => EvaluationResult;\n canRead: () => boolean;\n canCreate: () => boolean;\n canUpdate: () => boolean;\n canDelete: () => boolean;\n canManage: () => boolean;\n}\n\n/**\n * Vincula tipo + instância do recurso: a instância entra automaticamente nas\n * conditions (via `record`). Substitui usePermissionHelpers/useResourceACL.\n *\n * @example\n * const acl = useResource(\"posts\", post)\n * acl.canUpdate() acl.can(\"publish\")\n * acl.can(\"read\", { scope: \"app:B\" })\n */\nexport function useResource<TRecord>(\n type: Resource,\n record: TRecord,\n opts?: { scope?: Scope; environment?: Environment },\n): ResourceBinding<TRecord> {\n const { can, evaluate, user, revision } = useACLContext();\n const scope = opts?.scope;\n const environment = opts?.environment;\n\n return useMemo(() => {\n const base: CheckOptions<TRecord> = { record, scope, environment };\n const check = (action: Action, extra?: Omit<CheckOptions, \"record\">) =>\n can(action, type, { ...base, ...extra });\n\n return {\n resource: type,\n record,\n can: check,\n evaluate: (action: Action) => evaluate(action, type, base),\n canRead: () => check(\"read\") || check(`${type}.read`),\n canCreate: () => check(\"create\") || check(`${type}.create`),\n canUpdate: () => check(\"update\") || check(`${type}.update`),\n canDelete: () => check(\"delete\") || check(`${type}.delete`),\n canManage: () => check(\"manage\") || check(\"*\"),\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n can,\n evaluate,\n type,\n stableKey(record),\n scope,\n stableKey(environment),\n user,\n revision,\n ]);\n}\n","import { useMemo, useCallback } from \"react\";\nimport { useACLContext } from \"../context\";\nimport type { Role, RoleName, Scope } from \"@shield-acl/core\";\n\n/** Roles concedidas ao usuário no scope (com override opcional). */\nexport function useGrantedRoles(opts?: { scope?: Scope }): RoleName[] {\n const { engine, user, scope, revision } = useACLContext();\n const active = opts?.scope ?? scope;\n return useMemo(\n () => (user ? engine.getGrantedRoles(user, active) : []),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [engine, user, active, revision],\n );\n}\n\nexport interface RoleHierarchy {\n allRoles: RoleName[];\n directRoles: RoleName[];\n inheritedRoles: RoleName[];\n hasRole: (name: RoleName) => boolean;\n hasAnyRole: (names: RoleName[]) => boolean;\n hasAllRoles: (names: RoleName[]) => boolean;\n getRole: (name: RoleName) => Role | undefined;\n}\n\n/** Hierarquia de roles do usuário no scope (diretas + herdadas). */\nexport function useRoleHierarchy(opts?: { scope?: Scope }): RoleHierarchy {\n const { engine, user, scope, revision } = useACLContext();\n const active = opts?.scope ?? scope;\n\n const { allRoles, directRoles, inheritedRoles } = useMemo(() => {\n const direct = user ? engine.getGrantedRoles(user, active) : [];\n const all = new Set<RoleName>(direct);\n const walk = (name: RoleName, seen = new Set<RoleName>()) => {\n if (seen.has(name)) return;\n seen.add(name);\n engine.getRole(name)?.inherits?.forEach((inherited) => {\n all.add(inherited);\n walk(inherited, seen);\n });\n };\n direct.forEach((d) => walk(d));\n const allArr = [...all];\n return {\n allRoles: allArr,\n directRoles: direct,\n inheritedRoles: allArr.filter((r) => !direct.includes(r)),\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine, user, active, revision]);\n\n const hasRole = useCallback(\n (n: RoleName) => allRoles.includes(n),\n [allRoles],\n );\n const hasAnyRole = useCallback(\n (ns: RoleName[]) => ns.some((n) => allRoles.includes(n)),\n [allRoles],\n );\n const hasAllRoles = useCallback(\n (ns: RoleName[]) => ns.every((n) => allRoles.includes(n)),\n [allRoles],\n );\n const getRole = useCallback(\n (n: RoleName) => engine.getRole(n),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [engine, revision],\n );\n\n return {\n allRoles,\n directRoles,\n inheritedRoles,\n hasRole,\n hasAnyRole,\n hasAllRoles,\n getRole,\n };\n}\n","import { useMemo } from \"react\";\nimport { useACLContext } from \"../context\";\nimport type { Permission, RoleName, Scope } from \"@shield-acl/core\";\n\nexport interface UserPermissions {\n /** Efetivas no scope (roles resolvidas + diretas). */\n all: Permission[];\n /** Diretas nos grants deste scope (correspondência exata). */\n direct: Permission[];\n byRole: Record<RoleName, Permission[]>;\n denials: Permission[];\n allowances: Permission[];\n actions: string[];\n resources: string[];\n count: number;\n}\n\nconst EMPTY: UserPermissions = {\n all: [],\n direct: [],\n byRole: {},\n denials: [],\n allowances: [],\n actions: [],\n resources: [],\n count: 0,\n};\n\n/** Permissões efetivas do usuário no scope — para telas de admin/debug. */\nexport function usePermissions(opts?: { scope?: Scope }): UserPermissions {\n const { engine, user, scope, revision } = useACLContext();\n const active = opts?.scope ?? scope;\n\n return useMemo(() => {\n if (!user) return EMPTY;\n\n const all = engine.getUserPermissions(user, active);\n const direct = user.grants\n .filter((g) => g.scope === active)\n .flatMap((g) => g.permissions ?? []);\n\n const byRole: Record<RoleName, Permission[]> = {};\n engine.getGrantedRoles(user, active).forEach((roleName) => {\n const role = engine.getRole(roleName);\n if (role) byRole[roleName] = role.permissions;\n });\n\n const actions = new Set<string>();\n const resources = new Set<string>();\n for (const p of all) {\n (Array.isArray(p.action) ? p.action : [p.action]).forEach((a) =>\n actions.add(a),\n );\n if (p.resource !== undefined) {\n (Array.isArray(p.resource) ? p.resource : [p.resource]).forEach((r) =>\n resources.add(r),\n );\n }\n }\n\n return {\n all,\n direct,\n byRole,\n denials: all.filter((p) => p.deny === true),\n allowances: all.filter((p) => p.deny !== true),\n actions: [...actions].sort(),\n resources: [...resources].sort(),\n count: all.length,\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine, user, active, revision]);\n}\n","import { useEffect, useRef, useCallback } from \"react\";\nimport { useACLContext, type CheckOptions } from \"../context\";\nimport { useCan } from \"./useCan\";\nimport type { Action, Resource, Role, User } from \"@shield-acl/core\";\n\ntype Cleanup = (() => void) | void;\n\n/**\n * Sincroniza os grants do USUÁRIO ATUAL em tempo real.\n * Suporta push (a notificação traz o user) e pull (sinal → refetch → aplica).\n * A função `subscribe` roda uma vez (montagem) e retorna o unsubscribe.\n *\n * @example\n * // push\n * useUserSync((apply) => socket.on(\"acl:user\", (m) => apply(m.user)))\n * // pull\n * useUserSync((apply) => socket.on(\"acl:invalidate\", async () => apply(await api.me())))\n */\nexport function useUserSync(\n subscribe: (apply: (user: User | null) => void) => Cleanup,\n): void {\n const { setUser } = useACLContext();\n const ref = useRef(subscribe);\n ref.current = subscribe;\n useEffect(() => {\n const cleanup = ref.current(setUser);\n return () => {\n if (typeof cleanup === \"function\") cleanup();\n };\n }, [setUser]);\n}\n\n/**\n * Sincroniza o CATÁLOGO DE ROLES (afeta todos que as têm).\n * `reload(roles)` chama `engine.setRoles` — 1 notificação, toda a árvore reavalia.\n *\n * @example\n * useRolesSync((reload) => socket.on(\"acl:roles\", async () => reload(await api.roles())))\n */\nexport function useRolesSync(\n subscribe: (reload: (roles: Role[]) => void) => Cleanup,\n): void {\n const { engine } = useACLContext();\n const reload = useCallback(\n (roles: Role[]) => engine.setRoles(roles),\n [engine],\n );\n const ref = useRef(subscribe);\n ref.current = subscribe;\n useEffect(() => {\n const cleanup = ref.current(reload);\n return () => {\n if (typeof cleanup === \"function\") cleanup();\n };\n }, [reload]);\n}\n\n/**\n * Reage ao GANHO/PERDA de uma permissão (ex.: ao perder acesso, redirecionar).\n */\nexport function usePermissionEffect(\n action: Action,\n resource: Resource | undefined,\n handlers: { onGain?: () => void; onLose?: () => void },\n opts?: CheckOptions,\n): void {\n const allowed = useCan(action, resource, opts);\n const prev = useRef<boolean | null>(null);\n useEffect(() => {\n if (prev.current !== null) {\n if (allowed && !prev.current) handlers.onGain?.();\n else if (!allowed && prev.current) handlers.onLose?.();\n }\n prev.current = allowed;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [allowed]);\n}\n","import { type ReactNode } from \"react\";\nimport type { Action, Environment, Resource, Scope } from \"@shield-acl/core\";\nimport { useCan } from \"./hooks/useCan\";\nimport { useCanAsync } from \"./hooks/useCanAsync\";\nimport { useChecks, anyOf, allOf } from \"./hooks/useChecks\";\nimport type { CheckSpec } from \"./hooks/internal\";\n\nexport interface CanProps {\n action: Action;\n /** Nome/tipo do recurso (matching). */\n resource?: Resource;\n /** Instância do recurso (conditions ABAC). */\n record?: unknown;\n /** Override do scope do Provider. */\n scope?: Scope;\n environment?: Environment;\n fallback?: ReactNode;\n children: ReactNode;\n}\n\n/** Renderiza children quando o usuário TEM a permissão. */\nfunction CanBase({\n action,\n resource,\n record,\n scope,\n environment,\n fallback = null,\n children,\n}: CanProps) {\n const allowed = useCan(action, resource, { record, scope, environment });\n return <>{allowed ? children : fallback}</>;\n}\n\n/** Renderiza children quando o usuário NÃO tem a permissão. */\nexport function Cannot({\n action,\n resource,\n record,\n scope,\n environment,\n children,\n}: Omit<CanProps, \"fallback\">) {\n const allowed = useCan(action, resource, { record, scope, environment });\n return <>{allowed ? null : children}</>;\n}\n\nexport interface CanBatchProps {\n checks: CheckSpec[];\n fallback?: ReactNode;\n children: ReactNode;\n}\n\nfunction toMap(checks: CheckSpec[]): Record<string, CheckSpec> {\n const map: Record<string, CheckSpec> = {};\n checks.forEach((c, i) => {\n map[String(i)] = c;\n });\n return map;\n}\n\n/** Renderiza se QUALQUER checagem passar. */\nfunction CanAny({ checks, fallback = null, children }: CanBatchProps) {\n const result = useChecks(toMap(checks));\n return <>{anyOf(result) ? children : fallback}</>;\n}\n\n/** Renderiza se TODAS as checagens passarem. */\nfunction CanAll({ checks, fallback = null, children }: CanBatchProps) {\n const result = useChecks(toMap(checks));\n return <>{allOf(result) ? children : fallback}</>;\n}\n\nexport interface CanAsyncProps extends CanProps {\n pending?: ReactNode;\n}\n\n/** Verificação assíncrona com estado de carregamento. */\nfunction CanAsync({\n action,\n resource,\n record,\n scope,\n environment,\n pending = null,\n fallback = null,\n children,\n}: CanAsyncProps) {\n const { allowed, loading } = useCanAsync(action, resource, {\n record,\n scope,\n environment,\n });\n if (loading) return <>{pending}</>;\n return <>{allowed ? children : fallback}</>;\n}\n\n/**\n * `<Can>` com composição namespaced: `<Can.Any>`, `<Can.All>`, `<Can.Async>`.\n */\nexport const Can = Object.assign(CanBase, {\n Any: CanAny,\n All: CanAll,\n Async: CanAsync,\n});\n"],"mappings":"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","names":["useCallback","useCallback","useMemo","useMemo","useMemo","useMemo","useEffect","useState","useCallback","useState","useCallback","useEffect","useMemo","useMemo","useMemo","useMemo","useMemo","useCallback","useMemo","_a","useCallback","useMemo","useMemo","_a","useEffect","useCallback","useEffect","useCallback","jsx"]}