- Update default-diagnostic-service.ts - Update diagnostic-monitor-context.tsx - Update diagnostic-service-context.tsx - Update monitored-diagnostic-service.ts - Update teacher diagnostic page
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
"use client"
|
||
|
||
import { createContext, useContext, useMemo, type ReactNode } from "react"
|
||
|
||
import type { DiagnosticService } from "./diagnostic-service"
|
||
import { defaultDiagnosticService } from "./default-diagnostic-service"
|
||
import { createMonitoredDiagnosticService } from "./monitored-diagnostic-service"
|
||
import { noopDiagnosticMonitor } from "./diagnostic-monitor"
|
||
import { useDiagnosticMonitor } from "./diagnostic-monitor-context"
|
||
|
||
/**
|
||
* v2-P1-4: 诊断模块服务 Context。
|
||
*
|
||
* 组件通过 useDiagnosticService() 获取服务实现,
|
||
* 而非直接 import actions,实现依赖反转。
|
||
*
|
||
* 默认由 DiagnosticServiceProvider 在客户端组装默认实现(调用 Server Actions);
|
||
* 测试时可注入 mock 实现以隔离组件测试。
|
||
*/
|
||
const DiagnosticServiceContext = createContext<DiagnosticService | null>(null)
|
||
|
||
interface DiagnosticServiceProviderProps {
|
||
/** 可选自定义服务实现,未传则使用 defaultDiagnosticService + 监控包装 */
|
||
service?: DiagnosticService
|
||
children: ReactNode
|
||
}
|
||
|
||
export function DiagnosticServiceProvider({
|
||
service,
|
||
children,
|
||
}: DiagnosticServiceProviderProps): ReactNode {
|
||
const monitor = useDiagnosticMonitor()
|
||
const value = useMemo<DiagnosticService>(() => {
|
||
if (service) return service
|
||
// 客户端组装:默认 service + 监控埋点包装
|
||
return createMonitoredDiagnosticService(
|
||
defaultDiagnosticService,
|
||
monitor ?? noopDiagnosticMonitor,
|
||
)
|
||
}, [service, monitor])
|
||
|
||
return (
|
||
<DiagnosticServiceContext.Provider value={value}>
|
||
{children}
|
||
</DiagnosticServiceContext.Provider>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 获取诊断模块服务。
|
||
* 必须在 DiagnosticServiceProvider 内部使用。
|
||
*/
|
||
export function useDiagnosticService(): DiagnosticService {
|
||
const service = useContext(DiagnosticServiceContext)
|
||
if (!service) {
|
||
throw new Error(
|
||
"useDiagnosticService must be used within a DiagnosticServiceProvider",
|
||
)
|
||
}
|
||
return service
|
||
}
|