FilesLast commitLast update
1 month ago
1 month ago
7 months ago
7 months ago
7 months ago
README

Git Graph Demo MiniApp / Git Graph 示例 MiniApp

English | 中文


English

This demo showcases BitFun MiniApp's full-stack collaboration capability — specifically, using a third-party npm package (simple-git) inside a Node.js/Bun Worker to read a local Git repository and render an interactive commit graph.

Features

  • Pick a repository — opens a native directory picker via app.dialog.open({ directory: true })
  • Commit graph — Worker fetches git.graphData (log + refs + stashes + uncommitted in one call); UI renders commit nodes and branch lines as SVG
  • Branches & status — shows current branch, full branch list, and workspace status (modified / staged / untracked)
  • Commit detail — click any commit to view author, timestamp, diff stat, and per-file diff
  • Branch management — create, delete, rename, checkout local/remote branches
  • Merge / Rebase — merge a branch into HEAD, rebase HEAD onto a branch
  • Cherry-pick / Revert / Reset — cherry-pick a commit, revert with a new commit, or hard/mixed/soft reset
  • Push / Fetch — push to remote, fetch with prune, fetch a remote branch into a local branch
  • Remote management — add, remove, update remote URLs via the Remotes panel
  • Stash — push, apply, pop, drop, and branch-from-stash operations
  • Search commits — filter commit list by message, hash, or author
  • Tag management — add lightweight or annotated tags, delete tags, push tags

Data Flow

  1. UI → Bridge: app.call('git.log', { cwd, maxCount }) etc. via window.app (JSON-RPC)
  2. Bridge → Tauri: postMessage intercepted by the host useMiniAppBridge, which calls miniapp_worker_call
  3. Tauri → Worker: Rust writes the request to Worker stdin (JSON-RPC)
  4. Worker: worker_host.js loads source/worker.js; exported handlers are invoked — primarily git.graphData (returns commits + refs + stashes + uncommitted in one response), plus git.show, git.checkout, git.merge, git.push, git.stashPush, and 20+ other methods — all backed by the simple-git npm package
  5. Worker → Tauri → Bridge → UI: response travels back via stderr → Rust → postMessage to iframe → UI refreshes graph and detail panel

Directory Structure

miniapps/git-graph/
├── README.md           # this file
├── meta.json           # metadata & permissions (fs/shell/node)
├── package.json        # npm deps (simple-git) + build script
├── storage.json        # app KV (e.g. last opened repo path)
└── source/
    ├── index.html      # UI skeleton
    ├── build.js        # build script: concat ui/*.js → ui.js, styles/*.css → style.css
    ├── ui.js           # frontend entry (generated by build, do not edit directly)
    ├── style.css       # style entry  (generated by build, do not edit directly)
    ├── ui/             # frontend modules (run `npm run build` after editing)
    │   ├── state.js, theme.js, main.js, bootstrap.js
    │   ├── graph/layout.js, graph/renderRowSvg.js
    │   ├── components/contextMenu.js, modal.js, findWidget.js
    │   ├── panels/detailPanel.js, remotePanel.js
    │   └── services/gitClient.js
    ├── styles/         # style modules (run `npm run build` after editing)
    │   ├── tokens.css, layout.css, graph.css
    │   ├── detail-panel.css, overlay.css
    │   └── (merge order defined in build.js)
    ├── worker.js       # backend CJS (simple-git wrapper)
    └── esm_dependencies.json  # ESM deps (empty for this demo)

