- JavaScript 100%
| lib | ||
| server | ||
| Tests | ||
| .gitignore | ||
| config.json | ||
| main.alia | ||
| README.md | ||
ModSpace
Alia Mods Space 桌面客户端与 ModServer 服务端。客户端基于 gtk-alia(GTK4 + libadwaita),
整体以 Alia 语言编写;服务端基于 Express(server/),共同对接 alia CLI 工作流。
功能
- 浏览 / 搜索 / 排序模组(标题栏统一搜索栏)
- 模组详情(crates.io 风格:描述 / 文档 / 文件 / 版本 / 依赖 页签,Markdown 渲染 README)
- 注册、登录、退出
- 桌面端发布模组(选择本地
.aliam上传)
项目结构
main.alia 应用入口:装配外壳并运行 GTK 主循环
lib/
api.alia REST 客户端(列表 / 详情 / README / 文件 / 依赖 / 认证 / 发布)
json.alia JSON 解析与序列化(点路径扁平模型)
markdown.alia Markdown → HTML / 纯文本,体积与日期格式化
models.alia ModInfo / ModFile 数据模型与访问器
store.alia 键值存储抽象(桌面端 ~/.alia/config.json / Web 端浏览器存储)
theme.alia libadwaita 配色策略与组件 CSS
nav.alia 页面栈导航、轻提示、剪贴板与外链
account.alia 账户菜单(登录 / 注册 / 退出)
shell.alia 窗口外壳:AdwToolbarView + AdwHeaderBar + 页面注册
widgets/
status.alia 空态 / 加载态 / 错误重试态
mod_card.alia 模组卡片
markdown_view.alia Markdown 渲染视图(WebKit 优先,纯文本回退)
pages/
browse.alia 浏览页
detail.alia 详情页与文件查看页
publish.alia 发布页
auth.alia 登录 / 注册页
Tests/ 测试(api / json / markdown / store / ui / web)
server/ ModServer(Express REST API)
本地开发
桌面客户端
依赖系统安装 GTK4(libgtk-4.so.1)与 libadwaita(libadwaita-1.so.0);
README / 文档渲染优先使用 WebKitGTK(libwebkitgtk-6.0.so),缺失时自动回退为纯文本视图。
alia add gtk-alia ~ 首次拉取依赖
alia start ~ 解释模式运行(FFI 直连系统 GTK4,无编译产物)
alia run ~ 编译并运行(node-gtk 原生桌面)
alia build ~ 仅编译,产物位于 build/nodejs
MODSPACE_API=http://localhost:3000/ alia run ~ 指向本地 ModServer
窗口外壳使用 gtk.adwWindowNew + gtk.adwWindowSetContent:AdwWindow 会把内容里的
AdwHeaderBar 提升为窗口标题栏,若改用 gtk.windowNew + gtk.windowSetChild 会出现双顶栏;
顶栏内容必须走 gtk.adwHeaderBarPackStart/PackEnd/SetTitleWidget,混用 GTK 版
gtk.headerBarPack* 会静默失效并写坏内存。
API 基址优先级:URL 查询参数 ?api=(Web)> 环境变量 MODSPACE_API > ~/.alia/config.json 的 spaceUrl > 默认 https://mods.alia.0832.ink。
凭据由 lib/store.alia 托管:桌面端与 alia CLI 共享 ~/.alia/config.json(token / username),
Web 端落浏览器存储(宿主提供的 web.storage*)。宿主形态由能力探测决定,Alia 侧不对具体运行时做特化判断。
Web 目标
客户端可作为纯前端站点运行(nodejs 编译产物 + --target:web,由 gtk-alia 的 Web 后端桥接
命令式 GTK API 到 GTK.js / React)。浏览、搜索、排序、详情、README、文件树与文件查看、
注册、登录、退出均可用;发布依赖 curl 与本地文件系统,故 Web 宿主下发布页给出桌面端
替代指引。
alia build --lang:nodejs --target:web ~ 产出 build/nodejs-web/web/dist
node ../Base/Manager/index.js build --lang:nodejs --target:web
cd build/nodejs-web/web && npx vite --host ~ 本地预览(默认 http://localhost:5173)
部署时将 build/nodejs-web/web/dist 作为静态站点发布,并把 /api/ 反向代理到 ModServer:
alia build --lang:nodejs --target:web && cd build/nodejs-web/web && npx vite build
# dist/ 即可托管;?api=https://mods.example.ink/ 可在不改代码的情况下切换 API 基址
Web 目标约束:
web.httpRequest在浏览器侧为同步 XHR(语言层await编译为join()阻塞语义),因此 ModServer 必须开启 CORS(默认已开启);请求期间主线程被阻塞。- Web 宿主无进程与文件系统,
apiCanPublish返回false。 - 外链通过宿主
web.openUrl打开,桌面端仍走xdg-open。 - README / 文档在 Web 宿主下由
iframe承载 WebKit 视图(与桌面端同一套 Alia 代码路径)。 - gtk-alia 的 Web 后端需要包含
backends/web-gtk.js与backends/web-build.js的版本;alia add gtk-alia拉取的已发布版本若不含这些文件,需改用本地检出(见 gtk-alia 仓库)。
ModServer
cd server
npm install
npm start
默认监听 3000 端口。
构建
alia build
cd build/nodejs && node main.js
alia run 等价于编译后启动,编译产物使用 node-gtk 驱动原生 GTK4。
测试
alia check ~ 全项目静态检查(类型 / 未使用变量)
node ../Base/Executor/Tests/stdin_runner.js Tests/api.alia test
node ../Base/Executor/Tests/stdin_runner.js Tests/json.alia test
node ../Base/Executor/Tests/stdin_runner.js Tests/markdown.alia test
node ../Base/Executor/Tests/stdin_runner.js Tests/store.alia test
xvfb-run -a node ../Base/Executor/Tests/stdin_runner.js Tests/ui.alia run
node Tests/web.js ~ Web 目标端到端验收(无头 Chrome)
cd server
npm test
Tests/web.js 覆盖 Web 目标的真实浏览器行为:构建 nodejs-web 产物、在临时端口拉起
ModServer 并植入固定模组、再用无头 Chrome(CDP)逐项断言浏览 / 搜索 / 排序 / 详情五页签 /
README iframe 渲染 / 文件树与文件查看 / 返回 / 注册 / 登录 / 刷新保持 / 退出 / 空态 /
窄屏无横向溢出 / 无未知控件占位 / 控制台无警告,最后回归解释器测试与 alia check。
node Tests/web.js # 完整流程(含构建)
node Tests/web.js --skip:build # 复用已有 build/nodejs-web
node Tests/web.js --api:http://127.0.0.1:3000 ~ 对接既有 ModServer
node Tests/web.js --shots:./shots # 保留各步骤截图
--api: 指向的 ModServer 需允许跨域(默认 CORS 已开启)。Web 目标在浏览器侧的宿主能力由
entry.jsx 的 shimModules 兜底:内存 fs、同步 XHR 的 web.httpRequest、
web.storage*(浏览器存储)、web.pageUrl、web.openUrl。
ModServer 部署指南
ModServer 是 Alia Mods Space 的 REST API 服务端,源码位于本仓库 server/,数据默认持久化于 server/data/(已被 .gitignore 忽略)。
环境要求
- Node.js ≥ 18
- 可选:Nginx(生产反向代理与静态托管)
配置
通过环境变量配置:
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT |
3000 |
监听端口 |
ALIA_SPACE_DATA |
server/data |
数据目录(users.json、registry.json、mods/、secret) |
ALIA_SPACE_SECRET |
自动生成 | JWT 签名密钥 |
数据目录结构:
server/data/
├── users.json # 用户(bcrypt 密码哈希)
├── registry.json # 模组元数据注册表(描述/标签/主页/版本/依赖/下载统计)
├── secret # 自动生成的 JWT 密钥
├── mods/ # 已发布包 <name>@<version>.aliam
└── extracted/ # 解包内容 <name>@<version>/(README/文档/文件浏览)
本地运行
cd server
npm install
npm start
验证:
curl http://localhost:3000/api/mods
生产部署(Nginx + systemd)
推荐架构(单域名,API 由 Nginx 反代):
mods.alia.0832.ink→/api/路径由 Nginx 反向代理到本机127.0.0.1:3000的 ModServer;桌面客户端直接指向该域名
1. 安装 ModServer 依赖并创建 systemd 服务
cd server
npm install --omit=dev
sudo mkdir -p /opt/mods-space
sudo cp -r . /opt/mods-space/
创建 /etc/systemd/system/modserver.service:
[Unit]
Description=Alia Mods Space Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/mods-space
ExecStart=/usr/bin/node index.js
Environment=PORT=3000
Environment=ALIA_SPACE_DATA=/opt/mods-space/data
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now modserver
2. Nginx 配置
站点静态产物来自 alia build --lang:nodejs --target:web 的 build/nodejs-web/web/dist,
复制到 /var/www/mods.alia.0832.ink;/api/ 反向代理到本机 ModServer:
cd /path/to/ModSpace
alia build --lang:nodejs --target:web
sudo mkdir -p /var/www/mods.alia.0832.ink
sudo cp -r build/nodejs-web/web/dist/. /var/www/mods.alia.0832.ink/
/etc/nginx/sites-available/mods.alia.0832.ink.conf:
server {
listen 80;
server_name mods.alia.0832.ink;
root /var/www/mods.alia.0832.ink;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m;
}
location / {
try_files $uri $uri/ /index.html;
}
}
sudo ln -s /etc/nginx/sites-available/mods.alia.0832.ink.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
3. HTTPS
使用 certbot 为域名签发证书:
sudo certbot --nginx -d mods.alia.0832.ink
证书续期由 certbot 的 timer 自动处理。
客户端对接
alia CLI 与桌面客户端通过 alia space <url> 或 MODSPACE_API 指向部署地址:
alia space https://mods.alia.0832.ink/
alia login
alia publish
Web 客户端默认使用同域 /api/,无需额外配置;如需指向其它 ModServer,追加查询参数
?api=https://<host>/ 即可(同域部署时可省略)。
接口一览
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/register |
注册用户({ username, password }) |
POST |
/api/login |
登录,返回 JWT |
POST |
/api/logout |
退出登录 |
POST |
/api/publish |
发布包(multipart file,需 Authorization: Bearer <token>) |
GET |
/api/mods/:name/latest |
查询最新版本号 |
GET |
/api/mods/:name@:version.aliam |
下载指定版本 |
GET |
/api/mods |
模组列表,可选 ?q=<关键词> 与 `?sort=updated |
GET |
/api/mods/:name |
单模组详情(含全部版本与元数据) |
GET |
/api/mods/:name/versions |
版本列表 |
GET |
/api/mods/:name/readme?version= |
README 内容 |
GET |
/api/mods/:name/files?version= |
包内文件树 |
GET |
/api/mods/:name/file?version=&path= |
单个文件内容 |
GET |
/api/mods/:name/dependencies?version= |
指定版本的依赖表 |
服务端依赖
桌面客户端与 Web 客户端均依赖 ModServer 的 /api/mods 系列接口(列表 / 详情 / 版本 / README / 文件 / 依赖)与 register / login / logout;publish 仅桌面端使用(Web 端无进程与文件系统)。发布时服务端从包内 config.json(含可选 author/description/tags/homepage)提取元数据写入 registry.json,并将解包内容持久化到 data/extracted/。