@gasboost/client
v0.3.0
Published
Type-safe Google Apps Script RPC client with jobs and navigation.
Maintainers
Readme
@gasboost/client
Google Apps Script Web アプリケーション向けの、フレームワーク非依存クライアントライブラリです。
@gasboost/app で定義した RPC 契約を利用して、フロントエンドから型安全に Google Apps Script のサーバー関数を呼び出せます。
また、RPC や任意の非同期処理を Job として管理する仕組みと、Google Apps Script Web アプリケーションの History 同期機能を提供します。
インストール
pnpm add @gasboost/clientnpm:
npm install @gasboost/client型安全な RPC
バックエンドで @gasboost/app を使って RPC を定義します。
// backend/main.ts
import { AppsScript, type InferAppsScript } from "@gasboost/app";
const app = new AppsScript()
.call("sum", (a: number, b: number) => a + b)
.call("getUser", async (id: string) => ({
id,
name: "Taro",
}));
export default app;
export type AppType = InferAppsScript<typeof app>;フロントエンドでは AppType を型として共有します。
import { appsScriptClient } from "@gasboost/client";
import type { AppType } from "../backend/main";
const { client } = appsScriptClient<AppType>();これにより、登録された RPC が型安全な関数として利用できます。
const total = await client.sum(1, 2);
const user = await client.getUser("user-1");引数型と戻り値型は AppType から推論されます。
存在しない RPC や不正な引数は TypeScript 上で検出できます。
RPC Transport
@gasboost/client は RPC の実行先を Transport として抽象化しています。
デフォルトでは AppsScriptTransport が利用され、Google Apps Script が提供する google.script.run を通して RPC を実行します。
const { client } = appsScriptClient<AppType>();例えば、
await client.sum(1, 2);はデフォルトでは対応する GAS のサーバー関数を、
google.script.run.sum(1, 2)のように呼び出します。
成功時には RpcResponse.contents を JSON として parse し、その結果を返します。
GAS 側の失敗は Promise の reject としてそのまま伝播します。
Transport の差し替え
appsScriptClient() には任意の Transport を指定できます。
import { appsScriptClient, FetchTransport } from "@gasboost/client";
const { client } = appsScriptClient<AppType>({
transport: new FetchTransport({
endpoint: "/rpc",
}),
});Transport は次のインターフェースを持ちます。
interface Transport {
call(name: string, args: unknown[]): Promise<RpcResponse>;
}独自の Transport を実装することで、RPC の実行先を差し替えられます。
import type { RpcResponse, Transport } from "@gasboost/client";
class CustomTransport implements Transport {
public async call(name: string, args: unknown[]): Promise<RpcResponse> {
// 任意の RPC transport
}
}AppsScriptTransport
AppsScriptTransport は google.script.run を利用する標準 Transport です。
import { AppsScriptTransport } from "@gasboost/client";
const transport = new AppsScriptTransport();appsScriptClient() に transport を指定しなかった場合、自動的に AppsScriptTransport が利用されます。
FetchTransport
FetchTransport は HTTP endpoint に対して fetch で RPC を実行する Transport です。
import { FetchTransport } from "@gasboost/client";
const transport = new FetchTransport({
endpoint: "/rpc",
});RPC 名は endpoint の末尾に追加されます。
POST /rpc/{rpcName}引数は JSON body として送信されます。
{
"args": [1, 2]
}成功した HTTP response の body は RpcResponse.contents として扱われます。
HTTP endpoint がエラーを返した場合、次の形式の error response を利用できます。
{
"error": {
"name": "Error",
"message": "RPC failed",
"stack": "..."
}
}FetchTransport は特定の開発環境やサーバー実装には依存しません。
Vite、Cloud Run、Cloudflare Workers など、同じ RPC protocol を提供する任意の HTTP endpoint に利用できます。
Export
現在 @gasboost/client から公開されている主な API:
appsScriptClient;
AppsScriptTransport;
FetchTransport;
Transport;
RpcResponse;
AppsScriptJob;
AppsScriptJobStore;
AppsScriptHistoryPipeline;ローカル RPC について
@gasboost/vite の dev plugin は、Vite Dev Server 上に Local RPC endpoint を提供します。
POST /__gasboost/{rpcName}FetchTransport を利用することで、この endpoint に RPC を送信できます。
const { client } = appsScriptClient<AppType>({
transport: new FetchTransport({
endpoint: "/__gasboost",
}),
});ただし、@gasboost/client 自体は Vite やローカル開発環境を判定しません。
開発環境で FetchTransport を自動的に利用する仕組みは @gasboost/vite が担当します。
責務
@gasboost/client が担当するもの:
AppTypeに基づく型安全 RPC client- RPC Transport の抽象
google.script.runを利用するAppsScriptTransport- HTTP RPC を利用する
FetchTransport - JSON response の parse
- RPC / 非同期処理の Job Queue
- Job の状態管理
- pending Job の cancel
- Job の retry
- Job Store の購読
- GAS Container と iframe の History 同期
開発環境に応じた Transport の選択は @gasboost/vite が担当します。
React 固有の処理は @gasboost/react が担当します。
JSON Response
RPC のレスポンスは JSON として扱われます。
const user = await client.getUser("user-1");例えばバックエンドが、
{
id: "user-1",
name: "Taro",
}を返した場合、フロントエンドでも同じ構造の object として取得できます。
不正な JSON が返された場合は JSON.parse のエラーになります。
Date
Date は JavaScript の Date instance には復元されません。
例えばバックエンドが、
{
createdAt: new Date("2026-09-04T00:00:00.000Z"),
}を返した場合、クライアントでは、
{
createdAt: "2026-09-04T00:00:00.000Z",
}のように string として取得されます。
@gasboost/app の InferAppsScript も、この JSON シリアライズ後の型に合わせて Date を string として推論します。
appsScriptClient
const { client, jobs } = appsScriptClient<AppType>();appsScriptClient() は次の2つを返します。
{
client,
jobs,
}client
AppType から生成される型安全な RPC client です。
jobs
RPC と非同期処理の Job を管理します。
現在以下の API を提供します。
jobs.start(label, execute);
jobs.cancel(jobId);
jobs.retry(jobId);
jobs.subscribe(listener);
jobs.getSnapshot();Job
client 経由で実行した RPC は自動的に Job として管理されます。
const { client, jobs } = appsScriptClient<AppType>();
const promise = client.getUser("user-1");
const snapshot = jobs.getSnapshot();RPC 名が Job の label になります。
job.label === "getUser";Job には一意な id が割り当てられます。
Job Status
Job は次の状態を持ちます。
pending
running
success
failed状態は status から取得できます。
job.status;個別の判定メソッドも利用できます。
job.isPending();
job.isRunning();
job.isSuccess();
job.isFailed();Job は次の情報も保持します。
job.id;
job.label;
job.createdAt;
job.endedAt;
job.result;
job.error;Job の実行
RPC 以外の任意の非同期処理も、同じ Job Queue で管理できます。
const { jobs } = appsScriptClient<AppType>();
const result = await jobs.start("load-data", async () => {
return await loadData();
});client から実行された RPC と jobs.start() は同じ Queue / Runner を共有します。
並列実行
Job Runner は複数 Job の並列実行に対応しています。
現在の最大同時実行数は 30 です。
上限を超えた Job は pending として Queue に残り、実行中の Job が完了すると順次実行されます。
成功した Job
成功した Job は完了後に Job 一覧から削除されます。
jobs.getSnapshot();には、実行中・待機中・失敗した Job が主に残ります。
失敗した Job
失敗した Job は一覧に failed 状態で残ります。
const failedJob = jobs.getSnapshot().find((job) => job.status === "failed");エラーは job.error から取得できます。
Retry
失敗した Job は ID を指定して再実行できます。
jobs.retry(job.id);元の Job は一覧から削除され、同じ label と execute を利用した新しい Job が Queue に追加されます。
そのため、retry 後の Job は新しい ID を持ちます。
Cancel
pending 状態の Job はキャンセルできます。
jobs.cancel(job.id);キャンセルされた Job は Queue と Job 一覧から削除され、対応する Promise は AppsScriptJobCancelledError で reject されます。
すでに running になった Job はキャンセルされません。
現在の cancel は、実行開始前の Job を Queue から取り除くための機能です。
Job の購読
Job 一覧の変更を購読できます。
const unsubscribe = jobs.subscribe(() => {
console.log(jobs.getSnapshot());
});購読を解除する場合:
unsubscribe();getSnapshot() は現在の Job 一覧を返します。
const jobsSnapshot = jobs.getSnapshot();このインターフェースは React の useSyncExternalStore から直接利用できる形になっています。
React から利用する場合は @gasboost/react の useAppsScriptJob を利用できます。
History
AppsScriptHistoryPipeline は Google Apps Script Web アプリケーションの navigation state を同期するための仕組みです。
import { AppsScriptHistoryPipeline } from "@gasboost/client";Google Apps Script が提供する、
google.script.historygoogle.script.url
と iframe 側の History を同期します。
GAS Container History
↕
AppsScriptHistoryPipeline
↕
iframe History通常 React アプリケーションでは、直接利用する代わりに @gasboost/react の AppsScriptRouter を利用します。
Export
現在 @gasboost/client から公開されている API:
appsScriptClient;
AppsScriptJob;
AppsScriptJobStore;
AppsScriptHistoryPipeline;ローカル RPC について
@gasboost/vite の dev plugin は、Vite Dev Server 上に Local RPC endpoint を提供します。
POST /__gasboost/{rpcName}ただし現在の @gasboost/client の RPC transport は google.script.run を利用します。
そのため、@gasboost/vite の Local RPC endpoint へ自動的に transport を切り替える機能は、現在の @gasboost/client には含まれていません。
責務
@gasboost/client が担当するもの:
AppTypeに基づく型安全 RPC clientgoogle.script.runを利用した RPC transport- JSON response の parse
- RPC / 非同期処理の Job Queue
- Job の状態管理
- pending Job の cancel
- Job の retry
- Job Store の購読
- GAS Container と iframe の History 同期
React 固有の処理は @gasboost/react が担当します。
関連パッケージ
@gasboost/app— バックエンドと RPC 契約の定義@gasboost/vite— GAS build と Local RPC@gasboost/react— React integration
License
MIT
