@qauri/api
v0.1.2
Published
JavaScript/TypeScript SDK for Qauri Web Component
Maintainers
Readme
@qauri/api
JavaScript/TypeScript SDK for Qauri Web Component - 类型安全的 Native 通信 API
安装
npm install @qauri/api
# or
yarn add @qauri/api
# or
pnpm add @qauri/api快速开始
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)
import { invoke, listen } from '@qauri/api';
// 调用命令
const data = await invoke('get_data');
// 监听事件
const unlisten = listen('update', (payload) => {
console.log('Update:', payload);
});JavaScript (CommonJS)
const { invoke, listen } = require('@qauri/api');
// 使用方式相同API 文档
invoke<T>(cmd: string, args?: unknown): Promise<T>
调用 Native 命令并返回结果。
参数:
cmd: 命令名称args: 命令参数(可选)
返回:
Promise<T>: 命令执行结果
示例:
// 无参数命令
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: 取消监听的函数
示例:
// 监听事件
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: 事件回调函数
示例:
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: 事件数据(可选)
示例:
// 发送简单事件
await emit('user_clicked');
// 发送带数据的事件
await emit('form_submitted', {
username: 'john',
email: '[email protected]'
});isQauriAvailable(): boolean
检查 Qauri API 是否可用。
返回:
boolean: 如果 API 可用返回true
示例:
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
示例:
const version = await getVersion();
if (version) {
console.log('Qauri version:', version);
}waitForQauri(timeout?: number): Promise<void>
等待 Qauri API 准备就绪。
参数:
timeout: 超时时间(毫秒),默认 5000ms
返回:
Promise<void>: 当 API 准备就绪时 resolve
示例:
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 类来表示错误:
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 类型定义:
import type { QauriAPI, InvokeRequest, InvokeResponse, EmitEvent } from '@qauri/api';
// 扩展 Window 接口
declare global {
interface Window {
__QAURI__?: QauriAPI;
}
}最佳实践
1. 使用类型参数
// ✅ 好的做法
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 可用性
// ✅ 好的做法
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. 清理事件监听器
// ✅ 好的做法
const unlisten = listen('update', handleUpdate);
// 组件卸载时清理
onUnmount(() => {
unlisten();
});
// ❌ 不好的做法
listen('update', handleUpdate); // 忘记清理,可能导致内存泄漏4. 错误处理
// ✅ 好的做法
try {
const result = await invoke('risky_operation');
handleSuccess(result);
} catch (error) {
handleError(error);
}
// ❌ 不好的做法
const result = await invoke('risky_operation'); // 未处理错误框架集成
React
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
<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
<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>开发
# 安装依赖
npm install
# 开发模式(监听文件变化)
npm run dev
# 构建
npm run build
# 类型检查
npm run type-check
# 代码检查
npm run lint
# 测试
npm run test许可证
MIT
相关链接
Development
Building
Build the package for distribution:
npm run buildThis will generate:
dist/index.js- CommonJS formatdist/index.mjs- ES Module formatdist/index.d.ts- TypeScript type definitions
Development Mode
Watch mode for development:
npm run devType Checking
Run TypeScript type checking:
npm run type-checkLinting
Check code style:
npm run lintFix linting issues:
npm run lint:fixTesting
Run tests:
npm testPublishing
- Update version in
package.json - Update
CHANGELOG.mdwith changes - Build the package:
npm run build - Publish to npm:
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 fileModule Formats
This package supports both CommonJS and ES Modules:
ES Modules (Recommended)
import { invoke, listen } from '@qauri/api';CommonJS
const { invoke, listen } = require('@qauri/api');TypeScript
Full TypeScript support with type definitions included:
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) orwindow.cefQuery(CEF)crypto.randomUUID()support
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please read the contributing guidelines in the main repository.
