@opentiny/next-sdk 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/{SimulatorMask-BHVXyogh-CARX3Rff.js → SimulatorMask-BHVXyogh-CKmEDsYG.js} +1 -1
  2. package/dist/{index-R_HIbfUX.js → index-CHMa2zG4.js} +1065 -1042
  3. package/dist/index.js +1 -1
  4. package/dist/page-tools/a11y/config.d.ts +6 -3
  5. package/dist/page-tools/a11y/constants.d.ts +20 -0
  6. package/dist/page-tools/a11y/utils.d.ts +14 -0
  7. package/dist/page-tools/constants.d.ts +4 -2
  8. package/dist/page-tools/context.d.ts +2 -0
  9. package/dist/page-tools/handlers/hover.d.ts +9 -0
  10. package/dist/page-tools/schema.d.ts +3 -3
  11. package/dist/page-tools/utils/dom.d.ts +8 -2
  12. package/dist/runtime.js +19 -172
  13. package/package.json +6 -1
  14. package/WebMcpClient.ts +0 -505
  15. package/WebMcpServer.ts +0 -447
  16. package/agent/AgentModelProvider.ts +0 -932
  17. package/agent/type.ts +0 -91
  18. package/agent/utils/generateReActPrompt.ts +0 -71
  19. package/agent/utils/getAISDKTools.ts +0 -34
  20. package/agent/utils/getBuiltinMcpTools.ts +0 -86
  21. package/agent/utils/parseReActAction.ts +0 -34
  22. package/core.ts +0 -26
  23. package/index.ts +0 -91
  24. package/page-tools/a11y/build.ts +0 -74
  25. package/page-tools/a11y/config.ts +0 -465
  26. package/page-tools/a11y/constants.ts +0 -131
  27. package/page-tools/a11y/search.ts +0 -127
  28. package/page-tools/a11y/types.ts +0 -105
  29. package/page-tools/a11y/utils.ts +0 -239
  30. package/page-tools/a11y/vnode.ts +0 -439
  31. package/page-tools/a11y-tree.ts +0 -14
  32. package/page-tools/bridge.ts +0 -722
  33. package/page-tools/configs/console-cloud.ts +0 -172
  34. package/page-tools/constants.ts +0 -12
  35. package/page-tools/context.ts +0 -50
  36. package/page-tools/effects.ts +0 -345
  37. package/page-tools/handlers/browserState.ts +0 -12
  38. package/page-tools/handlers/click.ts +0 -30
  39. package/page-tools/handlers/executeJavascript.ts +0 -22
  40. package/page-tools/handlers/fill.ts +0 -65
  41. package/page-tools/handlers/scroll.ts +0 -66
  42. package/page-tools/handlers/searchTree.ts +0 -27
  43. package/page-tools/handlers/select.ts +0 -39
  44. package/page-tools/initialize-builtin-WebMCP.ts +0 -20
  45. package/page-tools/page-agent-highlight/index.ts +0 -245
  46. package/page-tools/page-agent-mask/SimulatorMask.module.css +0 -14
  47. package/page-tools/page-agent-mask/SimulatorMask.ts +0 -299
  48. package/page-tools/page-agent-mask/checkDarkMode.ts +0 -181
  49. package/page-tools/page-agent-mask/cursor-border.svg +0 -3
  50. package/page-tools/page-agent-mask/cursor-fill.svg +0 -5
  51. package/page-tools/page-agent-mask/cursor.module.css +0 -70
  52. package/page-tools/page-agent-mask/hauwei.svg +0 -25
  53. package/page-tools/page-agent-prompt.md +0 -139
  54. package/page-tools/page-agent-tool-event.ts +0 -113
  55. package/page-tools/page-agent-tool.ts +0 -207
  56. package/page-tools/page-state-cache.ts +0 -78
  57. package/page-tools/schema.ts +0 -52
  58. package/page-tools/tool-config.ts +0 -100
  59. package/page-tools/utils/dom.ts +0 -158
  60. package/page-tools/utils/scroll.ts +0 -58
  61. package/remoter/QrCode.ts +0 -54
  62. package/remoter/createRemoter.ts +0 -957
  63. package/remoter/svgs/chat.svg +0 -43
  64. package/remoter/svgs/icon-copy.svg +0 -25
  65. package/remoter/svgs/link.svg +0 -28
  66. package/remoter/svgs/logo.svg +0 -45
  67. package/remoter/svgs/qrcode.svg +0 -35
  68. package/remoter/svgs/scan.svg +0 -21
  69. package/remoter/tooltips.ts +0 -260
  70. package/runtime.html +0 -39
  71. package/runtime.ts +0 -44
  72. package/script/utils.ts +0 -26
  73. package/skills/index.ts +0 -287
  74. package/test/page-tools/a11y/build.test.ts +0 -638
  75. package/test/page-tools/a11y/config.test.ts +0 -370
  76. package/test/page-tools/configs/console-cloud.test.ts +0 -168
  77. package/test/page-tools/page-agent-highlight.test.ts +0 -110
  78. package/test/page-tools/page-agent-tool-dispatch.test.ts +0 -208
  79. package/test/page-tools/page-agent-tool.test.ts +0 -102
  80. package/test/page-tools/tool-config.test.ts +0 -112
  81. package/test/page-tools/utils/dom.test.ts +0 -122
  82. package/tsconfig.json +0 -16
  83. package/utils/builtinProxy.ts +0 -144
  84. package/utils/env.ts +0 -13
  85. package/utils/uuid.ts +0 -10
  86. package/vite.config.runtime.ts +0 -22
  87. package/vite.config.ts +0 -63
  88. package/vitest.config.ts +0 -10
