跳到內容
Graft 標誌:一個 G,橫筆是插向圓心的箭頭

園藝學 Effect 系統

Graft 在 Effect 上把應用程式養成一棵外掛樹。行程持續執行,任意一枝都可以載入、取代或卸載。放心修剪。

軟體不是造出來的,是長出來的。

外掛到來、生根、結果。有的被剪掉,有的在樹不倒的情況下被換掉。好園丁從不擔心一根枝條從哪裡來,也不擔心剪掉它會怎樣。

Graft 給你這份確定。每個外掛都嫁接在一個 scope 上,每個 fiber 都有歸屬,每個失敗都能追溯到根。

熱替換

不砍樹,只換品種。熱重載只取代受變更影響的外掛,在一次交易中完成;新程式碼失敗時保留舊程式碼。見 熱重載。

乾淨卸載

每個外掛都在自己的 Scope 中執行。外掛消失時,相依於它的部分先停止,再執行它的 finalizer。失敗保留完整的 Cause。見 生命週期。

相依受檢查

服務是 Effect 的 Context 鍵,由 layer 或其他外掛提供。外掛在 inject 中列出所需服務,由編譯器檢查。見 服務。

import { Context, Effect, Option, Schema, Stream } from "effect"
import { Fork, Graft, Plugin } from "@graftland/graft"
class Greeter extends Context.Service<
Greeter,
{ readonly greet: (name: string) => Effect.Effect<void> }
>()("app/Greeter") {}
// Publishes a Greeter while it is loaded.
const greeter = Plugin.make({
name: "app/greeter",
config: Schema.Struct({ greeting: Schema.String }),
apply: ({ greeting }) =>
Graft.provide(Greeter, {
greet: (name) => Effect.log(`${greeting}, ${name}!`),
}),
})
// Starts once a Greeter exists, and stops before it goes away.
const hello = Plugin.make({
name: "app/hello",
inject: [Greeter],
apply: () => Effect.flatMap(Greeter, (greeter) => greeter.greet("world")),
})
const states = await Effect.runPromise(
Effect.gen(function* () {
const helloFork = yield* Graft.plugin(hello)
yield* helloFork.await
const waiting = yield* Stream.runHead(helloFork.state)
yield* Graft.plugin(greeter, { greeting: "Hello" })
const started = yield* helloFork.state.pipe(
Stream.filter(
(state) => state._tag !== "Pending" && state._tag !== "Loading",
),
Stream.runHead,
)
return [waiting, started]
}).pipe(Effect.scoped, Effect.provide(Graft.layer)),
)
states // => [Option.some(Fork.ForkState.Pending({ missing: ["app/Greeter"] })), Option.some(Fork.ForkState.Active())]

在別處執行外掛

用 Remote 把某個外掛放到子行程、worker 或另一台機器上執行,使用它的外掛不必修改。

區段 頁面 閱讀目的
從這裡開始 快速開始、核心概念、從 cordis 遷移 了解模型並執行點什麼。
建構外掛 外掛、服務、事件 撰寫程式碼。
結構 生命週期、領域、Intercept、取代外掛 控制外掛之間的關係與變化。
應用程式 設定檔、命令列、熱重載、在自己的程式中使用 Graft 執行並維運應用程式。
Remote 概覽、宿主設定項目、Runner、替換與停止 讓外掛在另一個行程或另一台機器上執行。
參考 Fork 控制代碼、Loader API、HMR API、錯誤 查閱確切行為。
專案 發佈 檢查並發佈 Graft。
套件 功能
@graftland/graft 基於 Effect 的外掛框架:外掛、fork、服務、隔離、事件和日誌。
@graftland/loader 從設定項目清單或 YAML 設定檔載入外掛。
@graftland/hmr 在 Node.js 中重載外掛模組,無需重新啟動行程。
@graftland/cli 提供 graft 命令:start、create、add 和 remove。
@graftland/create 建立新的 Graft 專案:npm create @graftland 與 graft create。
@graftland/package-manager 使用 npm、pnpm 或 Yarn 安裝相依套件。安裝失敗時,透過快照還原復原。
@graftland/plugin-remote 讓外掛在子行程、worker 或另一台機器上執行。見 Remote。
@graftland/plugin-otlp 把一棵外掛子樹的 span 匯出到 OpenTelemetry。見匯出 span。
@graftland/plugin-http 共用 HTTP 伺服器;路由與串流隨外掛的生命週期載入與卸載。
@graftland/plugin-http-api 即時 HttpApi 路由群組、型別化用戶端與 OpenAPI 文件。
@graftland/plugin-mcp-server 把外掛的工具提供給 MCP 用戶端。見 MCP 伺服器。

所有套件共用同一個版本號,一同發布,並需要 effect 4.1.x。

園藝只出現在這一頁。在其餘文件和程式碼裡,Scope 仍然叫 Scope。Graft的外掛模型借鑑自 cordis。cordis 在時空中組合,Graft 只照料自己的園子。