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

asaihost-vue

v0.0.8

Published

AsaiWeb CMS Vue 3 host plugin — engine runtime, UI shell, directives, and webmodel bootstrap

Readme

asaihost-vue

Vue 3 应用宿主框架:引擎运行时(API / WebSocket / AES)、UI 壳层组件、自定义指令,以及基于 public/webmodel/ 的配置引导链。

| 项 | 值 | |----|-----| | npm 包名 | asaihost-vue | | 插件入口 | index.ts(monorepo 源码)/ dist/asaihost-vue.es.js(发布后) | | 运行时配置根 | public/webmodel/ + cfg.js | | 对等依赖 | vue ^3.4 |

目录结构

asaihost-vue/
├── index.ts              # 包入口(re-export 插件 + 类型)
├── package.json
├── vite.config.ts
└── src/
    ├── index.ts          # Vue 插件 install(glob 注册 asengine / asui / asdirectives)
    ├── types.ts
    ├── asengine/         # API、WS、AES、provide、路由引擎
    ├── asui/             # 全局 UI 组件
    └── asdirectives/     # v-drag、v-userlevel 等指令

目录

  1. 快速开始
  2. 在 AsaiCMS monorepo 内使用
  3. 独立项目集成
  4. LibInit 与 install 约定
  5. 配置文件总览
  6. 运行时上下文 ujt
  7. 扩展业务模块
  8. 核心组件与指令
  9. 开发与发布 npm 包
  10. 约束与后端对应

快速开始

安装

npm install asaihost-vue vue
# 或
yarn add asaihost-vue vue
pnpm add asaihost-vue vue

@noble/ciphers 已作为本包依赖声明(AES-GCM HTTP 降级路径);无需单独安装。

最小集成(main.ts)

import { createApp } from 'vue';
import App from './App.vue';
import LibInit from './lib/LibInit';           // 见下文「LibInit」
import AsaiHostVue from 'asaihost-vue';

const app = createApp(App);
const { lib } = LibInit();

app.use(AsaiHostVue, lib);   // 必须最先安装
app.mount('#app');

静态资源配置

index.html 引入 cfg.js,并将 webmodel/ 目录放到 Vite public/ 下(详见 cfg.js)。


在 AsaiCMS monorepo 内使用

本仓库 webclient 通过路径别名引用插件源码,开发时无需先 npm pack

// webclient/src/utils/index.ts
import AsaiHostVue from '../plugs/asaihost-vue';

本地构建 npm 产物:

cd webclient/src/plugs/asaihost-vue
npm install
npm run build

独立项目集成

1. Vite 项目

确保 vite.config 能处理本包内的 .vueimport.meta.glob(默认 @vitejs/plugin-vue 即可)。

若从 npm 安装(使用 dist/ 预构建产物),直接 import AsaiHostVue from 'asaihost-vue'

若通过 git submodule / 拷贝源码 联调,可在 package.json 使用 link:file: 指向插件目录,并优先解析 development 条件到 src/index.ts

2. 复制 LibInit

宿主插件不内置 LibInit——它由业务项目提供 loadts / loadvue / loadv 三个加载器。可从 AsaiCMS webclient/src/lib/LibInit.ts 复制或按需裁剪。

3. 环境变量(.env)

VITE_WEB_PATH=/
VITE_ASAI_AES_KEYBASE64=<与后端 ASAI_AES_KEYBASE64 一致>

4. TypeScript

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "types": ["vite/client"]
  }
}

可从本包导入类型:

import type { VueHostLibLoader, AsaiHostVuePlugin } from 'asaihost-vue';

LibInit 与 install 约定

AsaiHostVue.install(app, lib) 在启动时注册三类资源:

