Files
Endoleap/src/lib/canvas-runtime/storage-port.ts
T

40 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 便携持久化端口:定义 scope、leader/fence、恢复图像与原子 DurableBatch。
* 这里不导入 IndexedDB/Web Locks 实现,Node/测试宿主可以提供其它 adapter。
* 成功 commit 才能确认 durable,内存发布或排队成功不能替代它。
*/
import type { Json } from '../canvas-core/types.ts';
/** Portable durable-store contract. Browser database types belong to the adapter. */
/** 账号/工作区/项目共同隔离持久事实;同 projectId 不得串用其它账号的存储。 */
export type StorageScope = { readonly accountId: string; readonly workspaceId: string; readonly projectId: string };
/** 可恢复单 Root 图像;formatVersion 是解释器版本,rootRevision 与文档 localRevision 分开。 */
export type RecoveryImage = { readonly formatVersion: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17; readonly rootRevision: number; readonly localRevision: number; readonly payload: Json };
/** 同一提交携带恢复图像、文件写入/删除及可选共享 depot cut,adapter 保证合同中的原子性。 */
export type DurableBatch = { readonly image: RecoveryImage; readonly deleteFiles?:readonly string[]; readonly depot?:import('./asset-depot.ts').DepotCut; readonly files?: readonly { readonly id: string; readonly bytes: Blob }[] };
/** 排他写者句柄;fence 区分代次,active 检查加实际存储校验阻止旧 writer 在新 leader 后继续写。 */
export type StorageLeader = { readonly scope: StorageScope; readonly fence: number; readonly active: boolean; release(): Promise<void> };
/** 文件盘点只返回元信息,不为扫描加载全部 Blob 字节。 */
export type StoredFileInfo={readonly id:string;readonly byteLength:number;readonly mimeType:string};
/** 分页盘点绑定 rootRevision,nextAfter 是后续页游标,不能跨变更拼接成完整清理依据。 */
export type FileInventoryPage={readonly files:readonly StoredFileInfo[];readonly rootRevision:number;readonly nextAfter?:string};
/** 宿主实现的存储能力;可选字段必须显式探测,缺能力不能假装已完成扫描或原子删除。 */
export type StoragePort = {
/** 可选工作区共享资源仓库,文件/引用保留通过 depot 合同处理。 */
readonly assetDepot?:import('./asset-depot.ts').AssetDepotPort;
/** 在 expectedRootRevision 下按稳定游标读取文件页,revision 不匹配应拒绝。 */
scanFiles?(leader:StorageLeader,input:{readonly expectedRootRevision:number;readonly after?:string;readonly limit:number}):Promise<FileInventoryPage>;
/** atomic-v1 明确声明支持与 Root 一起提交文件删除,不能用普通异步 delete 冒充。 */
readonly fileDeletion?: 'atomic-v1';
/** 取得作用域 leader,已有有效写者时拒绝,而不是悄悄允许两个 writer。 */
claim(scope: StorageScope): Promise<StorageLeader>;
/** 在有效 leader 下恢复最后可靠图像;null 表示没有已提交快照。 */
recover(leader: StorageLeader): Promise<RecoveryImage | null>;
/** 原子提交 DurableBatch 并返回真实完成的 rootRevision,不能提前在请求入队时 resolve。 */
commit(leader: StorageLeader, batch: DurableBatch): Promise<{ readonly durableRootRevision: number }>;
/** 读取指定文件的 Blob,缺失用 undefined;不从文档资源引用猜字节已经存在。 */
readFile(leader: StorageLeader, id: string): Promise<Blob | undefined>;
/** 关闭 adapter 的本地句柄,leader 的异步释放仍通过其 release 合同完成。 */
close(): void;
};