# Feature SDK

## 概述

Feature SDK 提供插件管理 CoreBox 搜索结果项（TuffItem）的能力。

## 介绍

**快速开始**

:::TuffCodeBlock{lang="typescript"}
---
code: |
  import { useFeature } from '@talex-touch/utils/plugin/sdk'

  const feature = useFeature()

  // 推送搜索结果
  feature.pushItems([
    {
      id: 'result-1',
      title: { text: '搜索结果 1' },
      subtitle: { text: '描述信息' },
      source: { id: 'my-plugin', name: 'My Plugin' }
    }
  ])

  // 监听输入变化
  feature.onInputChange((input) => {
    console.log('用户输入:', input)
  })
---
:::

---

## API 参考

**useFeature()**

获取 Feature SDK 实例。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  import { useFeature } from '@talex-touch/utils/plugin/sdk'

  const feature = useFeature()
---
:::

> **注意**：必须在插件渲染器上下文中调用，且需要 `$boxItems` API 可用。

---

## 搜索结果管理

**`pushItems(items)`**

推送多个项目到 CoreBox 搜索结果。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  feature.pushItems([
    {
      id: 'calc-result',
      title: { text: '42' },
      subtitle: { text: '计算结果' },
      source: { id: 'calculator', name: 'Calculator' },
      icon: 'ri:calculator-line'
    }
  ])
---
:::

**`updateItem(id, updates)`**

更新指定项目。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  feature.updateItem('result-1', {
    title: { text: '更新后的标题' },
    subtitle: { text: '新的描述' }
  })
---
:::

**`removeItem(id)`**

移除指定项目。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  feature.removeItem('result-1')
---
:::

**`clearItems()`**

清除当前插件的所有项目。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  feature.clearItems()
---
:::

**`getItems()`**

获取当前插件的所有项目。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  const items = feature.getItems()
  console.log(`当前显示 ${items.length} 个项目`)
---
:::

---

## 事件监听

**`onInputChange(handler)`**

监听搜索输入变化。

:::TuffCodeBlock{lang="typescript"}
---
code: |
  const unsubscribe = feature.onInputChange((input) => {
    console.log('用户输入:', input)

    // 执行实时搜索
    const results = await search(input)
    feature.pushItems(results)
  })

  // 停止监听
  unsubscribe()
---
:::

**键盘处理**

`feature.onKeyEvent()` 已移除。旧 `core-box:key-event` 通道没有生产发送端，插件 UI 键盘交互应使用本地 DOM/组件键盘事件或宿主传入的 `hostKeyEvent` props。

---

## TuffItem 结构

:::TuffCodeBlock{lang="typescript"}
---
code: |
  interface TuffItem {
    id: string

    title: {
      text: string
      highlight?: boolean
    }

    subtitle?: {
      text: string
      highlight?: boolean
    }

    source: {
      id: string
      name: string
    }

    icon?: string

    actions?: TuffAction[]

    meta?: Record<string, any>
  }
---
:::

---

## 完整示例

**实时搜索插件**

:::TuffCodeBlock{lang="typescript"}
---
code: |
  import { useFeature, useBox } from '@talex-touch/utils/plugin/sdk'
  import { debounce } from 'lodash-es'

  const feature = useFeature()
  const box = useBox()

  // 防抖搜索
  const debouncedSearch = debounce(async (query: string) => {
    if (!query.trim()) {
      feature.clearItems()
      return
    }

    const results = await fetchSearchResults(query)

    feature.clearItems()
    feature.pushItems(results.map((r, i) => ({
      id: `result-${i}`,
      title: { text: r.title },
      subtitle: { text: r.description },
      source: { id: 'my-search', name: 'Search' },
      icon: r.icon
    })))

    // 调整窗口大小
    await box.expand({ length: results.length })
  }, 300)

  // 监听输入
  feature.onInputChange(debouncedSearch)

  // 键盘交互在插件 UI 组件内使用本地 keydown 或 hostKeyEvent props 处理。
---
:::

---

## 类型定义

:::TuffCodeBlock{lang="typescript"}
---
code: |
  interface FeatureSDK {
    pushItems(items: TuffItem[]): void
    updateItem(id: string, updates: Partial<TuffItem>): void
    removeItem(id: string): void
    clearItems(): void
    getItems(): TuffItem[]
    onInputChange(handler: InputChangeHandler): () => void
  }

  type InputChangeHandler = (input: string) => void
---
:::

## 最佳实践

- 结果项 ID 保持稳定，避免频繁重建造成排序抖动。
- 输入变化时做去抖，减少 pushItems 的调用频率。
- 合理设置排序与权重字段，避免推荐权重失衡。

## 技术原理

- Feature SDK 在渲染进程构建结果项，并通过主进程 CoreBox 管理器渲染。
- 结果数据进入统一的排序与推荐管线，最终合并展示给用户。
