Stackedit/src/services/providers/couchdbWorkspaceProvider.js

219 lines
6.3 KiB
JavaScript
Raw Normal View History

2018-01-24 07:31:54 +00:00
import store from '../../store';
import couchdbHelper from './helpers/couchdbHelper';
2018-04-27 14:37:05 +00:00
import Provider from './common/Provider';
2018-01-24 07:31:54 +00:00
import utils from '../utils';
2018-04-27 14:37:05 +00:00
let syncLastSeq;
export default new Provider({
2018-01-24 07:31:54 +00:00
id: 'couchdbWorkspace',
getToken() {
return store.getters['workspace/syncToken'];
},
2018-05-13 13:27:33 +00:00
async initWorkspace() {
2018-01-24 07:31:54 +00:00
const dbUrl = (utils.queryParams.dbUrl || '').replace(/\/?$/, ''); // Remove trailing /
2018-04-27 14:37:05 +00:00
const workspaceParams = {
2018-01-24 07:31:54 +00:00
providerId: this.id,
dbUrl,
};
2018-04-27 14:37:05 +00:00
const workspaceId = utils.makeWorkspaceId(workspaceParams);
2018-01-24 07:31:54 +00:00
const getToken = () => store.getters['data/couchdbTokens'][workspaceId];
const getWorkspace = () => store.getters['data/sanitizedWorkspaces'][workspaceId];
if (!getToken()) {
// Create token
store.dispatch('data/setCouchdbToken', {
sub: workspaceId,
dbUrl,
});
}
2018-05-13 13:27:33 +00:00
// Create the workspace
let workspace = getWorkspace();
if (!workspace) {
// Make sure the database exists and retrieve its name
let db;
try {
db = await couchdbHelper.getDb(getToken());
} catch (e) {
throw new Error(`${dbUrl} is not accessible. Make sure you have the proper permissions.`);
}
store.dispatch('data/patchWorkspaces', {
[workspaceId]: {
id: workspaceId,
name: db.db_name,
providerId: this.id,
dbUrl,
},
});
workspace = getWorkspace();
}
// Fix the URL hash
utils.setQueryParams(workspaceParams);
if (workspace.url !== window.location.href) {
store.dispatch('data/patchWorkspaces', {
[workspace.id]: {
...workspace,
url: window.location.href,
},
2018-01-24 07:31:54 +00:00
});
2018-05-13 13:27:33 +00:00
}
return getWorkspace();
2018-01-24 07:31:54 +00:00
},
2018-05-13 13:27:33 +00:00
async getChanges() {
2018-01-24 07:31:54 +00:00
const syncToken = store.getters['workspace/syncToken'];
const lastSeq = store.getters['data/localSettings'].syncLastSeq;
2018-05-13 13:27:33 +00:00
const result = await couchdbHelper.getChanges(syncToken, lastSeq);
const changes = result.changes.filter((change) => {
if (!change.deleted && change.doc) {
change.item = change.doc.item;
if (!change.item || !change.item.id || !change.item.type) {
return false;
}
// Build sync data
change.syncData = {
id: change.id,
itemId: change.item.id,
type: change.item.type,
hash: change.item.hash,
rev: change.doc._rev, // eslint-disable-line no-underscore-dangle
};
}
change.syncDataId = change.id;
return true;
});
syncLastSeq = result.lastSeq;
return changes;
2018-01-24 07:31:54 +00:00
},
2018-04-27 14:37:05 +00:00
onChangesApplied() {
2018-01-30 07:36:33 +00:00
store.dispatch('data/patchLocalSettings', {
2018-04-27 14:37:05 +00:00
syncLastSeq,
2018-01-30 07:36:33 +00:00
});
},
2018-06-07 23:56:11 +00:00
async saveWorkspaceItem(item, syncData) {
2018-01-30 07:36:33 +00:00
const syncToken = store.getters['workspace/syncToken'];
2018-05-13 13:27:33 +00:00
const { id, rev } = couchdbHelper.uploadDocument({
token: syncToken,
2018-01-30 07:36:33 +00:00
item,
2018-05-13 13:27:33 +00:00
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
return {
// Build sync data
id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev,
};
2018-01-30 07:36:33 +00:00
},
2018-06-07 23:56:11 +00:00
removeWorkspaceItem(syncData) {
2018-01-30 07:36:33 +00:00
const syncToken = store.getters['workspace/syncToken'];
return couchdbHelper.removeDocument(syncToken, syncData.id, syncData.rev);
},
2018-06-07 23:56:11 +00:00
async downloadWorkspaceContent(token, syncData) {
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, syncData.id);
const rev = body._rev; // eslint-disable-line no-underscore-dangle
const item = Provider.parseContent(body.attachments.data, body.item.id);
return {
item,
syncData: {
...syncData,
hash: item.hash,
rev,
},
};
2018-01-30 07:36:33 +00:00
},
2018-06-07 23:56:11 +00:00
async downloadWorkspaceData(token, dataId, syncData) {
2018-01-30 07:36:33 +00:00
if (!syncData) {
2018-06-07 23:56:11 +00:00
return {};
2018-05-13 13:27:33 +00:00
}
2018-06-07 23:56:11 +00:00
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, syncData.id);
const item = utils.addItemHash(JSON.parse(body.attachments.data));
2018-05-13 13:27:33 +00:00
const rev = body._rev; // eslint-disable-line no-underscore-dangle
2018-06-07 23:56:11 +00:00
return {
item,
syncData: {
...syncData,
hash: item.hash,
rev,
},
};
2018-01-30 07:36:33 +00:00
},
2018-06-07 23:56:11 +00:00
async uploadWorkspaceContent(token, item, syncData) {
const res = await couchdbHelper.uploadDocument({
token,
item: {
id: item.id,
type: item.type,
hash: item.hash,
},
data: Provider.serializeContent(item),
dataType: 'text/plain',
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
// Return new sync data
return {
id: res.id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev: res.rev,
};
2018-01-30 07:36:33 +00:00
},
2018-06-07 23:56:11 +00:00
async uploadWorkspaceData(token, item, syncData) {
const res = await couchdbHelper.uploadDocument({
token,
item: {
id: item.id,
type: item.type,
hash: item.hash,
},
data: JSON.stringify(item),
dataType: 'application/json',
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
// Return new sync data
return {
id: res.id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev: res.rev,
};
2018-01-30 07:36:33 +00:00
},
2018-05-13 13:27:33 +00:00
async listRevisions(token, fileId) {
const syncData = Provider.getContentSyncData(fileId);
const body = await couchdbHelper.retrieveDocumentWithRevisions(token, syncData.id);
const revisions = [];
body._revs_info.forEach((revInfo) => { // eslint-disable-line no-underscore-dangle
if (revInfo.status === 'available') {
revisions.push({
id: revInfo.rev,
sub: null,
created: null,
2018-01-30 07:36:33 +00:00
});
2018-05-13 13:27:33 +00:00
}
});
return revisions;
2018-01-30 07:36:33 +00:00
},
2018-05-13 13:27:33 +00:00
async loadRevision(token, fileId, revision) {
const syncData = Provider.getContentSyncData(fileId);
const body = await couchdbHelper.retrieveDocument(token, syncData.id, revision.id);
revision.sub = body.sub;
revision.created = body.time || 1; // Has to be truthy to prevent from loading several times
2018-01-30 07:36:33 +00:00
},
2018-05-13 13:27:33 +00:00
async getRevisionContent(token, fileId, revisionId) {
const syncData = Provider.getContentSyncData(fileId);
const body = await couchdbHelper
.retrieveDocumentWithAttachments(token, syncData.id, revisionId);
return Provider.parseContent(body.attachments.data, body.item.id);
2018-01-30 07:36:33 +00:00
},
2018-01-24 07:31:54 +00:00
});