Save and load notes in Zeichen using the browser's local storage.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

56 rader
1.7 KiB

  1. import Storage, { Collection, OutOfSyncError } from '../../core/src/storage'
  2. import Engine from './Engine'
  3. export default class LocalStorage<T> implements Storage<T> {
  4. private readonly engine: Engine<Collection<T>>
  5. constructor(
  6. private readonly ownerId: string,
  7. private readonly storageId: string,
  8. private readonly getItemId = item => item['id'],
  9. ) {
  10. this.engine = new Engine<Collection<T>>(window.localStorage)
  11. }
  12. private getMeta() {
  13. const oldMeta = this.engine.getCollection(this.storageId)
  14. if (oldMeta === null) {
  15. throw new OutOfSyncError()
  16. }
  17. return oldMeta
  18. }
  19. private existenceCheck(newItem: T) {
  20. return oldItem => this.getItemId(oldItem) === this.getItemId(newItem)
  21. }
  22. async queryItems() {
  23. return this.getMeta().items
  24. }
  25. async saveItem(newItem: T) {
  26. const oldMeta = this.getMeta()
  27. const isExistingItem = oldMeta.items.some(this.existenceCheck(newItem))
  28. const newMeta: Collection<T> = {
  29. items: isExistingItem
  30. ? oldMeta.items.map(oldItem => this.existenceCheck(newItem)(oldItem) ? newItem : oldItem)
  31. : [...oldMeta.items, newItem],
  32. lastModifiedBy: this.ownerId,
  33. lastModifiedAt: new Date(),
  34. }
  35. this.engine.replaceCollection(this.storageId, newMeta)
  36. }
  37. async deleteItem(newItem: T) {
  38. const oldMeta = this.getMeta()
  39. const newItems = oldMeta.items.filter(oldItem => !this.existenceCheck(newItem)(oldItem))
  40. const newMeta: Collection<T> = {
  41. items: newItems,
  42. lastModifiedBy: this.ownerId,
  43. lastModifiedAt: new Date(),
  44. }
  45. this.engine.replaceCollection(this.storageId, newMeta)
  46. return oldMeta.items.length !== newItems.length
  47. }
  48. }