API/api.medcify.app/node_modules/js-git/mixins/indexed-db.js
2022-09-26 11:41:44 +05:30

148 lines
3.8 KiB
JavaScript

"use strict";
/*global indexedDB*/
var codec = require('../lib/object-codec.js');
var sha1 = require('git-sha1');
var modes = require('../lib/modes.js');
var db;
mixin.init = init;
mixin.loadAs = loadAs;
mixin.saveAs = saveAs;
module.exports = mixin;
function init(callback) {
db = null;
var request = indexedDB.open("tedit", 1);
// We can only create Object stores in a versionchange transaction.
request.onupgradeneeded = function(evt) {
var db = evt.target.result;
if (evt.dataLoss && evt.dataLoss !== "none") {
return callback(new Error(evt.dataLoss + ": " + evt.dataLossMessage));
}
// A versionchange transaction is started automatically.
evt.target.transaction.onerror = onError;
if(db.objectStoreNames.contains("objects")) {
db.deleteObjectStore("objects");
}
if(db.objectStoreNames.contains("refs")) {
db.deleteObjectStore("refs");
}
db.createObjectStore("objects", {keyPath: "hash"});
db.createObjectStore("refs", {keyPath: "path"});
};
request.onsuccess = function (evt) {
db = evt.target.result;
callback();
};
request.onerror = onError;
}
function mixin(repo, prefix) {
if (!prefix) throw new Error("Prefix required");
repo.refPrefix = prefix;
repo.saveAs = saveAs;
repo.loadAs = loadAs;
repo.readRef = readRef;
repo.updateRef = updateRef;
repo.hasHash = hasHash;
}
function onError(evt) {
console.error("error", evt.target.error);
}
function saveAs(type, body, callback, forcedHash) {
if (!callback) return saveAs.bind(this, type, body);
var hash;
try {
var buffer = codec.frame({type:type,body:body});
hash = forcedHash || sha1(buffer);
}
catch (err) { return callback(err); }
var trans = db.transaction(["objects"], "readwrite");
var store = trans.objectStore("objects");
var entry = { hash: hash, type: type, body: body };
var request = store.put(entry);
request.onsuccess = function() {
// console.warn("SAVE", type, hash);
callback(null, hash, body);
};
request.onerror = function(evt) {
callback(new Error(evt.value));
};
}
function loadAs(type, hash, callback) {
if (!callback) return loadAs.bind(this, type, hash);
loadRaw(hash, function (err, entry) {
if (!entry) return callback(err);
if (type !== entry.type) {
return callback(new TypeError("Type mismatch"));
}
callback(null, entry.body, hash);
});
}
function loadRaw(hash, callback) {
var trans = db.transaction(["objects"], "readwrite");
var store = trans.objectStore("objects");
var request = store.get(hash);
request.onsuccess = function(evt) {
var entry = evt.target.result;
if (!entry) return callback();
return callback(null, entry);
};
request.onerror = function(evt) {
callback(new Error(evt.value));
};
}
function hasHash(hash, callback) {
if (!callback) return hasHash.bind(this, hash);
loadRaw(hash, function (err, body) {
if (err) return callback(err);
return callback(null, !!body);
});
}
function readRef(ref, callback) {
if (!callback) return readRef.bind(this, ref);
var key = this.refPrefix + "/" + ref;
var trans = db.transaction(["refs"], "readwrite");
var store = trans.objectStore("refs");
var request = store.get(key);
request.onsuccess = function(evt) {
var entry = evt.target.result;
if (!entry) return callback();
callback(null, entry.hash);
};
request.onerror = function(evt) {
callback(new Error(evt.value));
};
}
function updateRef(ref, hash, callback) {
if (!callback) return updateRef.bind(this, ref, hash);
var key = this.refPrefix + "/" + ref;
var trans = db.transaction(["refs"], "readwrite");
var store = trans.objectStore("refs");
var entry = { path: key, hash: hash };
var request = store.put(entry);
request.onsuccess = function() {
callback();
};
request.onerror = function(evt) {
callback(new Error(evt.value));
};
}