UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

602 lines (591 loc) 17 kB
import { HttpClient } from '@angular/common/http'; import { Subject, throwError } from 'rxjs'; import { filter, map, catchError, finalize, tap } from 'rxjs/operators'; import { Injectable, InjectionToken, defineInjectable, inject } from '@angular/core'; import { isFunction, isObject, isNumber, isString, EntityService, isDefined } from '@datorama/akita'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {string} */ const HttpMethod = { GET: 'GET', POST: 'POST', PUT: 'PUT', PATCH: 'PATCH', DELETE: 'DELETE', }; /** @type {?} */ const ofType = (/** * @param {?} type * @return {?} */ (type) => filter((/** * @param {?} action * @return {?} */ (action) => action.type === type))); /** @type {?} */ const filterMethod = (/** * @param {?} method * @return {?} */ (method) => filter((/** * @param {?} action * @return {?} */ (action) => action.method === method))); /** @type {?} */ const filterStore = (/** * @param {?} name * @return {?} */ (name) => filter((/** * @param {?} action * @return {?} */ (action) => action.storeName === name))); class NgEntityServiceNotifier { constructor() { this.dispatcher = new Subject(); this.action$ = this.dispatcher.asObservable(); } /** * @param {?} event * @return {?} */ dispatch(event) { this.dispatcher.next(event); } } NgEntityServiceNotifier.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgEntityServiceNotifier.ngInjectableDef = defineInjectable({ factory: function NgEntityServiceNotifier_Factory() { return new NgEntityServiceNotifier(); }, token: NgEntityServiceNotifier, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgEntityServiceLoader { constructor() { this.dispatcher = new Subject(); this.loading$ = this.dispatcher.asObservable(); } /** * @param {?} event * @return {?} */ dispatch(event) { this.dispatcher.next(event); } /** * @param {?=} name * @return {?} */ loadersFor(name) { /** @type {?} */ const filterStore$$1 = filter((/** * @param {?} __0 * @return {?} */ ({ storeName }) => (name ? storeName === name : true))); /** @type {?} */ const filterMethod$$1 = (/** * @param {?} mthd * @return {?} */ mthd => filter((/** * @param {?} __0 * @return {?} */ ({ method }) => { return isFunction(mthd) ? mthd(method) : method === mthd; }))); /** @type {?} */ const actionBased = (/** * @param {?} current * @return {?} */ (current) => this.loading$.pipe(filterStore$$1, filterMethod$$1(current), map((/** * @param {?} action * @return {?} */ action => action.loading)))); /** @type {?} */ const idBased = (/** * @param {?} id * @param {?} mthd * @return {?} */ (id, mthd) => this.loading$.pipe(filterStore$$1, filterMethod$$1(mthd), filter((/** * @param {?} action * @return {?} */ action => action.entityId === id)), map((/** * @param {?} action * @return {?} */ action => action.loading)))); return { get$: actionBased(HttpMethod.GET), add$: actionBased(HttpMethod.POST), update$: actionBased((/** * @param {?} method * @return {?} */ method => method === HttpMethod.PUT || method === HttpMethod.PATCH)), delete$: actionBased(HttpMethod.DELETE), getEntity: (/** * @param {?} id * @return {?} */ (id) => idBased(id, HttpMethod.GET)), updateEntity: (/** * @param {?} id * @return {?} */ (id) => idBased(id, (/** * @param {?} method * @return {?} */ method => method === HttpMethod.PUT || method === HttpMethod.PATCH))), deleteEntity: (/** * @param {?} id * @return {?} */ (id) => idBased(id, HttpMethod.DELETE)) }; } } NgEntityServiceLoader.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgEntityServiceLoader.ngInjectableDef = defineInjectable({ factory: function NgEntityServiceLoader_Factory() { return new NgEntityServiceLoader(); }, token: NgEntityServiceLoader, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NG_ENTITY_SERVICE_CONFIG = new InjectionToken('NgEntityServiceGlobalConfig'); /** @type {?} */ const defaultConfig = { httpMethods: { GET: HttpMethod.GET, POST: HttpMethod.POST, PATCH: HttpMethod.PATCH, PUT: HttpMethod.PUT, DELETE: HttpMethod.DELETE } }; /** * @param {?} target * @param {...?} sources * @return {?} */ function mergeDeep(target, ...sources) { if (!sources.length) return target; /** @type {?} */ const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); mergeDeep(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return mergeDeep(target, ...sources); } /** * @param {?=} config * @return {?} */ function NgEntityServiceConfig(config = {}) { return (/** * @param {?} constructor * @return {?} */ function (constructor) { if (config.baseUrl) { constructor['baseUrl'] = config.baseUrl; } if (config.resourceName) { constructor['resourceName'] = config.resourceName; } }); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} idOrConfig * @return {?} */ function isID(idOrConfig) { return isNumber(idOrConfig) || isString(idOrConfig); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} storeName * @param {?} notifier * @return {?} */ function successAction(storeName, notifier) { return (/** * @param {?} __0 * @return {?} */ function ({ payload, method, successMsg }) { notifier.dispatch({ type: 'success', storeName, payload, method, successMsg }); }); } /** * @param {?} storeName * @param {?} notifier * @return {?} */ function errorAction(storeName, notifier) { return (/** * @param {?} __0 * @return {?} */ function ({ payload, method, errorMsg }) { notifier.dispatch({ type: 'error', storeName, payload, method, errorMsg }); }); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const mapResponse = (/** * @param {?} config * @return {?} */ (config) => map((/** * @param {?} res * @return {?} */ res => ((config || {}).mapResponseFn ? config.mapResponseFn(res) : res)))); /** * @template S */ class NgEntityService extends EntityService { /** * @param {?} store * @param {?=} config */ constructor(store, config = {}) { super(); this.store = store; this.config = config; this.globalConfig = {}; this.http = inject(HttpClient); this.loader = inject(NgEntityServiceLoader); this.notifier = inject(NgEntityServiceNotifier); this.globalConfig = inject(NG_ENTITY_SERVICE_CONFIG); this.mergedConfig = mergeDeep(defaultConfig, this.globalConfig, config); this.dispatchSuccess = successAction(this.store.storeName, this.notifier); this.dispatchError = errorAction(this.store.storeName, this.notifier); } /** * @return {?} */ get api() { return `${this.baseUrl || this.getConfigValue('baseUrl')}/${this.resourceName}`; } /** * @return {?} */ get resourceName() { return this.getConfigValue('resourceName') || this.store.storeName; } /** * @param {?} api * @return {?} */ setBaseUrl(api) { this.baseUrl = api; } /** * @template T * @param {?=} idOrConfig * @param {?=} config * @return {?} */ get(idOrConfig, config) { /** @type {?} */ let url; /** @type {?} */ const isSingle = isID(idOrConfig); /** @type {?} */ const _config = (isSingle ? config : idOrConfig) || {}; /** @type {?} */ const method = this.getHttpMethod(HttpMethod.GET); if (_config.url) { url = _config.url; } else { url = isSingle ? `${this.api}/${idOrConfig}` : this.api; } this.loader.dispatch({ method, loading: true, entityId: isSingle ? idOrConfig : null, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](url, _config).pipe(mapResponse(_config), tap((/** * @param {?} data * @return {?} */ (data) => { if (isSingle) { this.store.upsert((/** @type {?} */ (idOrConfig)), data); } else { _config.append ? this.store.add(data) : this.store.set(data); } this.dispatchSuccess({ method, payload: data, successMsg: _config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, _config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, storeName: this.store.storeName }); }))))); } /** * * Add a new entity - Creates a POST request * * service.add(entity) * service.add(entity, config) * * @template T * @param {?} entity * @param {?=} config * @return {?} */ add(entity, config) { /** @type {?} */ const method = this.getHttpMethod(HttpMethod.POST); this.loader.dispatch({ method, loading: true, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](this.resolveUrl(config), entity, config).pipe(mapResponse(config), tap((/** * @param {?} entity * @return {?} */ (entity) => { this.store.add(entity, config); this.dispatchSuccess({ method, payload: entity, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, storeName: this.store.storeName }); }))))); } /** * * Update an entity - Creates a PUT/PATCH request * * service.update(id, entity) * service.update(id, entity, config) * * @template T * @param {?} id * @param {?} entity * @param {?=} config * @return {?} */ update(id, entity, config) { /** @type {?} */ const method = config && config.method ? config.method : this.getHttpMethod(HttpMethod.PUT); this.loader.dispatch({ method, loading: true, entityId: id, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLocaleLowerCase()](this.resolveUrl(config, id), entity, config).pipe(mapResponse(config), tap((/** * @param {?} entity * @return {?} */ entity => { this.store.update(id, (/** @type {?} */ (entity))); this.dispatchSuccess({ method, payload: entity, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, entityId: id, storeName: this.store.storeName }); }))))); } /** * * Delete an entity - Creates a DELETE request * * service.delete(id) * service.delete(id, config) * * @template T * @param {?} id * @param {?=} config * @return {?} */ delete(id, config) { /** @type {?} */ const method = this.getHttpMethod(HttpMethod.DELETE); this.loader.dispatch({ method, loading: true, entityId: id, storeName: this.store.storeName }); return (/** @type {?} */ (this.http[method.toLowerCase()](this.resolveUrl(config, id), config).pipe(mapResponse(config), tap((/** * @param {?} res * @return {?} */ res => { this.store.remove(id); this.dispatchSuccess({ method, payload: res, successMsg: config && config.successMsg }); })), catchError((/** * @param {?} error * @return {?} */ error => this.handleError(method, error, config && config.errorMsg))), finalize((/** * @return {?} */ () => { this.loader.dispatch({ method, loading: false, entityId: id, storeName: this.store.storeName }); }))))); } /** * @private * @param {?} type * @return {?} */ getHttpMethod(type) { return this.mergedConfig.httpMethods[type]; } /** * @private * @param {?} key * @return {?} */ getConfigValue(key) { return this.constructor[key] || this.mergedConfig[key]; } /** * @private * @param {?} config * @param {?=} id * @return {?} */ resolveUrl(config, id) { /** @type {?} */ const customUrl = (config || {}).url; if (isDefined(id)) { return customUrl || `${this.api}/${id}`; } return customUrl || this.api; } /** * @private * @param {?} method * @param {?} error * @param {?} errorMsg * @return {?} */ handleError(method, error, errorMsg) { this.dispatchError({ method, errorMsg, payload: error }); return throwError(error); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { mapResponse, NgEntityService, mergeDeep, NgEntityServiceConfig, NG_ENTITY_SERVICE_CONFIG, defaultConfig, HttpMethod, ofType, filterMethod, filterStore, NgEntityServiceNotifier, isID, NgEntityServiceLoader, successAction, errorAction }; //# sourceMappingURL=datorama-akita-angular-playground-projects-ng-entity-service.js.map