npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

moonbridge-ts

v0.7.0

Published

MoonBridge IPC by WebSocket for node(server) and browser(client).

Downloads

1,484

Readme

moonbridge-ts

基于 MoonBridge 通信协议的 TypeScript IPC 库,面向 WebSocket 场景(浏览器、WPS 加载项、Node)。

1. moonbridge-ts 是什么?

moonbridge-ts 是 moonbridge IPC 的 TypeScript 实现,用于在不同进程/应用之间进行消息通信。

角色模型与 Flutter 版本一致:

  1. 客户端:发送请求、接收请求、处理回调、发布/订阅事件。
  2. 服务端:负责客户端注册、消息转发、会话建立、唤醒目标客户端。

当前 TS 版本传输层仅提供 WebSocket 通道(ws://)。

角色环境限制:

  1. server 角色需要监听端口,浏览器环境受限,MoonBridgeIpcServer 只能在 Node.js 环境使用。
  2. client 角色不需要监听端口,MoonBridgeIpcClient 可在 Node.js 和浏览器环境使用。

2. 当前提供的能力

  1. 支持单应用/多应用跨进程通信(经 IPC 服务端转发)。
  2. 支持 Request/Response/Error 三类消息与回调链路。
  3. 支持消息拦截(MessageInterceptor)。
  4. 支持连接状态监听(ConnectionObserver)。
  5. 支持心跳保活(默认开启,默认 3000ms)。
  6. 支持客户端身份认证(服务端白名单 ClientIdentityProvider)。
  7. 支持自动唤醒目标应用(autoLaunch + AppLauncher)。
  8. 支持 1 对 1 指定客户端通信。
  9. 支持 EventBus 广播通信。
  10. 支持端口候选策略(PortCandidateRule,服务端按规则尝试绑定端口,客户端按规则尝试连接端口)。
  11. 支持 WPS 场景 deeplink 唤醒(WpsAppLauncher)。

2.1 PortCandidateRule 作用说明

PortCandidateRule 用于在端口不确定或端口可能被占用时,给 server/client 提供一致的端口尝试规则:

  1. 服务端启动时,如果初始端口被占用,会按 PortCandidateRule 生成的有序端口列表继续尝试绑定,直到某个端口启动成功,或所有候选端口尝试完毕后启动失败。
  2. 客户端连接时,会按同一规则生成的有序端口列表依次尝试连接;每个端口都会执行连接和握手校验,直到连接并握手成功,或所有候选端口尝试完毕后连接失败。
  3. 该机制可避免“固定端口冲突导致整体不可用”,并确保 server 与 client 共享相同的端口探索顺序。

3. API 设计概览

客户端(MoonBridgeIpcClient

  • MoonBridgeIpcClient.builder()
  • connect(onResult?)
  • disconnect()
  • isConnected()
  • messenger.call(target).args(...).onError(...).strategy(...).send()
  • rpcServiceFactory.createService(ServiceType, clientName?)
  • eventBus.register(subscriber)
  • eventBus.unregister(subscriber)
  • eventBus.post(event)

服务端(MoonBridgeIpcServer

  • MoonBridgeIpcServer.builder()
  • start(): Promise<boolean>
  • stop(): Promise<void>
  • clientIdentityProviders([...])
  • messagePreprocessor(...)
  • onMessageReceived(...)
  • wakeAppInterceptor(...)

传输层(与 Flutter 抽象保持一致)

TransportClient 统一接口:

  • connectWithServer()
  • sendData(data)
  • onMessage(cb)
  • onErrorAndClose({ onError, onServerClose })
  • close()
  • isClientConnected

4. 接入流程与示例

4.1 安装

npm install moonbridge-ts

4.2 初始化服务端(Node)

import {
  MoonBridgeIpcServer,
  WebSocketServerEndpoint,
  ClientIdentity,
} from 'moonbridge-ts';

const endpoint = new WebSocketServerEndpoint({
  address: '0.0.0.0',
  port: 9091,
  path: '/ws',
  useTls: false,
});

const getClientIdentity = (clientName: string) => {
  switch (clientName) {
    case 'client_a':
      return new ClientIdentity('client_a');
    case 'client_b':
      return new ClientIdentity('client_b');
    default:
      return undefined;
  }
};

const server = MoonBridgeIpcServer.builder()
  .serverName('moonbridge_server')
  .useWebSocketChannel(endpoint)
  .clientIdentityProviders([getClientIdentity])
  .build(true);

const started = await server.start();
if (!started) {
  throw new Error('IPC server start failed');
}

4.3 初始化客户端

import {
  MoonBridgeIpcClient,
  WebSocketServerEndpoint,
  IpcMessageStrategy,
} from 'moonbridge-ts';

const client = MoonBridgeIpcClient.builder()
  .clientName('client_a')
  .useWebSocketChannel(
    new WebSocketServerEndpoint({
      address: '127.0.0.1',
      port: 9091,
      path: '/ws',
      useTls: false,
    }),
  )
  .messageStrategy(new IpcMessageStrategy(1, true))
  .build(true);

client.connect((isConnected, error) => {
  if (isConnected) {
    console.log('connect success');
    return;
  }
  console.error('connect failed', error);
});

4.4 客户端接收消息(模块方式)

import {
  Bridge,
  BridgeModule,
  MoonBridgeMethod,
  MoonBridgeModule,
  ResultCallback,
} from 'moonbridge-ts';

@MoonBridgeModule('CallPhone')
export class CallModule extends BridgeModule {
  constructor(bridge: Bridge) {
    super(bridge);
  }

  @MoonBridgeMethod('callWithCallback')
  callWithCallback(phoneNumber: string, callback: ResultCallback): void {
    console.log(`[MoonBridge] call: ${phoneNumber}`);
    callback.invoke(['callback - Success']);
  }
}

tsconfig.json 需开启:

{
  "experimentalDecorators": true,
  "emitDecoratorMetadata": true,
  "useDefineForClassFields": false
}

4.5 客户端发送消息

// 方式:call(推荐)
client.messenger
  .call({ clientName: 'client_b', moduleName: 'CallPhone', methodName: 'callWithCallback' })
  .args('0431-4610123', (response) => console.log('response:', response))
  .onError((error) => console.error('ipc error:', error))
  .send();

4.6 EventBus(订阅与发布)

import { Subscriber } from 'moonbridge-ts';
import { Event } from 'moonbridge-ts/moonbridge-ipc/general/message/event';

const subscriber = new Subscriber('TestEvent', (event) => {
  console.log('event:', event.type, event.data);
});

client.eventBus.register(subscriber);
await client.eventBus.post(new Event('TestEvent', 'client_a', { key: 'hello' }));

4.7 WPS 场景唤醒(可选)

import {
  MoonBridgeIpcClient,
  WebSocketServerEndpoint,
  WpsAppLauncher,
} from 'moonbridge-ts';

const client = MoonBridgeIpcClient.builder()
  .clientName('client_a')
  .useWebSocketChannel(
    new WebSocketServerEndpoint({
      address: '127.0.0.1',
      port: 9091,
      path: '/ws',
      useTls: false,
    }),
  )
  .appLauncher(
    new WpsAppLauncher({
      appUrl: 'server://',
      fallbackMethod: 'linkClick',
    }),
  )
  .build();

4.8 RPC 风格调用(装饰器 + rpcServiceFactory)

import {
  IpcCallRetry,
  IpcRemoteCall,
  IpcRemoteClient,
  IpcRequestJob,
  MoonBridgeIpcClient,
} from 'moonbridge-ts';

@IpcRemoteClient({ name: 'client_b' })
abstract class CallPhoneService {
  @IpcCallRetry({ retries: 3 })
  @IpcRemoteCall({ module: 'CallPhone', method: 'callPhone' })
  callPhone(_number: string): IpcRequestJob {
    return IpcRequestJob.stub();
  }

  @IpcRemoteCall({ module: 'CallPhone', method: 'callWithCallback' })
  callPhoneWithCallback(_number: string, _onResponse: (response: unknown[]) => void): IpcRequestJob {
    return IpcRequestJob.stub();
  }
}

const client = MoonBridgeIpcClient.builder()
  .clientName('client_a')
  // ...省略 useWebSocketChannel(...)
  .build(true);

const service = client.rpcServiceFactory.createService(CallPhoneService);

service?.callPhone('11111').onIpcError((error) => {
  console.error('IPC error:', error);
}).send();

service?.callPhoneWithCallback('176****0000', (response) => {
  console.log('response:', response);
}).onIpcError((error) => {
  console.error('IPC error:', error);
}).send();

5. 与 Flutter README 的对齐点

  1. 角色模型一致:客户端负责收发,服务端负责转发与会话构建。
  2. Builder 使用方式一致:链式配置后 build(...)
  3. 协议语义一致:握手、注册、请求、响应、错误、心跳、事件。
  4. 模块能力一致:@MoonBridgeModule + @MoonBridgeMethod
  5. 客户端身份机制一致:服务端白名单控制可接入客户端。

6. 重要差异与注意事项

  1. MoonBridgeIpcServer 只能在 Node.js 环境使用(浏览器无法监听端口)。
  2. MoonBridgeIpcClient 可在 Node.js 和浏览器环境使用(仅需主动连接,不需监听端口)。
  3. TS 端当前只支持 WebSocket,不支持 TCP Socket 客户端。
  4. useTls: truewss)当前未实现,需使用 ws
  5. 服务端如果不配置 clientIdentityProviders,客户端会因白名单校验失败而无法完成注册。
  6. 模块通过装饰器运行时注册,模块文件必须被加载(import)后才能生效。
  7. RPC 服务代理依赖装饰器元数据:服务类型需使用 @IpcRemoteClient@IpcRemoteCall 标注后再通过 client.rpcServiceFactory.createService(...) 创建。

7. 开发命令

npm run build
npm run test
npm run lint