mcpField
B
blob-storage

blob-storage

github.com/val-town数据与数据库1041 次安装5 周前更新
代码仓库

关于 blob-storage

介绍如何在 Val Town 中使用 `std/blob` 持久化简单值,说明 val 级与账户级存储、数据操作,以及何时改用 `std/sqlite`。

主要功能

  1. 01存储 JSON 和原始数据
  2. 02val 级或账户级 Blob
  3. 03列出、删除和复制操作
  4. 04缺失键处理说明
  5. 05存储限制与使用提示

适用场景

  1. 01持久化 val 配置
  2. 02缓存 API 响应
  3. 03保存上传文件或二进制资源

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/val-town/plugins --skill blob-storage

安装后在 Claude Code 中输入/blob-storage确认已加载。

详细介绍

Blob 存储

Val Town 通过 std/blob 模块提供内置键值 Blob 存储。只要 val 需要按字符串键持久化简单值(例如 JSON 文档、缓存的 API 响应、上传的文件或二进制资源),就可以使用它。对于需要使用 SQL 查询的关系型或结构化数据,请改用 std/sqlite。

作用域:根据导入方式,可为账户全局或单个 val

Blob 工具提供两个导出:global.ts 的作用域为用户账户,main.ts 的作用域为 val 本身。对于新建的 val,优先使用 main.ts 接口和 val 作用域。

以下是作用域导入:

/**
 * Importing from `main.ts` provides an interface to val-scoped blobs.
 */
import { blob } from "https://esm.town/v/std/blob/main.ts";

以下是全局导入:

/**
 * 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";

作用域和全局 blob 接口具有相同的方法。

作用域 Blob 和全局 Blob 分开存储:你无法通过作用域接口访问全局 Blob,反之亦然。

基本用法(JSON)

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 会返回 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_"); // 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?) 会返回一个 { key: string; size: number; lastModified: string } 数组——返回的是对象,而不是单独的键字符串。

限制

  • **键长度:**最多 512 个字符。
  • **总存储空间:**免费计划为 10 MB,Pro 为 1 GB,由账户中的所有 Blob 共享。
  • 请将大型或结构化数据集存储在 std/sqlite 中,而不是作为一个巨大的 Blob 存储。

通过工具读取/写入 Blob

使用 storeBlob、readBlob、listBlobs 或 deleteBlob 工具操作属于某个组织(而非个人账户)的 val 时,请将组织句柄作为 org 参数传入,以便调用访问该组织的 Blob 存储。例如:{ key: "myapp:config", org: "some-org" }。这仅适用于工具调用——val 中的代码会自动读写其所属账户的存储。请注意,storeBlob 接受最多 100 KB 的 UTF-8 文本;对于更大的 Blob 或二进制 Blob,请在代码中使用 blob.set 写入。

规则

  • 将键视为扁平命名空间。使用前缀(feature:subkey)进行组织,并限定 list 的范围。
  • 对于缺失的键,getJSON 会返回 undefined;get 会抛出 ValTownBlobNotFoundError。请根据相应情况进行处理。
  • 不要在 Blob 中存储机密信息——请使用环境变量存储凭据。

参考

完整 API 文档:https://docs.val.town/std/blob/

评论

支持 Markdown