Certify loaded canvas scopes and publish completeness with runtime queries
This commit is contained in:
@@ -30,7 +30,7 @@ function purgedFileIds(image:RecoveryImage):Set<string>{
|
||||
return result;
|
||||
}
|
||||
function validateImage(image: RecoveryImage) {
|
||||
if (![1,2,3,4,5,6,7].includes(image.formatVersion)) throw fault('unsupported_recovery_version');
|
||||
if (![1,2,3,4,5,6,7,8].includes(image.formatVersion)) throw fault('unsupported_recovery_version');
|
||||
if (!Number.isSafeInteger(image.rootRevision) || image.rootRevision < 0 || !Number.isSafeInteger(image.localRevision) || image.localRevision < 0 || image.localRevision > image.rootRevision || !validJson(image.payload)) throw fault('corrupt_recovery_image');
|
||||
}
|
||||
const requestValue = <T>(request: IDBRequest<T>) => new Promise<T>((resolve, reject) => { request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); });
|
||||
@@ -160,8 +160,8 @@ export function createBrowserStorage(options: { indexedDB?: IDBFactory; locks?:
|
||||
if(!('image' in candidate)&&(candidate.baseRevision!==previous||candidate.baseChecksum!==saved?.checksum))throw fault('recovery_delta_base_mismatch');
|
||||
for(const file of files){if(!file.id||!(file.bytes instanceof Blob))throw fault('invalid_staged_file');if(await requestValue(transaction.objectStore('files').getKey([key,file.id])))throw fault('resource_identity_conflict',[file.id]);transaction.objectStore('files').put(file.bytes,[key,file.id]);}
|
||||
for(const id of deleteFiles)transaction.objectStore('files').delete([key,id]);
|
||||
// A complete cut must not depend on a v7 partial checkpoint in an older reader.
|
||||
if(previous===undefined||(base?.image.formatVersion===7&&image.formatVersion!==7)||image.rootRevision-(metadata.checkpointRevision??0)>=checkpointEvery){
|
||||
// A format transition must not depend on a newer partial checkpoint in an older reader.
|
||||
if(previous===undefined||((base?.image.formatVersion??0)>=7&&base?.image.formatVersion!==image.formatVersion)||image.rootRevision-(metadata.checkpointRevision??0)>=checkpointEvery){
|
||||
transaction.objectStore('checkpoints').put(stored,[key,image.rootRevision]);if(metadata.checkpointRevision!==undefined)transaction.objectStore('checkpoints').delete([key,metadata.checkpointRevision]);transaction.objectStore('journal').delete(IDBKeyRange.bound([key,0],[key,image.rootRevision]));metadata.checkpointRevision=image.rootRevision;
|
||||
}else transaction.objectStore('journal').put(candidate,[key,image.rootRevision]);
|
||||
transaction.objectStore('metadata').put({...metadata,throughRevision:image.rootRevision},key);return{durableRootRevision:image.rootRevision};
|
||||
|
||||
Reference in New Issue
Block a user