48 lines
4.6 KiB
TypeScript
48 lines
4.6 KiB
TypeScript
/**
|
||
* 便携持久化端口:定义 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. */
|
||
/** 持久键由账号/工作区/项目组成,不含 view/navigation/authEpoch;身份退役另由宿主与 leader 围栏处理。
|
||
* 类型声明不捕获字符串、不验证权限,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 清单的同次原子提交合同;不表示对象构造后已保存。
|
||
* files 是 Blob 原字节,image/depot 保存逻辑引用/证明;adapter 需在异步前捕获输入并核对身份/删除资格。
|
||
* 需要删除时还须显式 fileDeletion 能力,不能将独立异步删文件视为与 Root 同一事务。 */
|
||
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 可随 release/失效改变;只读类型不代表 active 永远不变。
|
||
* 宿主准入检查不能替代 adapter 在真实 I/O/提交处复核 scope/fence/有效性,接口自身不实现跨进程锁。 */
|
||
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};
|
||
/** 宿主实现的持久协议,声明本身不执行校验/深冻结、获取锁或操作数据库。
|
||
* 可选能力须显式探测;引擎的 ledger generation/Root 发布只是内存事实,commit 成功确认后才推进可靠水位。
|
||
* close 为同步本地句柄收尾,异步 leader.release 独立;失败/取消的 I/O 不自动说明数据从未提交。 */
|
||
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>;
|
||
/** 恢复最后已提交图像,不直接把任意 payload 当合法 Root;codec/engine 仍需版本、结构与身份校验。
|
||
* null 只表示该作用域没有已提交快照,不证明所有本地文件/共享 depot 记录也不存在。 */
|
||
recover(leader: StorageLeader): Promise<RecoveryImage | null>;
|
||
/** adapter 捕获/验证并原子提交批次,返回实际完成的 durableRootRevision;不能在入队/单条写请求成功时提前 resolve。
|
||
* 回执不直接修改 editor 或放行 scheduler,调用方还需核对水位并按同切点恢复调度。 */
|
||
commit(leader: StorageLeader, batch: DurableBatch): Promise<{ readonly durableRootRevision: number }>;
|
||
/** 读取指定文件的 Blob,缺失用 undefined;不从文档资源引用猜字节已经存在。 */
|
||
readFile(leader: StorageLeader, id: string): Promise<Blob | undefined>;
|
||
/** 关闭 adapter 的本地句柄,leader 的异步释放仍通过其 release 合同完成。 */
|
||
close(): void;
|
||
};
|