| 步骤 | lib 方法 | 注册内容 | |------|----------|----------| | 1 | loadts | $engineasaiasengine/common/*.tsuseApi / useWs / useAES / useProvide 等 | | 2 | loadvue | asui/*/*.vue 全局组件(懒加载) | | 3 | loadv | asdirectives/*/index.ts 自定义指令 |

lib 最少需提供:

interface VueHostLibLoader {
  loadts(params: { app; key; eager?; files }): void;
  loadvue(params: { app; eager?; loadfn?; files }): unknown;
  loadv(params: { app; eager?; files }): void;
  loadfn?: { fnvue: typeof defineAsyncComponent };
}

安装顺序:AsaiHostVue 必须早于业务 lib-install 与其它插件

启动链

app.use(AsaiHostVue, lib)
  → AsaiInitPage.onMounted
      → initweb($vueProxy)     // dirglobal + dirmodel + configrouter + server.json
      → useApi('web') / useWs('web')
  → AsaiWebServer → AsaiComponent(hash 选模块)
  → AsaiWebModule → useInitApp(module) → RouterView

配置文件总览

本插件不读取单一 JSON,而是通过 initweb() 按固定顺序加载一组配置文件,合并到运行时 ujtwindow.$GYS.ujt):

index.html
  └── cfg.js                    → window.$CFG(静态资源路径、标题)
        ↓
initweb() 加载顺序:
  1. sys/dirglobal.json         → 索引全局 sys 片段
  2. sys/dirmodel.json          → 索引模型 JSON
  3. asai/model/configrouter.json → 路由 / 权限(合并各模块 configrouter)
  4. sys/server.json            → API / WS 连接表 → $global.link
  5. 各 webmodel 子文件         → $model.data / $global.sys
  6. .env (VITE_*)              → AES 密钥等构建期变量

| 文件 | 典型路径 | 进 Git | 挂载到 | |------|----------|--------|--------| | cfg.js | public/webmodel/files/cfg.js | ✅ | window.$CFG$global.$cfg | | dirglobal.json | public/webmodel/sys/dirglobal.json | ✅ | $global.sys(合并) | | dirmodel.json | public/webmodel/sys/dirmodel.json | ✅ | $model.data.sys | | configrouter.json | public/webmodel/sys/asai/model/configrouter.json + 各模块 | ✅ | $global.sys.router | | server.json | public/webmodel/sys/server.json | ✅ | $global.link.api / .ws | | sysweb.json 等 | 由 dirglobal / dirmodel 索引 | ✅ | $global.sys.* | | .env.development | 项目根 .env.development | ✅ 模板 | import.meta.env.VITE_* |

静态资源默认通过 AsaiModel.fetchPublic('webmodel/...') 加载(相对 webpath)。


完整配置 — cfg.js(页面级)

index.html<script src="webmodel/files/cfg.js"> 引入:

window.$CFG = {
  webpath: '/',   // 静态资源根;设为 '/' 时需与构建 base 一致
  title: '',      // 空则 fallback 到语言包 configweb.webtit
};
window.$CFG.icon = window.$CFG.webpath + 'webmodel/files/favicon.ico';
window.$CFG.logo = window.$CFG.webpath + 'webmodel/files/logo.png';
if (window.$CFG.title) {
  document.title = window.$CFG.title;
  document.querySelector('link[rel="icon"]').href = window.$CFG.icon;
}

| 字段 | 说明 | |------|------| | webpath | 静态资源前缀;影响 getWebPath()AsSvg 等 | | title | 浏览器标题(优先于语言包) | | logo / icon | 由脚本派生,加载页/错误页使用 |


完整配置 — dirglobal.json(系统引导索引)

{
  "dir": [
    "asai/global/sysweb.json",
    "asai/global/syspath.json",
    "setting/settingsys.json",
    "setting/settingweb.json"
  ]
}
  • initweb() 读取 dir 数组中每个 JSON,浅合并$global.sys
  • 业务项目按需增删路径;插件本身只约定 sysweb.json 为核心全局项。

完整配置 — sysweb.json(全局行为,合成示例)

路径:public/webmodel/sys/asai/global/sysweb.json

{
  "webver": "2.0",
  "dttm": "2025-02-28 10:10:10",
  "env": "dev",
  "devlevel": 2,
  "catcherror": 0,
  "zoomid": "asaiwebzoomid",
  "zoomwidth": 1920,
  "zoomheight": 1200,
  "tmbeat": 0,
  "onweblog": true,
  "onwebsitemap": false,
  "onwebws": true,
  "onckuseronline": true,
  "onconsole": 1,
  "tyrobot": "web",
  "local": {
    "lang": "as-lang",
    "theme": "as-theme"
  },
  "aes": {
    "lv": 1,
    "aad": "asai aes aad",
    "keylength": 256,
    "ivlength": 12,
    "algorithm": "AES-GCM"
  }
}

| 字段 | 说明 | |------|------| | devlevel | >0 时开发模式自动生成路由菜单 | | catcherror | 1=全局 error / unhandledrejection 上报 | | onwebws | 1=启动用户 WS(publish/web 监听) | | onweblog | 远程客户端日志 | | onconsole | WS/API 耗时控制台输出 | | tyrobot | 默认机器人类型 → $fn.apisys / $fn.wssys 别名 | | local.lang / local.theme | localStorage 键名 | | aes.lv | 与后端 asaihost.jsonaes.lv 对齐;>1 需 .env 密钥 |

禁止在 JSON 中写 aes.keybase64;使用 VITE_ASAI_AES_KEYBASE64


完整配置 — dirmodel.json(模型索引)

{
  "dir": [
    "asai/model/configrouter.json",
    "asai/model/sysconfig.json",
    "setting/settinglang.json",
    "setting/settingweb.json"
  ]
}

加载后 $model.data.sys.configrouter 等可被 initweb 用于路由合并。


完整配置 — configrouter.json(路由与权限,合成示例)

路径:public/webmodel/sys/asai/model/configrouter.json
各业务模块可追加 {module}/configrouter.jsonrights 合并、其它字段浅合并

{
  "config": {
    "index": "",
    "login": "user/login",
    "loading": "PageLoad",
    "lv": 3
  },
  "rights": {
    "lv0": ["testkdd", "testkdd/testindex", "user/login", "user/reg", "user/exit", "user/edit"],
    "lv1": ["testkdd/testlv1"],
    "lv2": ["testkdd/testlv2", "admin/userlist"],
    "lv3": ["testkdd/testlv3", "admin/userlist"]
  }
}

| 字段 | 说明 | |------|------| | config.index | 默认首页 hash 段 | | config.login | 未登录跳转 hash | | config.loading | 加载组件名 | | config.lv | 默认访问等级 | | rights.lv0~lv3 | hash 路径片段列表;AsaiInitPage 计算 $global.rlv |

Hash 格式:#/模块名/路径/...$global.location.hasharr


完整配置 — server.json(API / WS 连接表,合成示例)

路径:public/webmodel/sys/server.json
startLink() / initLink() 解析为 $global.link,并缓存到 localStorageas-link

{
  "servertype": 0,
  "defaultws": "web",
  "api": {
    "default": "web",
    "web": {
      "url": "http://localhost:9198",
      "port": 9198
    },
    "ai": {
      "url": "http://localhost:11434"
    }
  },
  "ws": {
    "default": {
      "close": 0,
      "url": "ws://localhost:9198",
      "port": 9198,
      "sec": 1,
      "worker": 0,
      "config": {
        "tmdeltask": 600000,
        "resend": 0,
        "resendmax": 10
      }
    },
    "web": {
      "close": 0,
      "url": "ws://localhost:9198",
      "port": 9198,
      "sec": 1,
      "worker": 0,
      "config": {
        "tmdeltask": 600000,
        "resend": 0,
        "resendmax": 10
      }
    }
  }
}

api / ws 条目字段

| 字段 | 说明 | |------|------| | url | 完整地址;也可仅 port,由 As.getUrlByCfg 拼 hostname | | port | 端口(DEV 下 Vite 代理 /api 时不直连后端端口) | | 字符串值 | 引用同名键,如 "weld": "default" | | close | 1=不建连 | | sec | 1=WS 需登录 token 才建连 | | worker | 1=Web Worker 模式 WS | | config.tmdeltask | wsApi 回调 Map 清理间隔(ms) | | config.resend / resendmax | 重发策略 |

运行时用法

$fn.useApi(ujt, 'web');   // → $fn.api.web(AsaiApi 单例)
$fn.useWs(ujt, 'web');    // → $fn.ws.web(AsaiWs 单例)
$fn.api.web.apiPost('/api/user/login/auth/', body);
$fn.ws.web.wsApi({ ty: 'chat/web', id: '1', db: {} });

完整配置 — .env(构建期,合成示例)

NODE_ENV=development
VITE_ENV_TYPE=development
VITE_OBFUSCATE_ENABLE=0
VITE_MAIN_JS=main
VITE_WEB_PATH=/
VITE_API_URL=/api
VITE_HTTP_HOST=localhost
VITE_HTTP_PORT=9060
VITE_HTTP_API=http://localhost:9198
VITE_DIST_DIR=../webserver/webclient/
VITE_ASAI_AES_KEYBASE64=AsaiFfQ1hMYYvT2N4Y1BhenJ0RjY0M2cxWTMZXdXMVY=

| 变量 | 说明 | |------|------| | VITE_ASAI_AES_KEYBASE64 | 须与后端 ASAI_AES_KEYBASE64 一致 | | VITE_HTTP_API | 参考用;DEV 实际 API 走 Vite 代理 /api | | VITE_WEB_PATH | 构建 base,与 $CFG.webpath 对齐 |


配置 → 运行时映射

cfg.js                          → $global.$cfg
dirglobal.json → sysweb.json…   → $global.sys
dirmodel.json → configrouter…   → $model.data.sys, $global.sys.router
server.json                     → $global.link.api / .ws
  └── useApi / useWs            → $fn.api.* / $fn.ws.*
configrouter.rights             → $global.rlv(访问等级)
VITE_ASAI_AES_KEYBASE64         → $global.sys.aesfns(lv>0 时)

运行时上下文 ujt

安装完成后,各页面通过 inject / 全局属性访问 ujt

| 键 | 职责 | |----|------| | $global | 用户、hash、link、sys、主题 | | $fn | API/WS、As/AsCode、路由、登录 | | $model | 模块 dirmodel、comps | | $db / $dbwork | 模块响应式数据 | | $ws | WS 推送(wssys) |


扩展业务模块

  1. public/webmodel/{module}/ 放置 configrouter.jsondirmodel.json
  2. 将模块名加入 $model.webmodels(业务 bootstrap)
  3. Hash 访问 #/{module}/...
  4. 可选:lib-install/index.tsinstall(app, lib) 注册 $engine{module}

核心组件与指令

组件

| 组件 | 说明 | |------|------| | AsaiInitPage | 首屏:initweb / link / lang / WS | | AsaiWebServer | 根容器 | | AsaiWebModule | 模块:initAppModel + 模块 WS | | PageLoadClient / Server / Ws / Err | 加载与错误态 | | AsPageBusy | 全局 busy | | PopBox / PopMsg / PopTip | 弹层与消息 |

指令(v-*

| 指令 | 说明 | |------|------| | v-drag | 指针拖拽(绝对定位 translate) | | v-longpress | 长按触发回调 | | v-scrollbottom | 列表在底部时自动滚底 | | v-fullscreen | 点击/双击切换目标全屏 class | | v-userlevel | 用户等级不足时遮盖 | | v-levelread | 无读权限时遮盖 | | v-dbpointerdown | 300ms 内双击 pointerdown | | v-dragzoom | 缩放场景下拖拽(弹窗标题栏) | | v-popresizezoom | 缩放场景下右下角 resize | | v-resizeflexwidthzoom | 拖拽分隔条调整宽高 |


开发与发布 npm 包

本地开发(插件目录)

cd webclient/src/plugs/asaihost-vue
npm install
npm run build          # dist/asaihost-vue.es.js + dist/asaihost-vue.cjs + .d.ts

发布到 npm

cd webclient/src/plugs/asaihost-vue
npm login              # 首次需登录 npmjs.org,scope @asai 需有发布权限
npm publish --access public

prepublishOnly 会自动执行 npm run build。发布内容仅含 dist/README.md(见 files / .npmignore)。

版本升级

npm version patch   # 或 minor / major
npm publish --access public

package.json 要点

| 字段 | 说明 | |------|------| | name | asaihost-vue | | peerDependencies.vue | ^3.4.0 | | dependencies.@noble/ciphers | AES-GCM 纯 JS 降级 | | exports.development | monorepo 源码 ./index.ts | | publishConfig.access | public |


约束与后端对应

架构约束

  • 禁止在插件内 cross-import 其它 plugs/*
  • 通过业务项目 LibInitloadts / loadvue / loadfn 与宿主耦合
  • @estun/asaihost-nodejs(后端)配对使用时,保持 server.json / aes.lv / 环境变量一致

与 asaihost-nodejs 的对应关系

| 前端 server.json | 后端 asaihost.json | |------------------|-------------------| | api.web.port 9198 | hosts.default.port 9198 | | ws.web.port 9198 | hosts.default.ws: 1 | | aes.lv | aes.lv(密钥均走 env,不进 JSON) | | ws.sec: 1 | security.requireAuth + 登录 token |


配置文件树(monorepo 参考)

webclient/public/webmodel/
├── files/
│   ├── cfg.js                 ← window.$CFG
│   ├── logo.png
│   └── favicon.ico
└── sys/
    ├── dirglobal.json         ← 引导索引
    ├── dirmodel.json          ← 模型索引
    ├── server.json            ← API/WS 连接表 ★
    └── asai/
        ├── global/
        │   └── sysweb.json    ← 全局 sys ★
        └── model/
            ├── configrouter.json  ← 路由权限 ★
            └── sysconfig.json

配置与行为以本 README 与 useProvide.tsinitweb / initLink 源码为准。