Save and load notes in Zeichen using an external API.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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. }