Monorepo containing core modules of Zeichen.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

56 lignes
1.6 KiB

  1. import Storage, { Collection, OutOfSyncError } from '../core/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. }