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

@sl-theia/theia-socket-vue3

v0.1.2

Published

Vue3 adapter for Theia Socket

Downloads

310

Readme

@sl-theia/theia-socket-vue3

Vue3 版本的 Theia Socket 客户端封装。它基于 @sl-theia/socket-api-core,提供和 React 版本 @sl-theia/theia-socket-io-client 对齐的 socket 能力,并用 Vue3 的 provide/inject 与组合式 API 封装常用接入方式。

安装

npm install @sl-theia/theia-socket-vue3

或使用 pnpm:

pnpm add @sl-theia/theia-socket-vue3

本包要求项目中已安装 Vue3:

pnpm add vue

快速开始

1. 在应用入口挂载 Provider

TheiaSocketProvider 会创建 TheiaSocketClient 实例,并通过 Vue 的依赖注入提供给子组件。所有使用 useSocketuseTheiaSocketinjectSocket 的组件都必须放在 Provider 子树中。

<template>
  <TheiaSocketProvider :config="socketConfig">
    <RouterView />
  </TheiaSocketProvider>
</template>

<script setup lang="ts">
import {
  TheiaSocketProvider,
  type theiaSocketClientCfg,
} from '@sl-theia/theia-socket-vue3';

const socketConfig: theiaSocketClientCfg = {
  userRole: 'WebController',
  userGroup: 'default',
  hostname: window.location.hostname,
  port: '8070',
  namespace: '/TheiaVis',
  devTool: true,
  webApiJson: {},
};
</script>

2. 在页面中使用 useSocket

useSocket 是推荐用法。它会根据 name 创建当前页面或组件对应的实体 facade,返回的对象只暴露页面常用 socket 方法。

<template>
  <button type="button" @click="queryApis">查询 API</button>
  <button type="button" @click="emitNativeApi">调用 NativeAPI</button>
</template>

<script setup lang="ts">
import { onBeforeUnmount } from 'vue';
import { useSocket } from '@sl-theia/theia-socket-vue3';

const socket = useSocket({ name: 'DashboardPage' });

const offConnect = socket.onConnect((msg) => {
  console.log('socket connected:', msg);
});

const offQueryResponse = socket.onQueryResponse((msg) => {
  console.log('query response:', msg);
});

function queryApis() {
  socket.query();
}

function emitNativeApi() {
  socket.theiaEmit({
    Entity: 'BP_PointManager_2',
    NativeAPI: {
      API_ShowPoint: {
        Description: 'Show point',
        Parms: {
          show: true,
          type: '',
        },
      },
    },
  });
}

onBeforeUnmount(() => {
  offConnect();
  offQueryResponse();
});
</script>

3. 注册 WebAPI

WebAPI 是 Web 侧暴露给 Theia/Native 侧调用的 API。注册时建议在组件卸载时注销,避免页面重新进入后重复注册。

<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue';
import { useSocket } from '@sl-theia/theia-socket-vue3';

type SetCountParams = {
  count?: number;
};

const count = ref(0);
const socket = useSocket({ name: 'CounterPage' });

function API_SET_COUNT(params: SetCountParams = {}) {
  count.value += Number(params.count || 0);
}

socket.registerAPI('API_SET_COUNT', API_SET_COUNT);

onBeforeUnmount(() => {
  socket.unregisterAPI('API_SET_COUNT');
});
</script>

调用 WebAPI 时,Entity 要和注册 API 时的实体名一致:

socket.theiaEmit({
  Entity: 'CounterPage',
  WebAPI: {
    API_SET_COUNT: {
      Description: 'Update counter',
      Parms: {
        count: 1,
      },
    },
  },
});

在 vis/umi Vue3 项目中使用

如果项目通过 @sl-theia/vis@umijs/preset-vue 接入,可以直接在 .umirc.ts 中开启 theiaSocket。插件会识别 Vue3 项目,并自动选择 @sl-theia/theia-socket-vue3

import { defineConfig } from '@sl-theia/vis';

