|
- import { Deserializer, Serializer } from '../core/storage'
-
- const CREATED = 201
- const NO_CONTENT = 204
- const NOT_FOUND = 404
- const GONE = 410
-
- export default class RemoteStorage<U, T> {
- constructor(
- private readonly baseUrl: string,
- private readonly getItemId = item => item['id'],
- private readonly serializers: Map<string, Serializer> = new Map([
- ['*/*', JSON.stringify],
- ['application/json', JSON.stringify],
- ['text/json', JSON.stringify],
- ]),
- private readonly deserializers: Map<string, Deserializer> = new Map([
- ['*/*', JSON.parse],
- ['application/json', JSON.parse],
- ['text/json', JSON.parse],
- ]),
- ) {}
-
- async getCollection(collectionId: string) {
- const response = await window.fetch([this.baseUrl, collectionId].join('/'))
- const contentType = response.headers.get('content-type')
- const { [contentType]: deserializer = this.deserializers.get('*/*'), } = Object.fromEntries(this.deserializers.entries())
- const payload = await response.text()
- return deserializer(payload)
- }
-
- async setItem(collectionId: string, item: U, contentType = 'application/json') {
- const { [contentType]: serializer = this.serializers.get('application/json'), } = Object.fromEntries(this.serializers.entries())
- const response = await window.fetch([this.baseUrl, collectionId, this.getItemId(item)].join('/'), {
- method: 'put',
- body: serializer(item),
- })
- // resource is created
- if (response.status === CREATED) {
- return
- }
- if (100 <= response.status && response.status <= 399) {
- console.warn(`Expected response is ${CREATED}, got ${response.status}.`)
- return
- }
- throw new Error(response.statusText)
- }
-
- async removeItem(collectionId: string, item: U) {
- const response = await window.fetch([this.baseUrl, collectionId, this.getItemId(item)].join('/'), {
- method: 'delete',
- })
- // resource is deleted
- if (response.status === NO_CONTENT) {
- return true
- }
- // resource is already deleted
- if (response.status === NOT_FOUND || response.status === GONE) {
- return false
- }
- if (100 <= response.status && response.status <= 399) {
- console.warn(`Expected response is ${NO_CONTENT}, got ${response.status}.`)
- // assume there's a change in the collection
- return true
- }
- throw new Error(response.statusText)
- }
-
- // TODO do removeCollection for account closing?
- }
|