During development: after editing source/ui/*.js or source/styles/*.css, run npm run build inside the miniapps/git-graph directory to regenerate source/ui.js and source/style.css. BitFun will pick up the latest build on next load.

Running in BitFun

  1. Install to user data directory: copy this folder into BitFun's MiniApp data directory under an app_id subdirectory, e.g.:

    • The data directory is typically {user_data}/miniapps/
    • Create a subdirectory like git-graph-sample and place all files from this folder inside it (i.e. meta.json, package.json, source/ etc. at the root of that subdirectory)
  2. Or import via API: if BitFun supports path-based import, use create_miniapp or equivalent, pointing to this directory as the source; make sure the id in meta.json matches the directory name.

  3. Install dependencies: inside the MiniApp's app directory, run:

    • bun install or npm install (matching the runtime BitFun detected)
    • Or use the "Install Dependencies" action in the Mini Apps gallery (calls miniapp_install_deps)
  4. Compile: to regenerate compiled.html, call miniapp_recompile or let BitFun compile automatically when the MiniApp is opened.

  5. Open the MiniApp in the Mini Apps gallery, pick a repository, and the Git Graph will appear.

Permissions

Permission Value Purpose
fs.read {appdata}, {workspace}, {user-selected} Read app data, workspace, and user-selected repo
fs.write {appdata} Write app-own data only (e.g. storage)
shell.allow ["git"] simple-git needs to invoke the system git binary
node.enabled true Enable JS Worker to execute simple-git logic in worker.js

Technical Highlights

  • Client-side third-party library: require('simple-git') in worker.js runs inside a Bun or Node.js Worker process — no need to reimplement Git in Rust
  • Zero custom dialect: UI is plain concatenated JavaScript (IIFE modules sharing window.__GG), Worker is standard CJS — no custom framework or transpiler required; window.app is the unified Bridge API
  • ESM dependencies: this demo uses plain vanilla JS; esm_dependencies.json is empty — add React, D3, etc. there to have them served via Import Map from esm.sh

中文

本示例展示 BitFun MiniApp 的前后端协同能力,尤其是通过 Node.js/Bun 在端侧使用三方 npm 库(simple-git)读取 Git 仓库并渲染交互式提交图谱。

功能

  • 选择仓库:通过 app.dialog.open({ directory: true }) 打开原生目录选择器,选择本地 Git 仓库
  • 提交图谱:Worker 端通过 git.graphData(一次调用返回提交列表 + refs + stash + 未提交变更),UI 端用 SVG 绘制提交节点与分支线
  • 分支与状态:展示当前分支、所有分支列表及工作区状态(modified/staged/untracked)
  • 提交详情:点击某个 commit 可查看作者、时间、diff stat 及逐文件 diff
  • 分支管理:创建、删除、重命名、checkout 本地/远程分支
  • Merge / Rebase:将分支合并到 HEAD,或将 HEAD rebase 到目标分支
  • Cherry-pick / Revert / Reset:cherry-pick 指定 commit,revert 生成新提交,或 hard/mixed/soft reset
  • Push / Fetch:推送到远程,带 prune 的 fetch,将远程分支 fetch 到本地分支
  • 远程管理:通过远程面板添加、删除、修改远程 URL
  • Stash:push、apply、pop、drop 及从 stash 创建分支
  • 搜索提交:按消息、hash 或作者过滤提交列表
  • Tag 管理:添加轻量/注解 tag,删除 tag,推送 tag

前后端协同流程

  1. UI → Bridge:app.call('git.log', { cwd, maxCount }) 等通过 window.app 发起 RPC
  2. Bridge → Tauri:postMessage 被宿主 useMiniAppBridge 接收,调用 miniapp_worker_call
  3. Tauri → Worker:Rust 将请求写入 Worker 进程 stdin(JSON-RPC)
  4. Worker:worker_host.js 加载本目录 source/worker.js,其导出的处理函数被调用 — 主要是 git.graphData(一次返回提交 + refs + stash + 未提交变更),以及 git.show、git.checkout、git.merge、git.push、git.stashPush 等 20+ 个方法 — 均基于 simple-git npm 包
  5. Worker → Tauri → Bridge → UI:响应经 stderr 回传 Rust,再 postMessage 回 iframe,UI 更新图谱与详情

目录结构

miniapps/git-graph/
├── README.md           # 本说明
├── meta.json           # 元数据与权限(fs/shell/node)
├── package.json        # npm 依赖(simple-git)及 build 脚本
├── storage.json        # 应用 KV(如最近打开的仓库路径)
└── source/
    ├── index.html      # UI 骨架
    ├── build.js        # 构建脚本:合并 ui/*.js → ui.js,styles/*.css → style.css
    ├── ui.js           # 前端入口(由 build 生成,勿直接编辑)
    ├── style.css       # 样式入口(由 build 生成,勿直接编辑)
    ├── ui/             # 前端模块(编辑后需运行 npm run build)
    │   ├── state.js, theme.js, main.js, bootstrap.js
    │   ├── graph/layout.js, graph/renderRowSvg.js
    │   ├── components/contextMenu.js, modal.js, findWidget.js
    │   ├── panels/detailPanel.js, remotePanel.js
    │   └── services/gitClient.js
    ├── styles/         # 样式模块(编辑后需运行 npm run build)
    │   ├── tokens.css, layout.css, graph.css
    │   ├── detail-panel.css, overlay.css
    │   └── (合并顺序见 build.js)
    ├── worker.js       # 后端 CJS(simple-git 封装)
    └── esm_dependencies.json  # ESM 依赖(本示例为空)

开发时:修改 source/ui/*.js 或 source/styles/*.css 后,在 miniapps/git-graph 目录执行 npm run build 生成 source/ui.js 与 source/style.css,BitFun 加载时会使用最新构建结果。

在 BitFun 中运行

  1. 安装到用户数据目录:将本目录复制到 BitFun 的 MiniApp 数据目录下,并赋予一个 app_id 子目录,例如:

    • 数据目录一般为 {user_data}/miniapps/
    • 新建子目录如 git-graph-sample,将本目录中所有文件按相同结构放入其中(即 meta.json、package.json、source/ 等在该子目录下)
  2. 或通过 API 创建:若 BitFun 支持从路径导入,可使用 create_miniapp 或等价方式,将本目录作为 source 路径导入,并确保 meta.json 中的 id 与目录名一致。

  3. 安装依赖:在 MiniApp 的 app 目录下执行:

    • bun install 或 npm install(与 BitFun 检测到的运行时一致)
    • 或在 Mini Apps 画廊中对该 MiniApp 执行「安装依赖」操作(调用 miniapp_install_deps)
  4. 编译:若需重新生成 compiled.html,可调用 miniapp_recompile 或由 BitFun 在打开该 MiniApp 时自动编译。

  5. 在 Mini Apps 画廊中打开该 MiniApp,选择仓库后即可查看 Git Graph。

权限说明

权限 值 用途
fs.read {appdata}、{workspace}、{user-selected} 读取应用数据、工作区及用户选择的仓库目录
fs.write {appdata} 仅写入应用自身数据(如 storage)
shell.allow ["git"] simple-git 需调用系统 git 命令
node.enabled true 启用 JS Worker,以便执行 worker.js 中的 simple-git 逻辑

技术要点

  • 端侧三方库:worker.js 中 require('simple-git'),在 Bun 或 Node.js Worker 进程中运行,无需在 Rust 中重新实现 Git 能力
  • 无自定义方言:UI 为普通拼接脚本(IIFE 模块通过 window.__GG 共享状态),Worker 为标准 CJS,无需自定义框架或转译器;window.app 为统一 Bridge API
  • ESM 依赖:本示例 UI 使用纯 vanilla JS,esm_dependencies.json 为空;若需 React/D3 等,可在其中声明并由 Import Map 从 esm.sh 加载