| サブモジュール | 責務 |
|---|---|
| signal/ | リアクティブプリミティブ (Signal, Effect, Computed) |
| render/ | VNode → HTML文字列レンダリング |
| routes/ | 型安全ルーティング |
| serialize/ | 状態のシリアライズ/デシリアライズ |
| vnode.mbt | VNode型定義 |
pub enum Node[E] {
Element(VElement[E]) // HTML要素
Text(String) // 静的テキスト
DynamicText(() -> String) // 動的テキスト
Fragment(Array[Node[E]]) // フラグメント
Show(...) // 条件付きレンダリング
For(...) // リストレンダリング
Island(VIsland[E]) // Hydration境界
WcIsland(VWcIsland[E]) // Web Components Island
Async(VAsync[E]) // 非同期ノード
// ...
}let count = @signal.signal(0)
count.get() // 0
count.set(1) // 値を設定
count.update(fn(n) { n + 1 }) // 更新関数
// 派生値
let doubled = @signal.computed(fn() { count.get() * 2 })
// 副作用
@signal.effect(fn() {
println(count.get())
})pub enum Attr[E] {
VStatic(String) // 静的値
VDynamic(() -> String) // Signal連動
VHandler(EventHandler[E]) // イベントハンドラ
VAction(String) // 宣言的アクション
}pub enum TriggerType {
Load // ページロード時
Idle // requestIdleCallback時
Visible // IntersectionObserver検知時
Media(String) // メディアクエリマッチ時
None // 手動トリガー
}pub enum Attr[E] {
VStatic(String)
VDynamic(() -> String)
VHandler(EventHandler[E])
VAction(String)
}pub struct EventHandler[E] {
callback : (E) -> Unit
}pub enum Node[E] {
Element(VElement[E])
Text(String)
DynamicText(() -> String)
Fragment(Array[Node[E]])
Show(() -> Bool, () -> Node[E])
For(() -> Array[Node[E]])
Component(() -> Node[E])
Island(VIsland[E])
WcIsland(VWcIsland[E])
Async(VAsync[E])
ErrorBoundary(VErrorBoundary[E])
Switch(VSwitch[E])
InternalRef(VInternalRef[E])
}#alias(Trigger)
pub(all) enum TriggerType {
Load
Idle
Visible
Media(String)
None
}pub struct VInternalRef[E] {
url : String
state : String
trigger : TriggerType
wc : Bool
styles : String
children : Array[Node[E]]
}pub struct VIsland[E] {
id : String
url : String
state : String
trigger : TriggerType
children : Array[Node[E]]
}pub struct VWcIsland[E] {
name : String
url : String
styles : String
state : String
trigger : TriggerType
children : Array[Node[E]]
}pub enum MyAction { Increment; Decrement } derive(Show)
@luna.h("button", [("onclick", action(Increment))], [...])error_boundary(
children=fn() { risky_component() },
fallback=fn(err, reset) {
h("div", [], [
text("Error: " + err.to_string()),
h("button", [("onclick", handler(fn(_) { reset() }))], [text("Retry")])
])
}
)fn[E] internal_ref(url : String, state : String, trigger? : TriggerType, wc? : Bool, styles? : String, children? : Array[Node[E]]) -> Node[E]fn[E] island(id : String, url : String, state : String, children : Array[Node[E]], trigger? : TriggerType) -> Node[E]switch_(
cases=[
match_case(when=fn() { state.get() == 1 }, render=fn() { text("One") }),
match_case(when=fn() { state.get() == 2 }, render=fn() { text("Two") }),
],
fallback=Some(fn() { text("Other") })
)fn[E] wc_island(name : String, url : String, styles : String, state : String, children : Array[Node[E]], trigger? : TriggerType) -> Node[E]