import Hook from '../hook'; import { API } from 'aws-amplify'; import { QueryRequest, QueryResponse, SaveRequest, SaveResponse, ErrorResponse, Response, HistoryRequest, HistoryResponse, } from 'sync-ql'; import { equals } from 'sync-ql'; export const NoData = null as any; export const defaultHeaders = { 'Accept': 'application/json' } export type { QueryRequest, QueryResponse, SaveRequest, SaveResponse, HistoryRequest, HistoryResponse, ErrorResponse, Response } export abstract class Service { protected constructor(service: string) { this.cache = new CacheService(service); this.request = new RequestService(service); } protected readonly cache: CacheService; protected readonly request: RequestService; } class RequestService { constructor(private service: string) { } /****************************** METHODS ******************************/ public async get(url: string, params?: { [key: string]: string }, headers: { [key: string]: string } = defaultHeaders): Promise> { try { url = url.startsWith('/') ? url : `/${url}` const result = await API.get(this.service, url, { headers, queryStringParameters: params }); return result ? result : { type: 500, data: NoData } } catch (err) { console.log(err); throw err; } } public async post(url: string, params?: { [key: string]: string }, data?: any, headers: { [key: string]: string } = defaultHeaders): Promise> { try { url = url.startsWith('/') ? url : `/${url}` const result = await API.post(this.service, url, { headers, body: data, queryStringParameters: params }); return result ? result : { type: 500, data: NoData } } catch (err) { console.log(err); throw err; } } public async put(url: string, params?: { [key: string]: string }, data?: any, headers: { [key: string]: string } = defaultHeaders): Promise> { try { url = url.startsWith('/') ? url : `/${url}` const result = await API.put(this.service, url, { headers, body: data, queryStringParameters: params }); return result ? result : { type: 500, data: NoData } } catch (err) { console.log(err); throw err; } } public async delete(url: string, params?: { [key: string]: string }, headers: { [key: string]: string } = defaultHeaders): Promise> { try { url = url.startsWith('/') ? url : `/${url}` const result = await API.del(this.service, url, { headers, queryStringParameters: params }); return result ? result : { type: 500, data: NoData } } catch (err) { console.log(err); throw err; } } } class CacheService { private cache: { [url: string]: any } = {} constructor(private service: string) { } /****************************** METHODS ******************************/ public async get(url: string, params?: { [key: string]: string }, headers: { [key: string]: string } = defaultHeaders): Promise> { url = url.startsWith('/') ? url : `/${url}` if (!this.cache[url]) { this.cache[url] = { context: { method: 'get', params: NoData, data: NoData, }, response: NoData, loading: false, } } if (this.cache[url].loading) { return this.cache[url].loading; } if (equals(this.cache[url].context, { method: 'get', params })) { return new Promise((resolve) => resolve(this.cache[url].response)); } this.cache[url].context = { method: 'get', params } return (this.cache[url].loading = new Promise((resolve, reject) => { API.get(this.service, url, { headers, queryStringParameters: params }) .then(result => { this.cache[url].loading = false; resolve( result ? this.cache[url].response = result : { type: 500, data: NoData } ) }) .catch(err => { this.cache[url].loading = false; reject(err) }) })) as any; } public post(url: string, params?: { [key: string]: string }, data?: any, headers: { [key: string]: string } = defaultHeaders): Promise> { url = url.startsWith('/') ? url : `/${url}` if (!this.cache[url]) { this.cache[url] = { context: { method: 'post', params: NoData, data: NoData, }, response: NoData, loading: false, } } if (this.cache[url].loading) { return this.cache[url].loading; } if (equals(this.cache[url].context, { method: 'post', params, data })) { return new Promise((resolve) => resolve(this.cache[url].response)); } this.cache[url].context = { method: 'post', params, data } return (this.cache[url].loading = new Promise((resolve, reject) => { API.post(this.service, url, { headers, queryStringParameters: params, body: data }) .then(result => { this.cache[url].loading = false; resolve( result ? this.cache[url].response = result : { type: 500, data: NoData } ) }) .catch(err => { this.cache[url].loading = false; reject(err) }) })) as any; } public clear(url?: string) { if (url) { delete this.cache[url]; } else this.cache = {} } } export const send = { request: async function load(callback: () => Promise, loading?: 'DONT SHOW LOADING') { try { if (callback) { if (loading !== 'DONT SHOW LOADING') { Hook.loading().start(); } await callback(); } } catch (err) { console.log(err) } finally { if (callback && loading !== 'DONT SHOW LOADING') { Hook.loading().stop(); } } } }