次のような場合に使用: シンプルなキーと値のペアで情報を保存する必要があるとき——JSON形式のドキュメント、キャッシュ(一時保存)したレスポンス、アップロード済みファイル、またはバイナリ資産(デジタルデータ)。 標準的なblob API、キーの一覧表示と削除、アカウント全体またはval単位(スコープ)のスコープ指定、ストレージ制限に対応しています。
Use when a val needs simple key/value persistence — JSON documents, cached responses, uploaded files, or binary assets. Covers the std/blob API, listing and deleting keys, account-global or val scoping, and storage limits.
Val Town は std/blob モジュールを通じて、組み込みのキー/バリュー型 Blob ストレージを提供しています。
JSON ドキュメント、キャッシュされた API レスポンス、アップロードされたファイル、バイナリアセットなど、文字列をキーとしてシンプルな値を永続化する必要がある場合に活用してください。
SQL でクエリを行うリレーショナルデータや構造化データには、代わりに std/sqlite を使用してください。
Blob ユーティリティには 2 種類のエクスポートがあります。
global.ts はユーザーアカウント全体にスコープされ、main.ts は val 自身にスコープされます。
新しい val には main.ts インターフェースと val スコープを使用することを推奨します。
スコープ付きインポート:
/**
* `main.ts` からインポートすると、val スコープの Blob インターフェースが利用できます。
*/
import { blob } from "https://esm.town/v/std/blob/main.ts";
グローバルインポート:
/**
* `global.ts` からインポートすると、アカウント全体にスコープされた
* Blob インターフェースが利用できます。
*/
import { blob } from "https://esm.town/v/std/blob/global.ts";
/**
* このエントリーポイントは `v/std/blob` としても利用可能です。
* 古い val ではこちらが一般的です。
*/
import { blob } from "https://esm.town/v/std/blob";
スコープ付きとグローバルの blob インターフェースは、同じメソッドを持ちます。
スコープ付き Blob とグローバル Blob は別々に保存されます。スコープ付きインターフェースでグローバル Blob にアクセスすることも、その逆もできません。
import { blob } from "https://esm.town/v/std/blob/main.ts";
await blob.setJSON("config", { theme: "dark", count: 0 });
const config = await blob.getJSON("config");
// config = { theme: "dark", count: 0 }、キーが存在しない場合は undefined
getJSON はキーが存在しない場合に undefined を返すため、結果を使用する前にガード処理を行ってください:
const config = (await blob.getJSON("config")) ?? { theme: "light", count: 0 };
文字列、バイナリ、または任意の BodyInit には set/get を使用してください。
get は標準の Response を返すため、ボディヘルパー(.text()、.json()、.arrayBuffer()、.blob())を使用します:
await blob.set("logo.png", imageBytes); // string | BodyInit (Blob, ArrayBuffer, ReadableStream など)
const res = await blob.get("logo.png");
const bytes = await res.arrayBuffer();
getJSON と異なり、get はキーが存在しない場合に ValTownBlobNotFoundError を スロー します。
キーが存在しない可能性がある場合は try/catch で囲んでください。
const entries = await blob.list("user_"); // オプションのキープレフィックスフィルター
// entries = [{ key, size, lastModified }, …]
for (const { key } of entries) {
await blob.delete(key);
}
await blob.copy("config", "config.bak"); // 新しいキーで複製
await blob.move("draft", "published"); // 名前変更 / 移動
list(prefix?) は { key: string; size: number; lastModified: string } の配列を返します。
キー文字列そのものではなく、オブジェクトの配列である点に注意してください。
std/sqlite に保存してください。storeBlob、readBlob、listBlobs、deleteBlob ツールを、個人アカウントではなく組織が所有する val に対して使用する場合は、org パラメーターに組織のハンドルを渡すことで、その組織の Blob ストレージにアクセスできます。
例: { key: "myapp:config", org: "some-org" }
これはツール呼び出し時のみ必要です。val 内のコードは、所有アカウントのストレージに自動的にアクセスします。
なお、storeBlob は 100 KB までの UTF-8 テキストを受け付けます。それより大きいデータやバイナリ Blob は、コード内で blob.set を使用して書き込んでください。
list のスコープを絞るために、プレフィックス(feature:subkey)を活用してください。getJSON はキーが存在しない場合に undefined を返し、get は ValTownBlobNotFoundError をスローします。キーが存在しない場合の処理をそれぞれ適切に行ってください。完全な API ドキュメント: https://docs.val.town/std/blob/
Val Town provides built-in key/value blob storage via the std/blob module. Reach for it whenever a val needs to persist simple values — JSON documents, cached API responses, uploaded files, or binary assets — keyed by a string. For relational or structured data you query with SQL, prefer std/sqlite instead.
There are two exports of the blob utility: global.ts, which is scoped to the user account, and main.ts, which is scoped to the val itself. Prefer the main.ts interface and val scoping for new vals.
Here is the scoped import:
/**
* Importing from `main.ts` provides an interface to val-scoped blobs.
*/
import { blob } from "https://esm.town/v/std/blob/main.ts";
Here are the global imports:
/**
* Importing from `global.ts` provides a blob interface that is scoped
* to your account.
*/
import { blob } from "https://esm.town/v/std/blob/global.ts";
/**
* This entrypoint is also available as `v/std/blob`. This is common
* in older vals.
*/
import { blob } from "https://esm.town/v/std/blob";
The scoped & global blob interfaces have the same methods.
Scoped & global blobs are stored separately: you cannot access global blobs with the scoped interface or vice versa.
import { blob } from "https://esm.town/v/std/blob/main.ts";
await blob.setJSON("config", { theme: "dark", count: 0 });
const config = await blob.getJSON("config");
// config = { theme: "dark", count: 0 }, or undefined if the key doesn't exist
getJSON returns undefined when the key is missing, so guard before using the result:
const config = (await blob.getJSON("config")) ?? { theme: "light", count: 0 };
Use set/get for strings, binary, or any BodyInit. get returns a standard Response, so use its body helpers (.text(), .json(), .arrayBuffer(), .blob()):
await blob.set("logo.png", imageBytes); // string | BodyInit (Blob, ArrayBuffer, ReadableStream, …)
const res = await blob.get("logo.png");
const bytes = await res.arrayBuffer();
Unlike getJSON, get throws ValTownBlobNotFoundError if the key doesn't exist — wrap it in try/catch when the key may be absent.
const entries = await blob.list("user_"); // optional key prefix filter
// entries = [{ key, size, lastModified }, …]
for (const { key } of entries) {
await blob.delete(key);
}
await blob.copy("config", "config.bak"); // duplicate under a new key
await blob.move("draft", "published"); // rename / relocate
list(prefix?) returns an array of { key: string; size: number; lastModified: string } — objects, not bare key strings.
std/sqlite rather than as one giant blob.When using the storeBlob, readBlob, listBlobs, or deleteBlob tools against a val owned by an organization (not your personal account), pass the org handle as the org parameter so the call hits that organization's blob storage. Example: { key: "myapp:config", org: "some-org" }. This only matters for the tool calls — code inside the val reads and writes its owning account's storage automatically. Note storeBlob accepts UTF-8 text up to 100 KB; write larger or binary blobs from code with blob.set.
feature:subkey) for organization and to scope list.getJSON returns undefined for missing keys; get throws ValTownBlobNotFoundError. Handle the absent case accordingly.Full API docs: https://docs.val.town/std/blob/
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。