@magicbell/react-headless
Version:
Hooks to build a notification inbox
68 lines (58 loc) • 1.93 kB
text/typescript
import humps from 'humps';
import { deleteAPI, fetchAPI } from '../../lib/ajax.js';
import { QueryParams } from '../../types/INotificationsStoresCollection.js';
/**
* Class to represent a client that interacts with the MagicBell API.
*
* @example
* class NotificationRepo extends RemoteRepository<Notification, NotificationStore> {}
*/
export default abstract class RemoteRepository<Item, Collection> {
remotePathOrUrl: string;
constructor(remotePathOrUrl: string) {
this.remotePathOrUrl = remotePathOrUrl;
}
/**
* Get an element from the API server by ID.
*
* @example
* const notification = await repo.get('3df592eb-5f09dd6b');
*/
async get(id: string | number): Promise<Item> {
const url = `${this.remotePathOrUrl}/${id}`;
const json = await fetchAPI(url);
return humps.camelizeKeys(json) as Item;
}
/**
* Get elements that match params from the API server.
*
* @example
* const notifications = await repo.findBy({ read: false });
*/
async findBy(queryParams?: QueryParams): Promise<Collection | void> {
try {
const json = await fetchAPI(this.remotePathOrUrl, queryParams);
return humps.camelizeKeys(json) as Collection;
} catch (error) {
// Don't throw Network Errors. Browsers log these themselves and the realtime connection makes
// MagicBell sensitive to connection errors. We don't want to have these flooding consumer logs.
if (/Network Error/.test(error.message)) {
return;
}
// rethrow so upstream can handle all other errors
throw error;
}
}
/**
* Delete an element by ID from the API server.
*
* @example
* const deleted = await repo.delete('3df592eb-5f09dd6b');
*/
delete(id: string | number): Promise<boolean> {
const url = `${this.remotePathOrUrl}/${id}`;
return deleteAPI(url)
.then(() => true)
.catch(() => false);
}
}