Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# btuin

Bunランタイム向けの宣言的なTUIフレームワーク。

## 特徴

- **きめ細かなリアクティビティ**: 仮想DOMは使用しません。状態の変更に依存するコンポーネントのみが再描画されます。
- **Flexboxベースのレイアウト**: Rust製のエンジンがFlexboxのサブセットを実装し、レスポンシブなレイアウトを実現します。
- **Bunネイティブ**: Bunの高速なTTY、FFI、疑似ターミナルAPIと統合されています。
- **型安全**: TypeScriptで書かれています。

## インストール

```bash
bun add btuin
```

## 使い方

```ts
import { createApp, ref, ui } from "btuin";

const app = createApp({
// init: 状態とイベントリスナーをセットアップ
init({ onKey, runtime }) {
const count = ref(0);

onKey((keyEvent) => {
if (keyEvent.name === "up") count.value++;
if (keyEvent.name === "down") count.value--;
if (keyEvent.name === "q") runtime.exit(0);
});

return { count };
},

// render: UIツリーを返す。状態が変化すると再実行される。
render({ count }) {
return ui
.VStack([ui.Text("Counter"), ui.Text(String(count.value))])
.width("100%")
.height("100%")
.justify("center") // 子要素を垂直方向に中央揃え
.align("center"); // 子要素を水平方向に中央揃え
},
});

await app.mount();
```

## API概要

- `createApp(options)`: アプリケーションインスタンスを作成します。
- `options.init`: 状態を初期化し、リスナーを登録する関数。
- `options.render`: UIコンポーネントツリーを返す関数。
- `ref(value)`: リアクティブな状態変数を作成します。
- `computed(() => ...)`: 派生リアクティブ値を作成します。
- `watch(ref, () => ...)`: refが変更されたときに副作用を実行します。
- `ui`: プリミティブコンポーネントを含むオブジェクト (`Text`, `Block`, `VStack`など)。

## リンク

