npm package: @qauri/api
Description: JavaScript/TypeScript SDK for Qauri Web Component
Author: Qauri Team
Latest version: 0.1.2

# @qauri/api

JavaScript/TypeScript SDK for Qauri Web Component - 类型安全的 Native 通信 API

## 安装

```bash
npm install @qauri/api
# or
yarn add @qauri/api
# or
pnpm add @qauri/api
```

## 快速开始

### TypeScript

```typescript
import { invoke, listen, once } from '@qauri/api';

// 调用 Native 命令
const version = await invoke<string>('get_app_version');
console.log('App version:', version);

// 带参数的命令
interface User {
  id: number;
  name: string;
}

const user = await invoke<User>('get_user', { id: 123 });
console.log('User:', user.name);

// 监听 Native 事件
const unlisten = listen<string>('notification', (message) => {
  console.log('Notification:', message);
});

// 取消监听
unlisten();

// 监听一次性事件
once<void>('app_ready', () => {
  console.log('App is ready!');
});
```

### JavaScript (ESM)

```javascript
import { invoke, listen } from '@qauri/api';

// 调用命令
const data = await invoke('get_data');

// 监听事件
const unlisten = listen('update', (payload) => {
  console.log('Update:', payload);
});
```

### JavaScript (CommonJS)

```javascript
const { invoke, listen } = require('@qauri/api');

// 使用方式相同
```

## API 文档

### `invoke<T>(cmd: string, args?: unknown): Promise<T>`

调用 Native 命令并返回结果。

**参数：**
- `cmd`: 命令名称
- `args`: 命令参数（可选）

**返回：**
- `Promise<T>`: 命令执行结果

**示例：**

```typescript
// 无参数命令
const version = await invoke<string>('get_version');

// 带参数命令
const result = await invoke<number>('calculate', { a: 10, b: 20 });

// 复杂对象
interface FileInfo {
  path: string;
  size: number;
  modified: Date;
}

const file = await invoke<FileInfo>('read_file_info', { 
  path: '/path/to/file' 
});
```

### `listen<T>(event: string, callback: (payload: T) => void): () => void`

监听 Native 事件。

**参数：**
- `event`: 事件名称
- `callback`: 事件回调函数

**返回：**
- `() => void`: 取消监听的函数

**示例：**

```typescript
// 监听事件
const unlisten = listen<string>('log', (message) => {
  console.log('Log:', message);
});

// 稍后取消监听
unlisten();

// 监听复杂对象
interface Progress {
  current: number;
  total: number;
  percentage: number;
}

listen<Progress>('download_progress', (progress) => {
  console.log(`Progress: ${progress.percentage}%`);
});
```

### `once<T>(event: string, callback: (payload: T) => void): void`

监听 Native 事件（仅触发一次）。

**参数：**
- `event`: 事件名称
- `callback`: 事件回调函数

**示例：**

```typescript
once<void>('initialized', () => {
  console.log('App initialized!');
});

once<string>('error', (error) => {
  console.error('Error occurred:', error);
});
```

### `emit(event: string, payload?: unknown): Promise<void>`

发送事件到 Native（如果支持）。

**参数：**
- `event`: 事件名称
- `payload`: 事件数据（可选）

**示例：**

```typescript
// 发送简单事件
await emit('user_clicked');

// 发送带数据的事件
await emit('form_submitted', {
  username: 'john',
  email: 'john@example.com'
});
```

### `isQauriAvailable(): boolean`

检查 Qauri API 是否可用。

**返回：**
- `boolean`: 如果 API 可用返回 `true`

**示例：**

```typescript
if (isQauriAvailable()) {
  console.log('Running in Qauri WebView');
} else {
  console.log('Running in regular browser');
}
```

### `getVersion(): Promise<string | null>`

获取 Qauri API 版本。

**返回：**
- `Promise<string | null>`: 版本号，如果不可用返回 `null`

**示例：**

```typescript
const version = await getVersion();
if (version) {
  console.log('Qauri version:', version);
}
```

### `waitForQauri(timeout?: number): Promise<void>`

等待 Qauri API 准备就绪。

**参数：**
- `timeout`: 超时时间（毫秒），默认 5000ms

**返回：**
- `Promise<void>`: 当 API 准备就绪时 resolve

**示例：**

```typescript
try {
  await waitForQauri(3000);
  console.log('Qauri is ready!');
  
  // 现在可以安全地调用 API
  const data = await invoke('get_data');
} catch (error) {
  console.error('Qauri not available:', error);
}
```

## 错误处理

SDK 使用 `QauriError` 类来表示错误：

```typescript
import { invoke, QauriError } from '@qauri/api';

try {
  const result = await invoke('some_command');
} catch (error) {
  if (error instanceof QauriError) {
    console.error('Qauri Error:', error.message);
    console.error('Error Code:', error.code);
    console.error('Details:', error.details);
  } else {
    console.error('Unknown error:', error);
  }
}
```

### 错误代码

- `NOT_BROWSER`: 不在浏览器环境中
- `NOT_AVAILABLE`: Qauri API 不可用
- `NOT_SUPPORTED`: 功能不支持
- `TIMEOUT`: 操作超时

## 类型定义

SDK 提供完整的 TypeScript 类型定义：

```typescript
import type { QauriAPI, InvokeRequest, InvokeResponse, EmitEvent } from '@qauri/api';

// 扩展 Window 接口
declare global {
  interface Window {
    __QAURI__?: QauriAPI;
  }
}
```