export default defineConfig({
  presets: ['@umijs/preset-vue'],
  vue: {},
  theiaSocket: {
    userRole: 'webUI',
    userGroup: 'default',
    hostname: '127.0.0.1',
    port: '8070',
    namespace: '/TheiaVis',
    devTool: true,
    autoRegister: {},
  },
});

开启插件后,可以从 umi 导入运行时生成的 socket 工具:

<script setup lang="ts">
import { onBeforeUnmount } from 'vue';
// 由 theiaSocket 运行时插件生成。
import { socketEmiter, useSocket } from 'umi';

const socket = useSocket({ name: 'VueSocketPage' });

function API_SET_COUNT(params: { count?: number } = {}) {
  console.log('receive count:', params.count);
}

socket.registerAPI('API_SET_COUNT', API_SET_COUNT);

function emitApiSetCount() {
  socketEmiter.theiaEmit({
    Entity: 'VueSocketPage',
    WebAPI: {
      API_SET_COUNT: {
        Parms: {
          count: 1,
        },
      },
    },
  });
}

onBeforeUnmount(() => {
  socket.unregisterAPI('API_SET_COUNT');
});
</script>

API

TheiaSocketProvider

Provider 组件,用于创建并注入 socket 实例。

| 属性 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | config | theiaSocketClientCfg | 是 | socket 连接配置 |

config 常用字段:

| 字段 | 类型 | 必填 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | hostname | string | 否 | window.location.hostname127.0.0.1 | socket 服务地址 | | port | string | 否 | 8070 | socket 服务端口 | | namespace | string | 否 | /TheiaVis | socket 命名空间 | | userRole | string | 是 | - | 当前 Web 客户端注册角色 | | userGroup | string | 否 | - | 当前 Web 客户端分组 | | devTool | boolean | 否 | false | 是否开启调试工具 | | webApiJson | object | 否 | {} | WebAPI 注册信息,通常由 vis 插件生成 |

useSocket

function useSocket(config?: { name?: string }): SocketFacade;

推荐在业务页面和组件中使用。name 会作为当前实体名参与 WebAPI 注册和消息发送。

const socket = useSocket({ name: 'HomePage' });

如果不传 name,运行时会输出错误日志,匿名函数场景下建议显式传入。

useTheiaSocket

function useTheiaSocket(): TheiaSocketClient;

返回完整的 TheiaSocketClient 实例,适合需要访问底层 client、entities 或 socket 实例的高级场景。

const client = useTheiaSocket();
client.query();

injectSocket

function injectSocket(config?: { name?: string }): (WrappedComponent: Component) => Component;

injectSocket 会把 socket 注入到被包装组件的 props 中,主要用于需要沿用 React 版本高阶组件风格的场景。

import { defineComponent, type PropType } from 'vue';
import {
  injectSocket,
  type SocketFacade,
} from '@sl-theia/theia-socket-vue3';

const RawPanel = defineComponent({
  name: 'RawPanel',
  props: {
    socket: {
      type: Object as PropType<SocketFacade>,
      required: true,
    },
  },
  setup(props) {
    props.socket.query();

    return () => null;
  },
});

export default injectSocket({ name: 'RawPanel' })(RawPanel);

createTheiaSocket

function createTheiaSocket(config: theiaSocketClientCfg): TheiaSocketClient;

手动创建 socket client。一般情况下优先使用 TheiaSocketProvider,只有在运行时工具、测试或非组件环境中才需要直接创建。

import { createTheiaSocket } from '@sl-theia/theia-socket-vue3';

const socket = createTheiaSocket({
  userRole: 'manual-client',
  webApiJson: {},
});

provideTheiaSocket

function provideTheiaSocket(config: theiaSocketClientCfg): TheiaSocketClient;

在自定义 Provider 中创建并注入 socket。

import { defineComponent, h } from 'vue';
import { provideTheiaSocket } from '@sl-theia/theia-socket-vue3';

export default defineComponent({
  setup(_, { slots }) {
    const socket = provideTheiaSocket({
      userRole: 'custom-provider',
      webApiJson: {},
    });

    return () => slots.default?.();
  },
});