package/agent/type.ts DELETED
@@ -1,91 +0,0 @@
1
- import type { ProviderV2 } from '@ai-sdk/provider'
2
- import type { MCPClientConfig } from '@ai-sdk/mcp'
3
-
4
- // 从 MCPClientConfig 中提取 transport 类型
5
- export type MCPTransport = MCPClientConfig['transport']
6
-
7
- /**
8
- * 浏览器内置 WebMCP 测试 API 接口 (如 document.modelContext)
9
- */
10
- export interface BuiltinMcpClient {
11
- listTools?: () => Promise<any[]>
12
- getTools?: () => Promise<any[]>
13
- executeTool: (tool: any, input: string) => Promise<any>
14
- registerTool?: (config: { name: string; execute: (input: any) => Promise<any> | any; [key: string]: any }) => void
15
- unregisterTool?: (name: string) => void
16
- }
17
-
18
- type ProviderFactory = 'openai' | 'deepseek' | ((options: any) => ProviderV2)
19
-
20
- type LlmFactoryConfig = {
21
- /** API密钥 */
22
- apiKey: string
23
- /** API基础URL */
24
- baseURL: string
25
- /** 内置或自定义 Provider 工厂函数 */
26
- providerType: ProviderFactory
27
- /** 互斥:当使用 providerType 分支时不允许传入 llm */
28
- llm?: never
29
- /** 是否使用 ReAct 模式(通过提示词而非 function calling 进行工具调用),默认为 false */
30
- useReActMode?: boolean
31
- }
32
-
33
- type LlmInstanceConfig = {
34
- /** 自定义 Provider 实例,优先级最高 */
35
- llm: ProviderV2
36
- /** 互斥:当传入 llm 实例时不需要 apiKey/baseURL/providerType */
37
- apiKey?: never
38
- baseURL?: never
39
- providerType?: never
40
- /** 是否使用 ReAct 模式(通过提示词而非 function calling 进行工具调用),默认为 false */
41
- useReActMode?: boolean
42
- }
43
-
44
- /** 代理模型提供器的大语言配置对象, 通过 XOR 表达二选一 */
45
- export type IAgentModelProviderLlmConfig = LlmFactoryConfig | LlmInstanceConfig
46
-
47
- /** Mcp Server的配置对象 */
48
- export type McpServerConfig =
49
- | {
50
- type: 'streamableHttp'
51
- url: string
52
- useAISdkClient?: boolean
53
- headers?: Record<string, string>
54
- name?: string
55
- description?: string
56
- }
57
- | {
58
- type: 'sse'
59
- url: string
60
- useAISdkClient?: boolean
61
- headers?: Record<string, string>
62
- name?: string
63
- description?: string
64
- }
65
- | {
66
- type: 'local'
67
- transport: MCPTransport
68
- useAISdkClient?: boolean
69
- name?: string
70
- description?: string
71
- }
72
- | {
73
- /**
74
- * 浏览器内置 WebMCP 类型。
75
- * 将 `document.modelContext` 作为 MCP 工具数据源,
76
- * 通过 `getBuiltinMcpTools` 适配为 ai-sdk 可调用的 ToolSet。
77
- */
78
- type: 'builtin'
79
- /** 传入 `document.modelContext` 对象 */
80
- client: BuiltinMcpClient
81
- name?: string
82
- description?: string
83
- }
84
-
85
- /** */
86
- export interface IAgentModelProviderOption {
87
- /** 代理模型提供器的大语言配置对象 */
88
- llmConfig: IAgentModelProviderLlmConfig
89
- /** Mcp Server的配置对象的集合,键为服务器名称,值为配置对象 */
90
- mcpServers?: Record<string, McpServerConfig>
91
- }
@@ -1,71 +0,0 @@
1
- import type { ToolSet } from 'ai'
2
-
3
- /**
4
- * 生成 ReAct 模式的工具描述提示词(统一使用 XML 格式)
5
- * 将工具集合转换为 ReAct 格式的文本描述,用于添加到系统提示词中
6
- * @param tools - 工具集合对象
7
- * @returns 格式化的工具描述字符串
8
- */
9
- export function generateReActToolsPrompt(tools: ToolSet): string {
10
- const toolEntries = Object.entries(tools)
11
-
12
- // 如果没有工具,返回空字符串
13
- if (toolEntries.length === 0) {
14
- return ''
15
- }
16
-
17
- let prompt = `
18
- # 工具调用
19
-
20
- 你可以根据需要调用以下工具:
21
-
22
- <tools>
23
- `
24
-
25
- // 遍历所有工具,生成工具描述
26
- toolEntries.forEach(([toolName, tool]) => {
27
- const toolInfo = tool as any
28
- const description = toolInfo.description || '无描述'
29
- const schema = toolInfo.parameters || toolInfo.inputSchema || {}
30
-
31
- // 构造类似 OpenAI function 的格式但放在 XML 中
32
- const toolJson = {
33
- name: toolName,
34
- description: description,
35
- parameters: schema
36
- }
37
- prompt += `${JSON.stringify(toolJson, null, 2)}\n`
38
- })
39
-
40
- prompt += `
41
- </tools>
42
-
43
- ## 工具调用格式
44
-
45
- 要调用工具,请使用以下 XML 格式:
46
- Thought: [你的思考过程]
47
- <tool_call>
48
- {"name": "toolName", "arguments": {"arg1": "value1"}}
49
- </tool_call>
50
-
51
- 工具执行后,你将收到 <tool_response> 格式的结果。你可以继续思考或调用其他工具。
52
-
53
- ## 使用示例
54
-
55
- 如果用户要求"获取今天的日期",你可以这样调用工具:
56
- Thought: 用户想要获取今天的日期,我需要调用日期相关的工具。
57
- <tool_call>{"name": "get-today", "arguments": {}}</tool_call>
58
-
59
- 然后等待工具返回结果(Observation),再根据结果给出最终答案。
60
-
61
- ## 任务完成
62
-
63
- 当任务完成或无法继续时,直接给出最终答案即可。
64
-
65
- **重要提示**:
66
- - 必须严格按照 XML 格式调用工具
67
- - arguments 必须是有效的 JSON 格式
68
- - 如果不需要调用工具,直接给出最终答案即可
69
- `
70
- return prompt
71
- }
@@ -1,34 +0,0 @@
1
- import { dynamicTool, jsonSchema, Tool, ToolExecutionOptions, ToolSet } from 'ai'
2
- import { WebMcpClient } from '../../WebMcpClient'
3
-
4
- /**
5
- * 快速从官方 mcp 或 WebMcpClient 这2种client中读取 tools 数组,并转换成 ai-sdk 的tool的对象格式。
6
- * @params client 一个已连接好的 WebMcpClient
7
- * @returns ai-sdk的dynamicTool对象。
8
- */
9
- export const getAISDKTools = async (client: WebMcpClient): Promise<ToolSet> => {
10
- const tools: Record<string, Tool> = {}
11
-
12
- try {
13
- const listToolsResult = await client.listTools()
14
- for (const { name, description, inputSchema } of listToolsResult.tools) {
15
- const execute = async (args: any, options: ToolExecutionOptions): Promise<any> => {
16
- return client.callTool({ name, arguments: args }, { signal: options?.abortSignal })
17
- }
18
-
19
- tools[name] = dynamicTool({
20
- description,
21
- inputSchema: jsonSchema({
22
- ...inputSchema,
23
- properties: (inputSchema.properties as Record<string, any>) ?? {},
24
- additionalProperties: false
25
- }),
26
- execute
27
- })
28
- }
29
-
30
- return tools
31
- } catch (error) {
32
- throw error
33
- }
34
- }
@@ -1,86 +0,0 @@
1
- import { dynamicTool, jsonSchema, Tool, ToolSet } from 'ai'
2
-
3
- /**
4
- * 浏览器内置 WebMCP 测试 API 的工具描述格式(Chrome document.modelContext)
5
- */
6
- type BuiltinToolDescriptor = {
7
- name: string
8
- description?: string
9
- inputSchema?: {
10
- type?: string
11
- properties?: Record<string, unknown>
12
- required?: string[]
13
- [key: string]: unknown
14
- }
15
- }
16
-
17
- type BuiltinModelContextTesting = {
18
- listTools?: () => Promise<BuiltinToolDescriptor[]>
19
- getTools?: () => Promise<BuiltinToolDescriptor[]>
20
- executeTool?: (tool: { name: string }, input: string) => Promise<unknown>
21
- }
22
-
23
- /**
24
- * 将浏览器内置 WebMCP 的 `document.modelContext` 适配为 ai-sdk 的 ToolSet。
25
- *
26
- * 类似 getAISDKTools,但数据源是浏览器原生 API 而非 MCP client。
27
- * 工具执行时通过 `executeTool(toolObj, JSON.stringify(args))` 代理给浏览器。
28
- *
29
- * @param client - `document.modelContext` 对象
30
- * @returns ai-sdk 格式的 ToolSet,可直接传入 streamText/generateText 的 tools 参数
31
- */
32
- export const getBuiltinMcpTools = async (client: object | undefined | null): Promise<ToolSet> => {
33
- const tools: Record<string, Tool> = {}
34
- if (!client) {
35
- return tools
36
- }
37
-
38
- const testing = client as BuiltinModelContextTesting
39
-
40
- // 优先使用 listTools,降级到 getTools
41
- const listFn = testing.listTools ?? testing.getTools
42
- if (!listFn) {
43
- return tools
44
- }
45
-
46
- const rawList = await listFn.call(testing)
47
- const list = Array.isArray(rawList) ? (rawList as BuiltinToolDescriptor[]) : []
48
-
49
- for (const descriptor of list) {
50
- const { name, description } = descriptor
51
- const rawInputSchema = descriptor.inputSchema
52
- let schemaObj: Record<string, any> = {}
53
-
54
- if (typeof rawInputSchema === 'string') {
55
- try {
56
- schemaObj = JSON.parse(rawInputSchema)
57
- } catch (e) {
58
- console.error('Failed to parse inputSchema in getBuiltinMcpTools:', e)
59
- }
60
- } else if (typeof rawInputSchema === 'object' && rawInputSchema !== null) {
61
- schemaObj = rawInputSchema as Record<string, any>
62
- }
63
-
64
- // 规范化 inputSchema:补全 properties/additionalProperties 字段
65
- const normalizedSchema = {
66
- type: 'object' as const,
67
- properties: (schemaObj.properties ?? {}) as Record<string, unknown>,
68
- ...(schemaObj.required ? { required: schemaObj.required } : {}),
69
- additionalProperties: false,
70
- ...schemaObj
71
- }
72
-
73
- tools[name] = dynamicTool({
74
- description: description ?? '',
75
- inputSchema: jsonSchema(normalizedSchema as Parameters<typeof jsonSchema>[0]),
76
- async execute(args) {
77
- if (!testing.executeTool) {
78
- throw new Error(`document.modelContext.executeTool is not available`)
79
- }
80
- return testing.executeTool(descriptor, JSON.stringify(args ?? {}))
81
- }
82
- })
83
- }
84
-
85
- return tools
86
- }
@@ -1,34 +0,0 @@
1
- import type { ToolSet } from 'ai'
2
-
3
- /**
4
- * 解析 ReAct 格式的工具调用
5
- * 从模型输出文本中提取工具名称和参数
6
- * 现在统一使用 XML 格式(<call> 标签),同时保留对其他格式的兼容性支持
7
- * @param text - 模型输出的文本
8
- * @param availableTools - 可用的工具集合,用于验证工具名称
9
- * @returns 解析出的工具调用信息,如果未找到则返回 null
10
- */
11
- export function parseReActAction(text: string, availableTools: ToolSet): { toolName: string; arguments: any } | null {
12
- if (!text || typeof text !== 'string') {
13
- return null
14
- }
15
-
16
- // XML 格式 <tool_call>
17
- const toolCallMatchLegacy = text.match(/<tool_call>([\s\S]*?)<\/tool_call>/i)
18
- if (toolCallMatchLegacy) {
19
- try {
20
- const jsonContent = toolCallMatchLegacy[1].trim()
21
- const parsed = JSON.parse(jsonContent)
22
- const toolName = parsed.name || parsed.action || parsed.tool
23
- const args = parsed.arguments || parsed.args || parsed.input || {}
24
-
25
- if (toolName && availableTools[toolName]) {
26
- return { toolName, arguments: args }
27
- }
28
- } catch {
29
- // 解析失败,继续尝试其他方法
30
- }
31
- }
32
-
33
- return null
34
- }
package/core.ts DELETED
@@ -1,26 +0,0 @@
1
- // 核心导出,仅包含无 DOM 依赖(Node.js / Service Worker 安全)的内容
2
- import Ajv from 'ajv'
3
- export { Ajv }
4
- export { z } from 'zod'
5
- export { AuthClientProvider } from '@opentiny/next'
6
- export { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'
7
- export { UriTemplate } from '@modelcontextprotocol/sdk/shared/uriTemplate.js'
8
- export { completable } from '@modelcontextprotocol/sdk/server/completable.js'
9
- export { getDisplayName } from '@modelcontextprotocol/sdk/shared/metadataUtils.js'
10
- export { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
11
- export type * from 'zod'
12
- export type * from '@opentiny/next'
13
- export type * from '@modelcontextprotocol/sdk/types.js'
14
- export type * from '@modelcontextprotocol/sdk/shared/protocol.js'
15
- export type * from '@modelcontextprotocol/sdk/shared/transport.js'
16
- export type * from '@modelcontextprotocol/sdk/client/sse.js'
17
- export type * from '@modelcontextprotocol/sdk/client/streamableHttp.js'
18
- export type * from '@modelcontextprotocol/sdk/server/mcp.js'
19
-
20
- export * from './WebMcpServer'
21
- export * from './WebMcpClient'
22
-
23
- export { AgentModelProvider } from './agent/AgentModelProvider'
24
- export { getAISDKTools } from './agent/utils/getAISDKTools'
25
- export type * from './agent/type'
26
- export { initializeBuiltinWebMCP } from './page-tools/initialize-builtin-WebMCP'
package/index.ts DELETED
@@ -1,91 +0,0 @@
1
- // 从相关包中,导出一些常用变量,方便用户导入
2
- import Ajv from 'ajv'
3
- export { Ajv }
4
- export { z } from 'zod'
5
- export { AuthClientProvider } from '@opentiny/next'
6
- export { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'
7
- export { UriTemplate } from '@modelcontextprotocol/sdk/shared/uriTemplate.js'
8
- export { completable } from '@modelcontextprotocol/sdk/server/completable.js'
9
- export { getDisplayName } from '@modelcontextprotocol/sdk/shared/metadataUtils.js'
10
- export { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
11
- export type * from 'zod'
12
- export type * from '@opentiny/next'
13
- export type * from '@modelcontextprotocol/sdk/types.js'
14
- export type * from '@modelcontextprotocol/sdk/shared/protocol.js'
15
- export type * from '@modelcontextprotocol/sdk/shared/transport.js'
16
- export type * from '@modelcontextprotocol/sdk/client/sse.js'
17
- export type * from '@modelcontextprotocol/sdk/client/streamableHttp.js'
18
- export type * from '@modelcontextprotocol/sdk/server/mcp.js'
19
-
20
- // 2大核心模块
21
- export * from './WebMcpServer'
22
- export * from './WebMcpClient'
23
-
24
- // 快速创建一个悬浮图标和菜单,是扫码和聊天框的入口
25
- export * from './remoter/createRemoter'
26
-
27
- // 一个通用的ai-sdk的agent封装
28
- export { AgentModelProvider } from './agent/AgentModelProvider'
29
-
30
- // 快速 从官方 mcp 或 WebMcpClient 这2种client中, 抽取成 ai-sdk 所需要的 tool的对象
31
- export { getAISDKTools } from './agent/utils/getAISDKTools'
32
-
33
- // 方便的二维码类
34
- export { QrCode, type QrCodeOption } from './remoter/QrCode'
35
- export type * from './agent/type'
36
-
37
- // Web MCP 页面工具桥接:工具调用自动导航 + 页面消息通信
38
- export * from './page-tools/bridge'
39
-
40
- // Web 端 Skill 公共能力:解析 skill 文档、生成 systemPrompt、内置 list_skills / get_skill_content 工具
41
- export {
42
- getSkillOverviews,
43
- formatSkillsForSystemPrompt,
44
- getSkillMdContent,
45
- getMainSkillPaths,
46
- getMainSkillPathByName,
47
- parseSkillFrontMatter,
48
- createSkillTools,
49
- type SkillMeta,
50
- type SkillToolsSet
51
- } from './skills/index'
52
-
53
- export * from '@mcp-b/webmcp-polyfill'
54
-
55
- export { initializeBuiltinWebMCP } from './page-tools/initialize-builtin-WebMCP'
56
- export { registerPageAgentTool } from './page-tools/page-agent-tool'
57
- export { PAGE_AGENT_TOOL_CALL_EVENT, PAGE_AGENT_TOOL_RESULT_EVENT } from './page-tools/page-agent-tool-event'
58
- export type { PageAgentToolCallEventDetail, PageAgentToolResultEventDetail } from './page-tools/page-agent-tool-event'
59
- export type { PageAgentToolOptions } from './page-tools/tool-config'
60
-
61
- // registerPageAgentTool 完整运行期配置(顶层选项 enableHighlight + 统一无障碍配置 a11yConfig)
62
- // 的唯一一套读写 API:注册时初始化一次,之后可随时读取/修改
63
- export { DEFAULT_PAGE_AGENT_TOOL_CONFIG, getPageAgentToolConfig, setPageAgentToolConfig } from './page-tools/tool-config'
64
- export type { PageAgentToolConfig, PageAgentToolConfigPatch } from './page-tools/tool-config'
65
-
66
- // 站点预设:云控制台(consoleCloud)等 PageAgentToolOptions,可直接传给 registerPageAgentTool
67
- export {
68
- consoleCloudPageAgentToolOptions,
69
- isConsoleCloudHost,
70
- } from './page-tools/configs/console-cloud'
71
-
72
- // 统一无障碍配置(A11yConfig):角色/状态规则、白/黑名单、自定义属性、弹窗选择器,
73
- // 以及供用户直接调用的底层解析函数(运行期读写请使用上面的 getPageAgentToolConfig/setPageAgentToolConfig)
74
- export {
75
- DEFAULT_A11Y_CONFIG,
76
- defineA11yConfig,
77
- resolveA11yInfo,
78
- resolveA11yRole,
79
- resolveA11yStates,
80
- mergeA11yConfig,
81
- mergeA11yConfigs,
82
- ensureResolvedA11yConfig,
83
- isResolvedA11yConfig,
84
- extractSelectors,
85
- } from './page-tools/a11y/config'
86
- export type { A11yConfig, ResolvedA11yConfig, A11yRoleRule, A11yMatcher, A11yStateName, A11yInfo } from './page-tools/a11y/config'
87
-
88
- // 无障碍树构建与搜索:供高级用户直接生成/搜索自定义根节点下的无障碍树
89
- export { buildA11yTree } from './page-tools/a11y/build'
90
- export { searchA11yTree } from './page-tools/a11y/search'
91
- export type { A11yTreeOptions, A11yTreeResult, SearchA11yTreeOptions, SearchA11yTreeResult, VNode, RefMap } from './page-tools/a11y/types'
@@ -1,74 +0,0 @@
1
- /**
2
- * a11y/build.ts
3
- *
4
- * 暴露生成整棵无障碍树的主逻辑方法。
5
- */
6
-
7
- import type { A11yTreeOptions, A11yTreeResult, A11yTreeShapeOptions, RefMap } from './types'
8
- import type { A11yConfig } from './config'
9
- import { ensureResolvedA11yConfig } from './config'
10
- import { buildVNode, serializeVNode } from './vnode'
11
- import { getComposedChildren, collectHoverPointerElements } from './utils'
12
- import { deepQuerySelectorAll } from '../utils/dom'
13
- import { HIGHLIGHT_CONTAINER_ID } from '../page-agent-highlight'
14
-
15
- /** 将 whitelist/blacklist 中的 Element 引用与 CSS 选择器字符串统一解析为元素集合(字符串每次动态解析,适配 SPA 重渲染) */
16
- function resolveElementList(list: Array<Element | string>, root: Element): Set<Element> {
17
- const set = new Set<Element>()
18
- for (const item of list) {
19
- if (typeof item === 'string') {
20
- try {
21
- for (const el of deepQuerySelectorAll(item, root)) set.add(el)
22
- } catch {
23
- // 忽略非法选择器
24
- }
25
- } else if (item) {
26
- set.add(item)
27
- }
28
- }
29
- return set
30
- }
31
-
32
- /**
33
- * 生成当前页面的语义化 ARIA YAML 树
34
- *
35
- * @param root 遍历起点,默认 document.body
36
- * @param config 统一无障碍配置(角色/状态规则、白/黑名单、自定义属性等)+ 树形状选项(pruneUnnamed/preserveRoles)
37
- */
38
- export function buildA11yTree(root: Element = document.body, config?: A11yConfig & A11yTreeOptions): A11yTreeResult {
39
- const { pruneUnnamed = true, preserveRoles = [], ...a11yConfig } = config ?? {}
40
- // 运行期 a11yConfig 通常已是 ResolvedA11yConfig,走快路径避免再次与默认配置拼接
41
- const resolved = ensureResolvedA11yConfig(a11yConfig)
42
- const shapeOpts: A11yTreeShapeOptions = { pruneUnnamed, preserveRoles }
43
-
44
- // 使用对象引用避免全局可变状态,消除并发调用隐患
45
- const refCounter = { value: 0 }
46
- const refMap: RefMap = new Map()
47
- const blacklistSet = resolveElementList(resolved.blacklist, root)
48
- const whitelistSet = resolveElementList(resolved.whitelist, root)
49
- const lines: string[] = []
50
-
51
- // 永远过滤高亮容器
52
- const highlightContainer = document.getElementById(HIGHLIGHT_CONTAINER_ID)
53
- if (highlightContainer) blacklistSet.add(highlightContainer)
54
-
55
- // 一次性扫描样式表,收集只在 :hover/:focus/:active 下声明 cursor:pointer 的元素。
56
- // 这类元素静止态 getComputedStyle 读到 auto,需靠样式表兜底才能识别为可点击。
57
- const hoverPointerSet = collectHoverPointerElements(root)
58
-
59
- for (const child of getComposedChildren(root)) {
60
- const vnode = buildVNode(child, refCounter, refMap, blacklistSet, whitelistSet, resolved, hoverPointerSet)
61
- if (vnode) {
62
- lines.push(...serializeVNode(vnode, 0, shapeOpts))
63
- }
64
- }
65
-
66
- const yaml = '```yaml\n' + lines.join('\n') + '\n```'
67
-
68
- return {
69
- yaml,
70
- refMap,
71
- interactiveCount: refMap.size,
72
- lines,
73
- }
74
- }