- [**ドキュメント**](./docs/) (アーキテクチャ, ロードマップ)
- [**GitHub**](https://github.com/HALQME/btuin) (ソースコード, Issue)

## 言語

- [English (英語)](./README.md)

## コントリビューション

コントリビューションを歓迎します。

> このリポジトリはmiseでツールを管理しています (`mise install`)。

### 開発セットアップ

```bash
# 依存関係をインストール
mise exec -- bun install --frozen-lockfile

# ネイティブのレイアウトエンジンをビルド
mise run build:ffi

# テストを実行
mise run test
```
148 changes: 51 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,133 +1,87 @@
# btuin

**btuin** (pronounced _between_) は、Bun ランタイム向けに設計された、モダンで高速な TUIフレームワークです。
Vue.js の Composition API を意識したリアクティビティシステムとSwiftUIライクな表現を採用しており、宣言的かつ直感的に CLI アプリケーションを構築できます。

## 目的

Bunのパフォーマンスを最大限に活かし、快適な開発体験をターミナルアプリケーション開発にもたらすことを目的としています。

複雑になりがちなカーソル制御や描画更新ロジックを隠蔽し、開発者が状態とビューの定義に集中できる環境を提供します。

## 利点

- **Vue ライクなリアクティビティ**: `ref`, `computed`, `watch`, `effect` などを備えた独自のリアクティビティシステムを搭載。状態の変化に応じて画面の差分だけを自動的に効率よく再描画します。
- **宣言的レイアウト**: `VStack`, `HStack`, `ZStack` などのレイアウトプリミティブを提供。絶対座標を計算することなく、Flexbox のように柔軟な UI を構築できます。
- **Bun ネイティブ**: Bun の高速な起動と実行速度、Bunのネイティブ API を活用し、軽量かつハイパフォーマンスに動作します。
- **コンポーネント指向**: `defineComponent` による再利用可能なコンポーネント設計が可能。現状は `Text` / `Block` / `Spacer` などのプリミティブ中心で、実用コンポーネントは順次追加予定です。
- **入力・実行基盤**: raw mode / 差分描画 / stdout capture など、TUI を成立させる足回りを内蔵しています。

## ロードマップ

- [x] 入力
- [x] 入力パーサーをステートフル化(チャンク分割耐性): `src/terminal/parser/ansi.ts`
- [x] `ESC` 単体 vs `Alt+Key` の曖昧さを解消
- [x] ブラケットペーストを「1イベント」に正規化: `src/terminal/parser/ansi.ts`
- [x] ブラケットペーストの on/off をランタイムへ統合
- [ ] マウス
- [ ] マウス入力(SGR など)をランタイムへ統合(有効化/無効化・イベント形式の確定)
- [ ] ヒットテスト(`ComputedLayout` と座標の照合、重なり順の決定)
- [ ] バブリング/伝播(子→親、キャンセル可能なイベントモデル)
- [ ] Developer Tools
- [ ] シェル統合
- [x] stdout/stderr capture 基盤(listener/console patch/テストモード): `src/terminal/capture.ts`
- [ ] `useLog`(capture → reactive state)でログUIを簡単にする
- [ ] デバッグ
- [ ] インスペクターモード(境界線/座標/サイズ可視化)
- [x] 配布
- [x] GitHub Release 用 tarball 生成(`src/layout-engine/native/` 同梱): `.github/workflows/release.yml`
- [x] `npm pack` の成果物を展開し、`src/layout-engine/native/` と `src/layout-engine/index.ts` の解決が噛み合うことを自動チェック
- [ ] Inline モード
- [ ] コンポーネント
- [ ] `TextInput` を実用レベルへ(編集・カーソル移動・IME確定後の反映)
- [ ] `ScrollView` / `ListView`(必要に応じて仮想スクロール、マウスホイール連動)
- [x] 安全性
- [x] FFI 境界の同期テスト(Rust 定数/構造体 ↔ JS 定義)を CI に追加
- [ ] ドキュメント / スターター
- [ ] `examples/` の拡充

## クイックスタート

> **前提**: `mise` がインストール済みであること(このリポジトリは `mise.toml` でツールを管理します)。

### セットアップ
Declarative TUI framework for the Bun runtime.

```bash
mise install
mise exec -- pnpm install --frozen-lockfile

# Layout Engine (FFI) をビルド(初回/更新時)
mise run build:ffi
```
## Features

### テスト

```bash
mise run test
```
- **Fine-Grained Reactivity**: No virtual DOM. Only components that depend on changed state are re-rendered.
- **Flexbox-based Layout**: A Rust-powered engine that implements a subset of Flexbox for responsive layouts.
- **Bun Native**: Integrated with Bun's fast TTY, FFI, and pseudo-terminal APIs.
- **Type-Safe**: Written in TypeScript.

### Profiling / Perf Regression
## Installation

```bash
# 大量要素のストレス
mise run profiler:stress -- --n=10000 --frames=120 --io=off --out=profiles/stress.json

# パフォーマンス上限テスト
mise run profiler:limit
bun add btuin
```

## 使い方
## Usage

```ts
import { createApp, ref, ui } from "btuin";

const app = createApp({
// init: setup state and event listeners.
init({ onKey, runtime }) {
const count = ref(0);
onKey((k) => {
if (k.name === "up") count.value++;
if (k.name === "down") count.value--;
if (k.name === "q") runtime.exit(0);

onKey((keyEvent) => {
if (keyEvent.name === "up") count.value++;
if (keyEvent.name === "down") count.value--;
if (keyEvent.name === "q") runtime.exit(0);
});

return { count };
},

// render: returns the UI tree. Re-runs when state changes.
render({ count }) {
return ui
.VStack([ui.Text("Counter"), ui.Text(String(count.value))])
.width("100%")
.height("100%")
.justify("center")
.align("center");
.justify("center") // Center children vertically
.align("center"); // Center children horizontally
},
});

await app.mount();
```

## 責務
## API Overview

- `reactivity`: `ref/computed/effect/watch` による状態管理
- `layout-engine`: Flexbox ライクなレイアウト(Rust FFI)
- `renderer`: バッファ描画 + 差分レンダリング(`renderDiff` は文字列を返す純粋関数)
- `terminal`: raw mode / 入力 / stdout 書き込み
- `btuin`: それらを束ねる “アプリ実行” と View API
- `createApp(options)`: Creates an application instance.
- `options.init`: Function to initialize state and register listeners.
- `options.render`: Function that returns the UI component tree.
- `ref(value)`: Creates a reactive state variable.
- `computed(() => ...)`: Creates a derived reactive value.
- `watch(ref, () => ...)`: Runs a side effect when a ref changes.
- `ui`: Object with primitive components (`Text`, `Block`, `VStack`, etc.).

## アダプタ(テスト/差し替え用)
## Links

通常はそのまま `createApp()` を使えば動きます。必要なら I/O を差し替えできます。
- [**Documentation**](./docs/) (Architecture, Roadmap)
- [**GitHub**](https://github.com/HALQME/btuin) (Source Code, Issues)

```ts
import { createApp } from "btuin";
## Language

createApp({
terminal: {
// write/onKey/getTerminalSize... など
},
platform: {
// resize/exit/signal... など
},
setup() {
return () => /* view */;
},
});
- [日本語 (Japanese)](./README.ja.md)

## Contributing

Contributions are welcome.

> This repository uses `mise` for tool management (`mise install`).

### Development Setup

```bash
# Install dependencies
mise exec -- bun install --frozen-lockfile

# Build the native layout-engine
mise run build:ffi

# Run tests
mise run test
```
Loading