SocketFacade 方法

useSocketinjectSocket 返回的 socket 都是 SocketFacade

| 方法 | 说明 | 返回值 | | --- | --- | --- | | registerAPI(apiName, callback) | 注册当前实体的 WebAPI | void | | unregisterAPI(apiName) | 注销当前实体的 WebAPI,支持字符串或字符串数组 | void | | query(entityName?) | 查询已注册的实体和 API 信息 | void | | theiaEmit(msg) | 发送 Msg 消息,可调用 NativeAPI 或 WebAPI | void | | theiaOn(callback) | 监听 Msg 消息 | () => void | | theiaOnce(callback) | 只监听一次 Msg 消息 | void | | onConnect(callback) | 监听客户端连接广播 | () => void | | onDisconnect(callback) | 监听客户端断开广播 | () => void | | onQueryResponse(callback) | 监听 query 的响应 | () => void | | onNativeAPIResponse(callback) | 监听 NativeAPI 调用响应 | () => void | | onNativeAPIResponseAsync(callback) | 监听 NativeAPI 异步响应 | () => void | | onWebAPIResponse(callback) | 监听 WebAPI 调用响应 | () => void | | on(eventName, callback) | 监听 socket 原生事件 | () => void |

事件监听方法通常会返回取消监听函数,建议在 onBeforeUnmount 中执行。

const offMsg = socket.theiaOn((msg) => {
  console.log('Msg:', msg);
});

onBeforeUnmount(() => {
  offMsg();
});

消息格式示例

调用 NativeAPI

socket.theiaEmit({
  Entity: 'BP_PointManager_2',
  NativeAPI: {
    API_ShowPoint: {
      Description: 'Show point',
      Parms: {
        show: true,
        type: '',
      },
    },
  },
});

调用 WebAPI

socket.theiaEmit({
  Entity: 'CounterPage',
  WebAPI: {
    API_SET_COUNT: {
      Description: 'Set count',
      Parms: {
        count: 10,
      },
    },
  },
});

监听调用结果

const offNativeResponse = socket.onNativeAPIResponse((msg) => {
  console.log('NativeAPI response:', msg);
});

const offWebResponse = socket.onWebAPIResponse((msg) => {
  console.log('WebAPI response:', msg);
});

onBeforeUnmount(() => {
  offNativeResponse();
  offWebResponse();
});

导出内容

export {
  Entity,
  Provider,
  SocketContext,
  TheiaSocketClient,
  TheiaSocketProvider,
  createSocketFacade,
  createTheiaSocket,
  injectSocket,
  provideTheiaSocket,
  socketKey,
  useSocket,
  useTheiaSocket,
};
export type {
  EntityConfig,
  InjectSocketProps,
  SocketFacade,
  injectSocketProps,
  theiaSocketClientCfg,
};

ProviderTheiaSocketProvider 的别名,SocketContextsocketKey 的别名,用于对齐 React 版本 API 命名。

打包产物

包内同时提供 CJS、ESM 和独立类型声明:

{
  "main": "dist/cjs/index.js",
  "module": "dist/esm/index.js",
  "types": "dist/types/index.d.ts"
}

发布文件只包含运行时 JS、类型声明,以及用于导出边界和模块类型声明的 package.json 文件,不会发布 .map 文件。

常见问题

useSocket 报错 TheiaSocketClient has not been provided.

说明当前组件没有被 TheiaSocketProvider 包裹。请把 Provider 放在应用入口或当前页面父级。

页面重复进入后 WebAPI 被重复调用.

通常是注册后没有注销。请在 onBeforeUnmount 中调用 unregisterAPI,并清理事件监听返回的 off 函数。

Umi/vis 项目里应该从哪里导入 useSocket.

开启 theiaSocket 插件后,业务页面推荐从 umi 导入:

import { socketEmiter, useSocket } from 'umi';

独立 Vue3 项目或非 Umi 项目从本包导入:

import { TheiaSocketProvider, useSocket } from '@sl-theia/theia-socket-vue3';