|
- import Storage, { Collection, OutOfSyncError } from '../core/storage'
- import Engine from './Engine'
-
- export default class LocalStorage<T> implements Storage<T> {
- private readonly engine: Engine<Collection<T>>
-
- constructor(
- private readonly ownerId: string,
- private readonly storageId: string,
- private readonly getItemId = item => item['id'],
- ) {
- this.engine = new Engine<Collection<T>>(window.localStorage)
- }
-
- private getMeta() {
- const oldMeta = this.engine.getCollection(this.storageId)
- if (oldMeta === null) {
- throw new OutOfSyncError()
- }
- return oldMeta
- }
-
- private existenceCheck(newItem: T) {
- return oldItem => this.getItemId(oldItem) === this.getItemId(newItem)
- }
-
- async queryItems() {
- return this.getMeta().items
- }
-
- async saveItem(newItem: T) {
- const oldMeta = this.getMeta()
- const isExistingItem = oldMeta.items.some(this.existenceCheck(newItem))
- const newMeta: Collection<T> = {
- items: isExistingItem
- ? oldMeta.items.map(oldItem => this.existenceCheck(newItem)(oldItem) ? newItem : oldItem)
- : [...oldMeta.items, newItem],
- lastModifiedBy: this.ownerId,
- lastModifiedAt: new Date(),
- }
- this.engine.replaceCollection(this.storageId, newMeta)
- }
-
- async deleteItem(newItem: T) {
- const oldMeta = this.getMeta()
- const newItems = oldMeta.items.filter(oldItem => !this.existenceCheck(newItem)(oldItem))
- const newMeta: Collection<T> = {
- items: newItems,
- lastModifiedBy: this.ownerId,
- lastModifiedAt: new Date(),
- }
- this.engine.replaceCollection(this.storageId, newMeta)
- return oldMeta.items.length !== newItems.length
- }
- }
|