pauls-dat-api
Version:
Library of functions that make working with dat / hyperdrive easier.
101 lines (52 loc) • 4.09 kB
JavaScript
var findEntryByContentBlock = function () {var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(
function _callee(archive, block) {var lo, hi, nextCursor, cursor, entry, st, origCursor, range;return regeneratorRuntime.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:if (!(
archive.metadata.length <= 0)) {_context.next = 2;break;}return _context.abrupt('return');case 2:
// do a binary search
lo = 1;
hi = archive.metadata.length;
nextCursor = function nextCursor() {return (hi + lo) / 2 | 0;};
cursor = nextCursor();case 6:if (!(
lo <= hi)) {_context.next = 33;break;}
// find a file entry in the current [lo, hi] range
entry = void 0;
st = void 0;
origCursor = cursor;case 10:if (!
true) {_context.next = 26;break;}_context.next = 13;return (
new Promise(function (resolve) {return (
archive.tree._getAndDecode(cursor, {}, function (err, entry) {
if (err) console.warn('Failed to fetch block', block, err);
resolve(entry);
}));}));case 13:entry = _context.sent;if (
entry) {_context.next = 16;break;}return _context.abrupt('return');case 16:if (!
entry.value) {_context.next = 20;break;}
st = archive.tree._codec.decode(entry.value);if (!(
st.blocks !== 0)) {_context.next = 20;break;}return _context.abrupt('break', 26);case 20:
cursor++;
if (cursor > hi) cursor = lo; // overflow back to lo
if (!(cursor === origCursor)) {_context.next = 24;break;}return _context.abrupt('return');case 24:_context.next = 10;break;case 26:
// check the range
range = {
name: entry.name,
start: st.offset,
end: st.offset + st.blocks - 1 };if (!(
block >= range.start && block <= range.end)) {_context.next = 29;break;}return _context.abrupt('return',
range);case 29:
// adjust range and try again
if (block > range.end) {
lo = cursor + 1;
} else {
hi = cursor - 1;
}
cursor = nextCursor();_context.next = 6;break;case 33:case 'end':return _context.stop();}}}, _callee, this);}));return function findEntryByContentBlock(_x, _x2) {return _ref.apply(this, arguments);};}();function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}var callMeMaybe = require('call-me-maybe');var _require = require('beaker-error-constants'),NotFoundError = _require.NotFoundError,DestDirectoryNotEmpty = _require.DestDirectoryNotEmpty;function toBeakerError(err, info) {if (err.notFound || err.code === 'ENOENT' || err.code === 'ENOTDIR') {return new NotFoundError();} else if (err.toString().indexOf('Directory is not empty') !== -1) {return new DestDirectoryNotEmpty();} else {// TODO cover all error types
console.error(`Pauls-Dat-API: Unhandled error type from ${info}`, err);return new Error('Unexpected error: ' + err.toString());}} // helper to convert an encoding to something acceptable
function toValidEncoding(str) {if (!str) return 'utf8';if (!['utf8', 'utf-8', 'hex', 'base64'].includes(str)) return undefined;return str;} // helper to call promise-generating function
function maybe(cb, p) {if (typeof p === 'function') {p = p();}return callMeMaybe(cb, p);}
function tonix(str) {
return str.replace(/\\/g, '/');
}
module.exports = {
findEntryByContentBlock,
toBeakerError,
toValidEncoding,
maybe,
tonix };
;