@northsea4/proxy-service
v1.0.2
Published
A type-safe wrapper around the web extension messaging APIs that lets you call a function from anywhere, but execute it in the background. Forked from @webext-core/proxy-service with sender parameter support.
Maintainers
Readme
@northsea4/proxy-service
基于 @webext-core/proxy-service 的二次开发版本,支持 ServiceCallContext 上下文对象,提供更丰富的调用上下文信息。
类型安全的浏览器扩展消息传递 API 封装,允许你在任何地方调用函数,但在后台脚本中执行。支持所有主流浏览器(Chrome、Firefox、Safari 等)。
主要特性
- 支持 ServiceCallContext:服务方法可获取完整的调用上下文(sender、requestId、timestamp、metadata 等)
- 类型安全的服务注册与调用
- 自动注入 context,无需手动传递
安装
pnpm add @northsea4/proxy-service快速开始
1. 定义服务
// services/tab-service.ts
import { defineProxyService, type ServiceCallContext } from '@northsea4/proxy-service'
class TabService {
async getCurrentTabInfo(context?: ServiceCallContext) {
return {
tabId: context?.sender?.tab?.id,
url: context?.sender?.tab?.url,
title: context?.sender?.tab?.title,
requestId: context?.requestId,
timestamp: context?.timestamp
}
}
async closeTab(tabId: number, context?: ServiceCallContext) {
console.log('closeTab called from:', context?.sender?.tab?.url)
await browser.tabs.remove(tabId)
}
}
export const [registerTabService, getTabService] = defineProxyService(
'tab-service',
() => new TabService()
)2. 注册服务(Background)
// background/index.ts
import { registerTabService } from '@/services/tab-service'
registerTabService()3. 使用服务(任何地方)
// content-script.ts 或 popup.ts
import { getTabService } from '@/services/tab-service'
const tabService = getTabService()
// context 会自动注入
const tabInfo = await tabService.getCurrentTabInfo()
console.log('Current tab:', tabInfo)
await tabService.closeTab(tabInfo.tabId)ServiceCallContext 类型
import type { ServiceCallContext } from '@northsea4/proxy-service'
interface ServiceCallContext {
sender: Browser.Runtime.MessageSender
timestamp?: number
requestId?: string
metadata?: Record<string, any>
}服务方法的最后一个参数应为 context?: ServiceCallContext,并通过 context?.sender 获取调用方信息。
常见场景示例
1. 获取调用者信息
class ContextService {
async getCallerInfo(context?: ServiceCallContext) {
return {
fromTab: context?.sender?.tab?.id,
fromUrl: context?.sender?.tab?.url,
fromFrame: context?.sender?.frameId,
requestId: context?.requestId,
timestamp: context?.timestamp
}
}
}2. 权限检查
class PermissionService {
async checkPermission(action: string, context?: ServiceCallContext) {
const url = context?.sender?.tab?.url
if (url?.startsWith('https://trusted-domain.com')) {
return true
}
return false
}
}3. 日志追踪
class LoggingService {
async logAction(action: string, data: any, context?: ServiceCallContext) {
console.log({
requestId: context?.requestId,
timestamp: context?.timestamp,
caller: context?.sender?.tab?.title,
action,
data
})
}
}TypeScript 类型支持
服务方法签名应为:
import type { ServiceCallContext } from '@northsea4/proxy-service'
interface MyService {
method1(arg1: string, context?: ServiceCallContext): Promise<void>
method2(arg1: number, arg2: string, context?: ServiceCallContext): Promise<number>
}高级功能
flattenPromise
简化异步依赖的处理:
import { flattenPromise } from '@northsea4/proxy-service'
function createService(dbPromise: Promise<IDBDatabase>) {
const db = flattenPromise(dbPromise)
return {
async getData(context?: ServiceCallContext) {
return await db.get('store', 'key')
}
}
}defineProxyService
简化服务定义和类型推导:
// services/my-service.ts
import { defineProxyService, type ServiceCallContext } from '@northsea4/proxy-service'
class MyService {
async add(x: number, y: number, context?: ServiceCallContext) {
return x + y
}
}
export const [registerMyService, getMyService] = defineProxyService(
'my-service',
() => new MyService()
)
// background/index.ts
registerMyService()
// content-script.ts
const myService = getMyService()
await myService.add(1, 2)配置选项
支持 @webext-core/messaging 的所有配置项:
import { registerService, createProxyService } from '@northsea4/proxy-service'
const config = {
logger: console // 自定义日志记录器
}
registerService('my-service', myService, config)
const proxy = createProxyService('my-service', config)开发
# 构建
pnpm build
# 开发模式(监听文件变化)
pnpm devLicense
MIT
致谢
本项目基于 @webext-core/proxy-service 开发,感谢原作者的优秀工作。
