Files
notesnook/packages/core/database/indexed-collection.js

83 lines
2.1 KiB
JavaScript
Raw Normal View History

import Storage from "./storage";
2020-11-05 15:50:10 +05:00
import HyperSearch from "hypersearch";
import { getSchema } from "./schemas";
import PersistentCachedMap from "./persistentcachedmap";
import PersistentMap from "./persistentmap";
import sort from "fast-sort";
2020-03-19 11:30:05 +05:00
export default class IndexedCollection {
/**
*
* @param {Storage} storage
* @param {string} type
*/
constructor(storage, type) {
2020-11-05 15:50:10 +05:00
this.type = type;
this.storage = storage;
2020-11-16 12:57:39 +05:00
this.indexKey = `${this.type}Index`;
this.storeKey = `${this.type}Store`;
2020-03-19 11:30:05 +05:00
}
clear() {
return this.search.clear();
}
2020-03-19 11:30:05 +05:00
async init() {
const store = new PersistentMap(`${this.type}Store`, this.storage);
await store.init();
this.search = new HyperSearch({
schema: getSchema(this.type),
tokenizer: "forward",
store,
2020-11-16 12:57:39 +05:00
onIndexUpdated: async () => {
await this.storage.write(this.indexKey, this.search.indexer.export());
},
});
2020-11-16 12:57:39 +05:00
const index = await this.storage.read(this.indexKey);
this.search.indexer.import(index);
2020-03-19 11:30:05 +05:00
}
async addItem(item) {
const exists = this.exists(item.id);
2020-03-19 11:30:05 +05:00
if (!exists) item.dateCreated = item.dateCreated || Date.now();
await this._upsertItem(item);
2020-03-19 11:30:05 +05:00
}
/**
* @protected
*/
async _upsertItem(item) {
2020-03-19 11:30:05 +05:00
if (!item.id) throw new Error("The item must contain the id field.");
// if item is newly synced, remote will be true.
item.dateEdited = item.remote ? item.dateEdited : Date.now();
// the item has become local now, so remove the flag.
delete item.remote;
const exists = this.exists(item.id);
if (!exists) await this.search.addDoc(item);
else await this.search.updateDoc(item.id, item);
2020-03-19 11:30:05 +05:00
}
2020-11-05 15:50:10 +05:00
async removeItem(id) {
await this.search.remove(id);
await this._upsertItem({
id,
deleted: true,
dateCreated: Date.now(),
dateEdited: Date.now(),
});
2020-03-19 11:30:05 +05:00
}
async exists(id) {
const item = await this.getItem(id);
return item && !item.deleted;
2020-03-19 11:30:05 +05:00
}
getItem(id) {
return this.search.getById(id);
2020-03-19 11:30:05 +05:00
}
2020-03-19 12:38:33 +05:00
async getItems() {
return await this.search.getAllDocs();
2020-03-19 12:38:33 +05:00
}
2020-03-19 11:30:05 +05:00
}