## 最佳实践

### 1. 使用类型参数

```typescript
// ✅ 好的做法
interface User {
  id: number;
  name: string;
}
const user = await invoke<User>('get_user', { id: 1 });
console.log(user.name); // 类型安全

// ❌ 不好的做法
const user = await invoke('get_user', { id: 1 });
console.log(user.name); // 类型不安全
```

### 2. 检查 API 可用性

```typescript
// ✅ 好的做法
if (isQauriAvailable()) {
  const data = await invoke('get_data');
} else {
  // 提供降级方案
  const data = await fetch('/api/data').then(r => r.json());
}

// ❌ 不好的做法
const data = await invoke('get_data'); // 可能抛出错误
```

### 3. 清理事件监听器

```typescript
// ✅ 好的做法
const unlisten = listen('update', handleUpdate);

// 组件卸载时清理
onUnmount(() => {
  unlisten();
});

// ❌ 不好的做法
listen('update', handleUpdate); // 忘记清理，可能导致内存泄漏
```

### 4. 错误处理

```typescript
// ✅ 好的做法
try {
  const result = await invoke('risky_operation');
  handleSuccess(result);
} catch (error) {
  handleError(error);
}

// ❌ 不好的做法
const result = await invoke('risky_operation'); // 未处理错误
```

## 框架集成

### React

```typescript
import { useEffect, useState } from 'react';
import { invoke, listen } from '@qauri/api';

function App() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    // 调用命令
    invoke('get_data').then(setData);
    
    // 监听事件
    const unlisten = listen('update', (newData) => {
      setData(newData);
    });
    
    // 清理
    return () => unlisten();
  }, []);
  
  return <div>{JSON.stringify(data)}</div>;
}
```

### Vue 3

```vue
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { invoke, listen } from '@qauri/api';

const data = ref(null);
let unlisten: (() => void) | null = null;

onMounted(async () => {
  data.value = await invoke('get_data');
  
  unlisten = listen('update', (newData) => {
    data.value = newData;
  });
});

onUnmounted(() => {
  unlisten?.();
});
</script>

<template>
  <div>{{ data }}</div>
</template>
```

### Svelte

```svelte
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { invoke, listen } from '@qauri/api';

let data = null;
let unlisten: (() => void) | null = null;

onMount(async () => {
  data = await invoke('get_data');
  
  unlisten = listen('update', (newData) => {
    data = newData;
  });
});

onDestroy(() => {
  unlisten?.();
});
</script>

<div>{JSON.stringify(data)}</div>
```

## 开发

```bash
# 安装依赖
npm install

# 开发模式（监听文件变化）
npm run dev

# 构建
npm run build

# 类型检查
npm run type-check

# 代码检查
npm run lint

# 测试
npm run test
```

## 许可证

MIT

## 相关链接

- [Qauri Web Component](https://github.com/your-org/qauri-web-component)
- [文档](https://qauri.dev/docs)
- [示例](https://github.com/your-org/qauri-examples)


## Development

### Building

Build the package for distribution:

```bash
npm run build
```

This will generate:
- `dist/index.js` - CommonJS format
- `dist/index.mjs` - ES Module format
- `dist/index.d.ts` - TypeScript type definitions

### Development Mode

Watch mode for development:

```bash
npm run dev
```

### Type Checking

Run TypeScript type checking:

```bash
npm run type-check
```

### Linting

Check code style:

```bash
npm run lint
```

Fix linting issues:

```bash
npm run lint:fix
```

### Testing

Run tests:

```bash
npm test
```

## Publishing

1. Update version in `package.json`
2. Update `CHANGELOG.md` with changes
3. Build the package:
   ```bash
   npm run build
   ```
4. Publish to npm:
   ```bash
   npm publish
   ```

## Package Structure

```
@qauri/api/
├── dist/              # Built files (generated)
│   ├── index.js       # CommonJS bundle
│   ├── index.mjs      # ES Module bundle
│   └── index.d.ts     # TypeScript definitions
├── src/               # Source files
│   ├── index.ts       # Main entry point
│   └── types.ts       # Type definitions
├── package.json       # Package configuration
├── tsconfig.json      # TypeScript configuration
├── tsup.config.ts     # Build configuration
└── README.md          # This file
```

## Module Formats

This package supports both CommonJS and ES Modules:

### ES Modules (Recommended)

```javascript
import { invoke, listen } from '@qauri/api';
```

### CommonJS

```javascript
const { invoke, listen } = require('@qauri/api');
```

### TypeScript

Full TypeScript support with type definitions included:

```typescript
import { invoke, listen, QauriAPI } from '@qauri/api';
```

## Browser Compatibility

This package is designed to run in the Qauri WebView environment. It requires:

- Modern browser with ES2020 support
- `window.chrome.webview` (WebView2) or `window.cefQuery` (CEF)
- `crypto.randomUUID()` support

## License

MIT License - see [LICENSE](./LICENSE) file for details

## Contributing

Contributions are welcome! Please read the contributing guidelines in the main repository.

## Links

- [GitHub Repository](https://github.com/your-org/qauri-web-component)
- [Documentation](https://github.com/your-org/qauri-web-component#readme)
- [Issue Tracker](https://github.com/your-org/qauri-web-component/issues)
- [Changelog](./CHANGELOG.md)