logseq/resources/js/worker.js

308 lines
7.3 KiB
JavaScript

importScripts(
// Batched optimization
"./lightning-fs.min.js?v=0.0.2.3",
"./isomorphic-git/1.7.4/index.umd.min.js",
"./isomorphic-git/1.7.4/http-web-index.umd.js",
// Fixed a bug
"./magic_portal.js"
);
const detect = () => {
if (typeof window !== 'undefined' && !self.skipWaiting) {
return 'window'
} else if (typeof self !== 'undefined' && !self.skipWaiting) {
return 'Worker'
} else if (typeof self !== 'undefined' && self.skipWaiting) {
return 'ServiceWorker'
}
};
function basicAuth (username, token) {
return "Basic " + btoa(username + ":" + token);
}
const fsName = 'logseq';
const createFS = () => new LightningFS(fsName);
let fs = createFS();
let pfs = fs.promises;
if (detect() === 'Worker') {
const portal = new MagicPortal(self);
portal.set('git', git);
portal.set('fs', fs);
portal.set('pfs', pfs);
portal.set('gitHttp', GitHttp);
portal.set('workerThread', {
setConfig: function (dir, path, value) {
return git.setConfig ({
fs,
dir,
path,
value
});
},
clone: function (dir, url, corsProxy, depth, branch, username, token) {
return git.clone ({
fs,
dir,
http: GitHttp,
url,
corsProxy,
ref: branch,
singleBranch: true,
depth,
headers: {
"Authorization": basicAuth(username, token)
}
});
},
fetch: function (dir, url, corsProxy, depth, branch, username, token) {
return git.fetch ({
fs,
dir,
http: GitHttp,
url,
corsProxy,
ref: branch,
singleBranch: true,
depth,
headers: {
"Authorization": basicAuth(username, token)
}
});
},
pull: function (dir, corsProxy, branch, username, token) {
return git.pull ({
fs,
dir,
http: GitHttp,
corsProxy,
ref: branch,
singleBranch: true,
// fast: true,
headers: {
"Authorization": basicAuth(username, token)
}
});
},
push: function (dir, corsProxy, branch, force, username, token) {
return git.push ({
fs,
dir,
http: GitHttp,
ref: branch,
corsProxy,
remote: "origin",
force,
headers: {
"Authorization": basicAuth(username, token)
}
});
},
merge: function (dir, branch) {
return git.merge ({
fs,
dir,
ours: branch,
theirs: "remotes/origin/" + branch,
// fastForwardOnly: true
});
},
checkout: function (dir, branch) {
return git.checkout ({
fs,
dir,
ref: branch,
});
},
log: function (dir, branch, depth) {
return git.log ({
fs,
dir,
ref: branch,
depth,
singleBranch: true
})
},
add: function (dir, file) {
return git.add ({
fs,
dir,
filepath: file
});
},
remove: function (dir, file) {
return git.remove ({
fs,
dir,
filepath: file
});
},
commit: function (dir, message, name, email, parent) {
if (parent) {
return git.commit ({
fs,
dir,
message,
author: {name: name,
email: email},
parent: parent
});
} else {
return git.commit ({
fs,
dir,
message,
author: {name: name,
email: email}
});
}
},
readCommit: function (dir, oid) {
return git.readCommit ({
fs,
dir,
oid
});
},
readBlob: function (dir, oid, path) {
return git.readBlob ({
fs,
dir,
oid,
path
});
},
writeRef: function (dir, branch, oid) {
return git.writeRef ({
fs,
dir,
ref: "refs/heads/" + branch,
value: oid,
force: true
});
},
resolveRef: function (dir, ref) {
return git.resolveRef ({
fs,
dir,
ref
});
},
listFiles: function (dir, branch) {
return git.listFiles ({
fs,
dir,
ref: branch
});
},
rimraf: async function (path) {
// try {
// // First assume path is itself a file
// await pfs.unlink(path)
// // if that worked we're done
// return
// } catch (err) {
// // Otherwise, path must be a directory
// if (err.code !== 'EISDIR') throw err
// }
// Knowing path is a directory,
// first, assume everything inside path is a file.
let files = await pfs.readdir(path);
for (let file of files) {
let child = path + '/' + file
try {
await pfs.unlink(child)
} catch (err) {
if (err.code !== 'EISDIR') throw err
}
}
// Assume what's left are directories and recurse.
let dirs = await pfs.readdir(path)
for (let dir of dirs) {
let child = path + '/' + dir
await rimraf(child, pfs)
}
// Finally, delete the empty directory
await pfs.rmdir(path)
},
getFileStateChanges: async function (commitHash1, commitHash2, dir) {
return git.walk({
fs,
dir,
trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })],
map: async function(filepath, [A, B]) {
var type = 'equal';
if (A === null) {
type = "add";
}
if (B === null) {
type = "remove";
}
// ignore directories
if (filepath === '.') {
return
}
if ((A !== null && (await A.type()) === 'tree')
||
(B !== null && (await B.type()) === 'tree')) {
return
}
// generate ids
const Aoid = A !== null && await A.oid();
const Boid = B !== null && await B.oid();
if (type === "equal") {
// determine modification type
if (Aoid !== Boid) {
type = 'modify'
}
if (Aoid === undefined) {
type = 'add'
}
if (Boid === undefined) {
type = 'remove'
}
}
if (Aoid === undefined && Boid === undefined) {
console.log('Something weird happened:')
console.log(A)
console.log(B)
}
return {
path: `/${filepath}`,
type: type,
}
},
})
},
statusMatrix: async function (dir) {
return git.statusMatrix({ fs, dir });
},
statusMatrixChanged: async function (dir) {
return (await git.statusMatrix({ fs, dir }))
.filter(([_, head, workDir, stage]) => !(head == 1 && workDir == 1 && stage == 1));
},
getChangedFiles: async function (dir) {
try {
const FILE = 0, HEAD = 1, WORKDIR = 2;
let filenames = (await git.statusMatrix({ fs, dir }))
.filter(row => row[HEAD] !== row[WORKDIR])
.map(row => row[FILE]);
return filenames;
} catch (err) {
console.error(err);
return [];
}
}
});
// self.addEventListener("message", ({ data }) => console.log(data));
}