mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-10-14 02:21:24 +00:00
5.7 KiB
5.7 KiB
window.__TAURITAVERN__.api.extension.store — API 参考
TauriTavern 为第三方扩展提供的全局持久化能力,可选KV JSON 与 Blob 两种数据形态。
数据存储在 data_root/_tauritavern/extension-store/ 下,可随数据根目录一起备份/迁移/清理。
0. 快速上手
await (window.__TAURITAVERN__?.ready ?? window.__TAURITAVERN_MAIN_READY__);
const store = window.__TAURITAVERN__.api.extension.store;
KV JSON 存储
await store.setJson({ namespace: 'my-ext', key: 'settings', value: { enabled: true } });
const settings = await store.getJson({ namespace: 'my-ext', key: 'settings' });
const maybeSettings = await store.tryGetJson({ namespace: 'my-ext', key: 'settings' });
if (!maybeSettings.found) {
// Use in-code defaults; write only when the user changes settings.
}
JSON 多表(额外 json / table)
不提供
table时默认使用主表main。
await store.setJson({
namespace: 'my-ext',
table: 'index',
key: 'v1',
value: { lastId: 42 },
});
const tables = await store.listTables({ namespace: 'my-ext' });
Blob 存储
await store.setBlob({
namespace: 'my-ext',
key: 'icon.png',
data: myBlob, // Blob | ArrayBuffer | Uint8Array | base64 string
});
const blob = await store.getBlob({ namespace: 'my-ext', key: 'icon.png' });
大文件可用 getBlobStream() 逐块读取;提前停止时应取消流:
const stream = await store.getBlobStream({ namespace: 'my-ext', key: 'archive.bin' });
await stream.pipeTo(destination); // destination 是调用方的 WritableStream
1. KV JSON 方法
所有 KV 方法都支持可选 table 字段:
- 省略:使用默认主表
main - 指定:将数据写入对应 table
什么时候用 KV JSON?
建议绝大多数情况下使用KV JSON,把它当作“扩展的结构化数据存储”:
- 扩展设置(settings / feature flags)
- 索引、映射表、状态快照(index / map / progress)
- 需要
updateJson()深度合并对象的场景
| 方法 | 返回值 | 说明 |
|---|---|---|
getJson({ namespace, key, table? }) |
Promise<any> |
读取 JSON 值 |
tryGetJson({ namespace, key, table? }) |
Promise<{ found: boolean; value?: any }> |
可选读取;key 不存在时返回 { found: false },其他错误仍抛出 |
setJson({ namespace, key, value, table? }) |
Promise<void> |
写入 JSON 值(覆盖) |
updateJson({ namespace, key, value, table? }) |
Promise<void> |
合并更新:对象会深度合并;非对象直接替换 |
renameKey({ namespace, key, newKey, table? }) |
Promise<void> |
重命名 key |
deleteJson({ namespace, key, table? }) |
Promise<void> |
删除 key |
listKeys({ namespace, table? }) |
Promise<string[]> |
列出 table 下所有 key |
listTables({ namespace }) |
Promise<string[]> |
列出现有 table(KV 与 Blob 的 union) |
deleteTable({ namespace, table }) |
Promise<void> |
删除 table(同时删除该 table 下的 KV 与 Blob) |
兼容:updateJSON() 是 updateJson() 的别名;updateKey() 是 renameKey() 的别名。
2. Blob 方法
什么时候用 Blob?
存大型文件时,需要时再用:
- 图片/音频/压缩包/模型文件等二进制
- 体积较大、不希望浪费 JSON 格式化算力的内容(例如大段纯文本缓存)
- 需要直接喂给 Web API 的场景(返回值是
Blob,可URL.createObjectURL())
| 方法 | 返回值 | 说明 |
|---|---|---|
getBlob({ namespace, key, table? }) |
Promise<Blob> |
读取 blob(文件类型 mimeType 基于 key 文件扩展名猜测) |
getBlobStream({ namespace, key, table? }) |
Promise<ReadableStream<Uint8Array>> |
按消费速度读取原始字节;取消会关闭 reader |
setBlob({ namespace, key, data, table? }) |
Promise<void> |
写入 blob,允许空内容 |
deleteBlob({ namespace, key, table? }) |
Promise<void> |
删除 blob |
listBlobKeys({ namespace, table? }) |
Promise<string[]> |
列出 table 下所有 blob key |
3. 命名规则(namespace / table / key)
- 仅允许字符:
[A-Za-z0-9_.-] - 不能为空
- 不能以
.开头 ./..不被允许
4. table (多表)的语义
table 是逻辑分组:方便把同一扩展的不同数据域分开放、以及一键清理某个分组(deleteTable)。
当前实现中:
- 每个
(namespace, table, key)都是一个独立文件 KV JSON:.../kv/<table>/<key>.jsonBlob:.../blobs/<table>/<key>(原样文件名,不强制扩展名)
示例(以 my-ext 为例):
setJson({ namespace: 'my-ext', key: 'settings', value })- 存储在
data_root/_tauritavern/extension-store/my-ext/kv/main/settings.json
- 存储在
setJson({ namespace: 'my-ext', table: 'index', key: 'v1', value })- 存储在
data_root/_tauritavern/extension-store/my-ext/kv/index/v1.json
- 存储在
setBlob({ namespace: 'my-ext', key: 'icon.png', data })- 存储在
data_root/_tauritavern/extension-store/my-ext/blobs/main/icon.png
- 存储在
小型整体状态可以使用固定 key;持续增长的数据应拆成多个 key,按需读取。
5. 读写边界
- 写入保存调用时快照,以单文件原子替换发布;失败不暴露部分内容,不承诺断电持久化。页面重载前应等待需要确认的写入完成。
- 并发修改按发布顺序生效;
updateJson()的读取、合并和发布作为一次原子更新。删除不取消在途写入,没有跨 key 事务。 - 已打开的读取保持原文件版本,不受后续覆盖或删除影响。
getJson()/getBlob()返回完整值;JSON 写入和 base64 输入仍有整份数据的内存成本。大型二进制优先使用 Blob 写入和getBlobStream()读取。