前端:抽象了创建服务上下文
This commit is contained in:
parent
1385251318
commit
88bf3b5592
@ -8,8 +8,8 @@
|
||||
*/
|
||||
import { SerializeType } from "./generalRequirement";
|
||||
import { ExtensionProps } from "types/extensionRequirement";
|
||||
import { useExtention } from "hooks/extensionService";
|
||||
import { ExtensionService } from "service/extensionService";
|
||||
import { useExtension } from "hooks/servicesProvider";
|
||||
|
||||
export interface PluginConfig {
|
||||
name: string; // 插件名称
|
||||
@ -46,25 +46,14 @@ export interface PluginConfiguration {
|
||||
};
|
||||
}
|
||||
|
||||
export interface PluginDependencies {
|
||||
plugins: string[]; // 依赖的插件列表(可选)
|
||||
themes: string[]; // 依赖的主题列表(可选)
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件属性接口
|
||||
*
|
||||
* 该接口定义了插件的属性和行为。
|
||||
*/
|
||||
export class usePluginProps implements ExtensionProps {
|
||||
private extensionService: ExtensionService = useExtention();
|
||||
private dependencies: PluginDependencies;
|
||||
export class usePluginProps extends ExtensionProps {
|
||||
|
||||
constructor(dependencies: PluginDependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
action?: ((...args: any[]) => void); // 动作函数(可选)
|
||||
component?: (...args: any[]) => React.FC; // 组件函数(可选)
|
||||
text?: (...args: any[]) => string; // 文本生成函数(可选)
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
|
||||
import type { LoaderFunction } from "@remix-run/node";
|
||||
import { useLoaderData } from "@remix-run/react";
|
||||
import { ThemeProvider } from "hooks/themeContext";
|
||||
import { createContext, useContext, ReactNode } from 'react';
|
||||
import { ServiceProvider } from "hooks/servicesProvider";
|
||||
import "./tailwind.css";
|
||||
|
||||
export function Layout({ children }: { children: React.ReactNode }) {
|
||||
@ -17,9 +17,9 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
||||
<Meta />
|
||||
</head>
|
||||
<body>
|
||||
<ThemeProvider>
|
||||
<ServiceProvider>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</ServiceProvider>
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</body>
|
||||
|
@ -1,55 +1,50 @@
|
||||
// File path: /hooks/createServiceContext.tsx
|
||||
|
||||
import { createContext, ReactNode, useContext } from "react";
|
||||
import { createContext, useContext, ReactNode, FC } from 'react';
|
||||
|
||||
/**
|
||||
* 创建一个服务上下文,用于提供和使用服务实例。
|
||||
*
|
||||
* @param name - 服务的名称,用于错误提示。
|
||||
* @param getInstance - 一个函数,用于获取服务实例。
|
||||
* @returns 返回一个包含 Provider 组件和 useService 钩子的对象。
|
||||
* 创建服务上下文的返回类型
|
||||
*/
|
||||
interface ServiceContextResult<T> {
|
||||
Provider: React.FC<{ children: ReactNode }>; // 提供服务实例的组件
|
||||
useService: () => T; // 获取服务实例的钩子
|
||||
}
|
||||
type ServiceContextReturn<N extends string,T> = {
|
||||
[K in `${N}Provider`]: FC<{ children: ReactNode }>;
|
||||
} & {
|
||||
[K in `use${N}`]: () => T;
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建服务上下文的函数。
|
||||
* 创建服务上下文和相关钩子的工厂函数
|
||||
*
|
||||
* @param name - 服务的名称,用于错误提示。
|
||||
* @param getInstance - 获取服务实例的函数。
|
||||
* @returns 包含 Provider 组件和 useService 钩子的对象。
|
||||
* @param serviceName - 服务名称,用于错误信息
|
||||
* @param ServiceClass - 服务类(包含静态 getInstance 方法)
|
||||
*/
|
||||
export function createServiceContext<T>(
|
||||
name: string,
|
||||
getInstance: () => T
|
||||
): ServiceContextResult<T> {
|
||||
// 创建一个上下文,初始值为 undefined。
|
||||
export function createServiceContext<T, N extends string>(
|
||||
serviceName: N,
|
||||
getServiceInstance: () => T
|
||||
): ServiceContextReturn<N,T> {
|
||||
const ServiceContext = createContext<T | undefined>(undefined);
|
||||
|
||||
// Provider 组件,用于提供服务实例给子组件
|
||||
const Provider = ({ children }: { children: ReactNode }) => {
|
||||
const service = getInstance();
|
||||
|
||||
return (
|
||||
<ServiceContext.Provider value={service}>
|
||||
/**
|
||||
* 服务提供者组件
|
||||
*/
|
||||
const Provider: FC<{ children: ReactNode }> = ({ children }) => (
|
||||
<ServiceContext.Provider value={getServiceInstance()}>
|
||||
{children}
|
||||
</ServiceContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// 获取服务实例的钩子
|
||||
/**
|
||||
* 自定义钩子,用于获取服务实例
|
||||
*/
|
||||
const useService = (): T => {
|
||||
const context = useContext(ServiceContext);
|
||||
if (context === undefined) {
|
||||
throw new Error(`use${name} must be used within a ${name}Provider`);
|
||||
throw new Error(`use${serviceName} must be used within a ${serviceName}Provider`);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
return {
|
||||
Provider,
|
||||
useService,
|
||||
};
|
||||
[`${serviceName}Provider`]: Provider,
|
||||
[`use${serviceName}`]: useService,
|
||||
} as ServiceContextReturn<N,T>;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// File path: /d:/data/echoes/frontend/hooks/extensionService.tsx
|
||||
/**
|
||||
* 扩展服务上下文提供者和自定义 Hook。
|
||||
*
|
||||
* 该文件包含扩展服务的上下文提供者组件和用于访问该上下文的自定义 Hook。
|
||||
*/
|
||||
|
||||
import { createContext, useContext, ReactNode } from 'react';
|
||||
import { ExtensionService } from 'service/extensionService';
|
||||
|
||||
// 创建扩展服务上下文
|
||||
const ExtensionContext = createContext<ExtensionService | undefined>(undefined);
|
||||
|
||||
/**
|
||||
* 扩展提供者组件,用于提供扩展服务的上下文。
|
||||
*
|
||||
* @param children - 要渲染的子组件。
|
||||
*/
|
||||
export function ExtensionProvider({ children }: { children: ReactNode }) {
|
||||
const extensionService = ExtensionService.getInstance(); // 获取扩展服务实例
|
||||
|
||||
return (
|
||||
<ExtensionContext.Provider value={extensionService}>
|
||||
{children}
|
||||
</ExtensionContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 Hook,用于访问扩展服务上下文。
|
||||
*
|
||||
* @returns {ExtensionService} - 返回扩展服务实例。
|
||||
* @throws {Error} - 如果在未被 ExtensionProvider 包裹的组件中调用,将抛出错误。
|
||||
*/
|
||||
export function useExtention(): ExtensionService {
|
||||
const context = useContext(ExtensionContext); // 获取扩展服务上下文
|
||||
if (context === undefined) {
|
||||
throw new Error('useTheme must be used within a ThemeProvider'); // 抛出错误
|
||||
}
|
||||
return context; // 返回扩展服务实例
|
||||
}
|
22
frontend/hooks/servicesProvider.tsx
Normal file
22
frontend/hooks/servicesProvider.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { ExtensionService } from 'service/extensionService';
|
||||
import { ThemeService } from 'service/themeService';
|
||||
import { createServiceContext } from './createServiceContext';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export const {
|
||||
ExtensionProvider,
|
||||
useExtension
|
||||
} = createServiceContext('Extension', () => ExtensionService.getInstance());
|
||||
|
||||
export const {
|
||||
ThemeProvider,
|
||||
useTheme
|
||||
} = createServiceContext("Theme", () => ThemeService.getInstance());
|
||||
|
||||
export const ServiceProvider = ({ children }: { children: ReactNode })=>(
|
||||
<ExtensionProvider>
|
||||
<ThemeProvider>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</ExtensionProvider>
|
||||
);
|
@ -1,36 +0,0 @@
|
||||
// File path: /hooks/themeContext.tsx
|
||||
|
||||
import { createContext, useContext, ReactNode } from 'react';
|
||||
import { ThemeService } from 'service/themeService';
|
||||
|
||||
const ThemeContext = createContext<ThemeService | undefined>(undefined);
|
||||
|
||||
/**
|
||||
* ThemeProvider 组件用于提供主题上下文给其子组件。
|
||||
* 它使用 ThemeService 的单例实例来管理主题相关的状态和功能。
|
||||
*
|
||||
* @param children - 要渲染的子组件。
|
||||
*/
|
||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
const themeService = ThemeService.getInstance();
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={themeService}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* useTheme 钩子用于访问主题上下文。
|
||||
*
|
||||
* @returns ThemeService - 返回主题服务的实例。
|
||||
* @throws Error - 如果在 ThemeProvider 之外使用,将抛出错误。
|
||||
*/
|
||||
export function useTheme(): ThemeService {
|
||||
const context = useContext(ThemeContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useTheme must be used within a ThemeProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
@ -88,7 +88,7 @@ export class ExtensionService {
|
||||
}
|
||||
|
||||
//获取指定配置文件
|
||||
getConfiguration(pluginName: string): PluginConfiguration | undefined {
|
||||
private getConfiguration(pluginName: string): PluginConfiguration | undefined {
|
||||
return this.configuration.get(pluginName);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user