クイックスタート

注釈

@rescript-tauri/core のモジュール一式は main で機能完備済みです。以下のサンプルは main 上で出荷されている実際の .resi シグネチャを反映しています。本パッケージは初回 npm 公開(v0.1.0)を待っている状態です。それまでは、ソースリポジトリ経由か ワークスペースリンクで @rescript-tauri/core を利用してください。

前提条件

  • インストール を完了済み

  • Rust 側に少なくとも 1 つの #[tauri::command] が定義されている Tauri 2.x プロジェクト

Layer 1 — Raw invoke

最下層は @tauri-apps/api/core を 1:1 でミラーします。可能な限り薄く始めたい場合や、型付き層からの逃げ道として使用してください。

let greeting: string =
  await Tauri.Core.Raw.invoke("greet", ~args={"name": "ReScript"})

Layer 2 — typed Command

Layer 2 では、コマンド名を明示的なエンコーダ・デコーダと一緒にラップし、エンドツーエンドで型付けされた Command.t<'args, 'result> を提供します。

module Commands = {
  let greet = Core.Command.make(
    ~name="greet",
    ~encodeArgs=({name}) =>
      JSON.Encode.object([("name", JSON.Encode.string(name))]),
    ~decodeResult=json =>
      switch json->JSON.Decode.string {
      | Some(s) => Ok(s)
      | None => Error("expected string")
      },
  )
}

switch await Commands.greet->Core.Command.invoke({name: "ReScript"}) {
| Ok(message) => Console.log(message)
| Error(DecodeError(msg)) => Console.error("decode failed: " ++ msg)
| Error(RustError(json)) => Console.error2("rust error:", json)
}

例外ベースの制御フローを好む呼び出し元のために、Core.Command.invokeExn も提供されます。

Event 購読

Event.make で型付きの event handle を 1 度宣言し、Event.listen で購読すると unlisten 関数が返されます。

let fileChanged = Event.make(
  ~name="file-changed",
  ~decode=json =>
    switch json->JSON.Decode.string {
    | Some(s) => Ok(s)
    | None => Error("expected string")
    },
)

let unlisten = await fileChanged->Event.listen(result =>
  switch result {
  | Ok(evt) => Console.log(evt.payload)
  | Error(_) => () // ignore decode failures
  }
)
// ... later
unlisten()

ウィンドウ操作

Window.t は不透明型です。インスタンスメソッドは pipe-first 形式で呼び出します。

open Tauri

let win = Window.getCurrent()
await win->Window.setTitle("Hello, ReScript")
await win->Window.maximize

let size = Dpi.LogicalSize.make(~width=1024.0, ~height=768.0)
await win->Window.setSize(size)

ボタン付きの完全なデモは examples/window-management にあります。

WebviewWindow の生成

open Tauri

let secondary = WebviewWindow.make(
  "secondary",
  ~options={
    url: "/",
    title: "Secondary",
    width: 480.0,
    height: 320.0,
  },
)

// Same instance can be viewed as a Window for window-only methods.
await secondary->WebviewWindow.asWindow->Window.setAlwaysOnTop(true)

Channel によるストリーミング

Core.Channel は Rust からフロントエンドへの一方向ストリーミングを提供します。各コールバックは result<'message, string> を受け取るため、デコーダの失敗が明示的に表面化します。Ok(...) / Error(_) をパターンマッチして処理方法を選択してください。

let counter = Core.Channel.make(~decode=json =>
  switch json->JSON.Decode.float {
  | Some(f) => Ok(Float.toInt(f))
  | None => Error("expected number")
  }
)

counter->Core.Channel.onMessage(result =>
  switch result {
  | Ok(n) => Console.log2("recv", n)
  | Error(_) => () // ignore decode failures
  }
)

let countTo = Core.Command.make(
  ~name="count_to",
  ~encodeArgs=({channel, target}) =>
    JSON.Encode.object(
      Dict.fromArray([
        ("channel", Obj.magic(channel)),
        ("target", JSON.Encode.float(Int.toFloat(target))),
      ]),
    ),
  ~decodeResult=_ => Ok(),
)

let _ = await countTo->Core.Command.invoke({channel: counter, target: 10})

対応する Rust ハンドラ付きの完全なデモは examples/streaming-ipc にあります。

Path / App ユーティリティ

let configDir = await Path.appConfigDir()
let appName = await App.getName()
Console.log3("ready:", appName, configDir)

Path は意図的に Tauri から再エクスポート されませんopen Tauri で Window / Event と一緒にスコープに取り込むのではなく、明示的に Path.appConfigDir() のように呼び出してください。

次のステップ