Save and load notes in Zeichen using an external API.
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.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { Deserializer, Serializer } from '../../core/src/storage'
  2. const CREATED = 201
  3. const NO_CONTENT = 204
  4. const NOT_FOUND = 404
  5. const GONE = 410
  6. export default class RemoteStorage<U, T> {
  7. constructor(
  8. private readonly baseUrl: string,
  9. private readonly getItemId = item => item['id'],
  10. private readonly serializers: Map<string, Serializer> = new Map([
  11. ['*/*', JSON.stringify],
  12. ['application/json', JSON.stringify],
  13. ['text/json', JSON.stringify],
  14. ]),
  15. private readonly deserializers: Map<string, Deserializer> = new Map([
  16. ['*/*', JSON.parse],
  17. ['application/json', JSON.parse],
  18. ['text/json', JSON.parse],
  19. ]),
  20. ) {}
  21. async getCollection(collectionId: string) {
  22. const response = await window.fetch([this.baseUrl, collectionId].join('/'))
  23. const contentType = response.headers.get('content-type')
  24. const { [contentType]: deserializer = this.deserializers.get('*/*'), } = Object.fromEntries(this.deserializers.entries())
  25. const payload = await response.text()
  26. return deserializer(payload)
  27. }
  28. async setItem(collectionId: string, item: U, contentType = 'application/json') {
  29. const { [contentType]: serializer = this.serializers.get('application/json'), } = Object.fromEntries(this.serializers.entries())
  30. const response = await window.fetch([this.baseUrl, collectionId, this.getItemId(item)].join('/'), {
  31. method: 'put',
  32. body: serializer(item),
  33. })
  34. // resource is created
  35. if (response.status === CREATED) {
  36. return
  37. }
  38. if (100 <= response.status && response.status <= 399) {
  39. console.warn(`Expected response is ${CREATED}, got ${response.status}.`)
  40. return
  41. }
  42. throw new Error(response.statusText)
  43. }
  44. async removeItem(collectionId: string, item: U) {
  45. const response = await window.fetch([this.baseUrl, collectionId, this.getItemId(item)].join('/'), {
  46. method: 'delete',
  47. })
  48. // resource is deleted
  49. if (response.status === NO_CONTENT) {
  50. return true
  51. }
  52. // resource is already deleted
  53. if (response.status === NOT_FOUND || response.status === GONE) {
  54. return false
  55. }
  56. if (100 <= response.status && response.status <= 399) {
  57. console.warn(`Expected response is ${NO_CONTENT}, got ${response.status}.`)
  58. // assume there's a change in the collection
  59. return true
  60. }
  61. throw new Error(response.statusText)
  62. }
  63. // TODO do removeCollection for account closing?
  64. }