| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import React, { |
| useState, |
| useEffect, |
| useCallback, |
| useMemo, |
| useRef, |
| useContext, |
| createContext, |
| } from "react"; |
| import { api, fetchJSON } from "@/lib/api"; |
| import { cn, timeAgo, isoTimeAgo } from "@/lib/utils"; |
| import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; |
| import { Badge } from "@/components/ui/badge"; |
| import { Button } from "@/components/ui/button"; |
| import { Input } from "@/components/ui/input"; |
| import { Label } from "@/components/ui/label"; |
| import { Select, SelectOption } from "@/components/ui/select"; |
| import { Separator } from "@/components/ui/separator"; |
| import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; |
| import { useI18n } from "@/i18n"; |
| import { registerSlot, PluginSlot } from "./slots"; |
|
|
| |
| |
| |
|
|
| type RegistryListener = () => void; |
|
|
| const _registered: Map<string, React.ComponentType> = new Map(); |
| const _listeners: Set<RegistryListener> = new Set(); |
|
|
| function _notify() { |
| for (const fn of _listeners) { |
| try { fn(); } catch { } |
| } |
| } |
|
|
| |
| function registerPlugin(name: string, component: React.ComponentType) { |
| _registered.set(name, component); |
| _notify(); |
| } |
|
|
| |
| export function getPluginComponent(name: string): React.ComponentType | undefined { |
| return _registered.get(name); |
| } |
|
|
| |
| export function onPluginRegistered(fn: RegistryListener): () => void { |
| _listeners.add(fn); |
| return () => _listeners.delete(fn); |
| } |
|
|
| |
| export function getRegisteredCount(): number { |
| return _registered.size; |
| } |
|
|
| |
| |
| |
|
|
| declare global { |
| interface Window { |
| __HERMES_PLUGIN_SDK__: unknown; |
| __HERMES_PLUGINS__: { |
| register: typeof registerPlugin; |
| registerSlot: typeof registerSlot; |
| }; |
| } |
| } |
|
|
| export function exposePluginSDK() { |
| window.__HERMES_PLUGINS__ = { |
| register: registerPlugin, |
| registerSlot, |
| }; |
|
|
| window.__HERMES_PLUGIN_SDK__ = { |
| |
| React, |
| hooks: { |
| useState, |
| useEffect, |
| useCallback, |
| useMemo, |
| useRef, |
| useContext, |
| createContext, |
| }, |
|
|
| |
| api, |
| |
| fetchJSON, |
|
|
| |
| components: { |
| Card, |
| CardHeader, |
| CardTitle, |
| CardContent, |
| Badge, |
| Button, |
| Input, |
| Label, |
| Select, |
| SelectOption, |
| Separator, |
| Tabs, |
| TabsList, |
| TabsTrigger, |
| PluginSlot, |
| }, |
|
|
| |
| utils: { cn, timeAgo, isoTimeAgo }, |
|
|
| |
| useI18n, |
| }; |
| } |
|
|