Skip to content

chen99-long/inject-content-message

Repository files navigation

Inject Content Message

一个简单易用的浏览器事件通信库,支持类型安全的事件发送和监听,以及异步回调。

特性

  • 类型安全的事件通信
  • 支持异步回调
  • 简单直观的 API
  • 支持浏览器插件环境
  • 支持普通网页环境

安装

NPM 安装

npm install inject-content-message

CDN 引入

你也可以通过 script 标签直接引入:

<!-- 引入完整版本 -->
<script src="https://unpkg.com/inject-content-message@1.2.0/dist/index.umd.js"></script>

<!-- 或引入压缩版本 -->
<script src="https://unpkg.com/inject-content-message@1.2.0/dist/index.umd.min.js"></script>

使用方法

ES 模块方式

import { defineEventMessaging } from 'inject-content-message';

// 定义事件协议
interface ProtocolMap {
  // 普通事件
  log: (message: string) => void;
  // 带回调的事件
  getData: (id: number) => Promise<{ id: number; value: string }>;
}

// 创建事件通信实例
const { sendEvent, listenEvent, listenEventOnce } = defineEventMessaging<ProtocolMap>();

// 监听事件
const unsubscribe = listenEvent('getData', async (id) => {
  const data = await fetchData(id);
  return data;
});

// 取消监听(防止内存泄漏)
unsubscribe();

// 发送普通事件
sendEvent('log', 'Hello World');

// 发送带回调的事件(支持任意类型数据)
const result = await sendEvent('getData', 123);
console.log(result); // { id: 123, value: 'some data' }

// 一次性监听事件(默认10秒超时)
const eventData = await listenEventOnce('getData');
if (eventData !== null) {
  console.log('收到事件数据:', eventData);
} else {
  console.log('监听超时');
}

// 一次性监听事件(自定义超时时间)
const eventData2 = await listenEventOnce('getData', 5000); // 5秒超时

Script 标签方式

通过 script 标签引入后,库提供了两种使用方式:

方式一:命名空间访问(推荐)

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/inject-content-message@1.2.0/dist/index.umd.min.js"></script>
</head>
<body>
    <script>
        // 通过 InjectContentMessage 命名空间访问
        const { defineEventMessaging } = InjectContentMessage;

        // 创建事件通信实例
        const { sendEvent, listenEvent, listenEventOnce } = defineEventMessaging();

        // 使用方式与 ES 模块完全相同
        const unsubscribe = listenEvent('getData', async (id) => {
            return { id: id, value: `data for ${id}` };
        });

        sendEvent('getData', 123).then(result => {
            console.log(result); // { id: 123, value: 'data for 123' }
        });
    </script>
</body>
</html>

方式二:直接从 window 访问

<script src="https://unpkg.com/inject-content-message@1.2.0/dist/index.umd.min.js"></script>
<script>
    // defineEventMessaging 函数会自动挂载到 window 对象
    const { sendEvent, listenEvent, listenEventOnce } = defineEventMessaging();

    // 使用方式完全相同
    listenEvent('log', (message) => {
        console.log('收到消息:', message);
    });

    sendEvent('log', 'Hello World!');
</script>

构建版本

该库提供了多种构建版本以适应不同的使用场景:

  • ES Module (dist/index.esm.js) - 用于现代打包工具(webpack、rollup、vite等)
  • CommonJS (dist/index.cjs.js) - 用于 Node.js 环境
  • UMD (dist/index.umd.js) - 用于浏览器 script 标签引入
  • UMD Minified (dist/index.umd.min.js) - 压缩版本,适合生产环境

API

defineEventMessaging(debug?: boolean)

创建一个事件通信实例,返回 sendEventlistenEventlistenEventOnce 方法。

参数:

  • debug (可选): 是否启用调试日志,默认为 false

sendEvent(name: K, data: Parameters<T[K]>[0], options?: { timeout?: number })

发送一个事件并等待回调。支持任意类型的数据,如果监听器返回值则返回该值,否则在超时后返回 undefined。

参数:

  • name: 事件名称
  • data: 要发送的数据
  • options (可选): 配置选项
    • timeout (可选): 超时时间(毫秒),默认为 5000(5秒)

使用示例:

// 使用默认超时(5秒)
const result1 = await sendEvent('getData', 123);

// 使用自定义超时(2秒)
const result2 = await sendEvent('getData', 123, { timeout: 2000 });

// 使用长超时(10秒)
const result3 = await sendEvent('getData', 123, { timeout: 10000 });

兼容性: 仍然支持旧的 API sendEvent(name, ...args),但推荐使用新的 API 以获得更好的类型安全和超时控制。

listenEvent(name: K, callback: T[K])

监听一个事件,返回取消监听的函数。如果事件需要返回结果,处理函数可以返回一个值或 Promise。

返回值: 返回一个函数,调用该函数可以取消事件监听,防止内存泄漏。

使用示例:

// 监听事件
const unsubscribe = listenEvent('getData', async (id) => {
  const data = await fetchData(id);
  return data;
});

// 取消监听(防止内存泄漏)
unsubscribe();

listenEventOnce(name: K, timeout?: number)

监听一个事件一次,在事件触发或超时后自动取消监听。

参数:

  • name: 事件名称
  • timeout (可选): 超时时间(毫秒),默认为 10000(10秒)

返回值: 返回一个 Promise,成功时解析事件数据,超时时解析为 null

使用示例:

// 监听事件一次(默认10秒超时)
const eventData = await listenEventOnce('getData');
if (eventData !== null) {
  console.log('收到事件数据:', eventData);
} else {
  console.log('监听超时');
}

// 监听事件一次(自定义超时时间)
const eventData2 = await listenEventOnce('getData', 5000); // 5秒超时

更新日志

v1.5.0

  • 新功能: sendEvent 支持自定义超时时间
  • ⏰ 新增 timeout 选项,可以自定义超时时间(默认仍为 5 秒)
  • 🔧 保持向后兼容,旧的 API 仍然可用
  • 📝 更新了 TypeScript 类型定义和文档

v1.4.0

  • 新功能: 添加 listenEventOnce 一次性监听功能
  • ⏰ 支持自定义超时时间,默认 10 秒
  • 🔧 事件触发或超时后自动取消监听,避免内存泄漏
  • 📝 完善了 TypeScript 类型定义

v1.3.0

  • 🐛 重大修复: 修复了 sendEvent 不支持非对象类型数据回调的 bug
  • ✨ 现在 sendEvent 支持发送任意类型数据(字符串、数字、布尔值等)并获得回调
  • 🔧 sendEvent 现在总是返回 Promise,提供一致的 API 体验
  • ⏱️ 添加了 5 秒超时机制,避免无限等待

v1.2.2

  • 🐛 修复了当发送非对象类型数据时出现的 Cannot use 'in' operator 错误
  • ✅ 现在可以安全地发送字符串、数字、布尔值等原始类型数据
  • 🔧 改进了类型检查逻辑,确保只有对象类型才检查 _callbackId 属性

v1.2.1

  • 📦 优化构建配置

v1.2.0

  • 🎉 初始版本发布

License

MIT

About

使用浏览器的CustomEvent特性实现便捷的事件通讯

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published