@datorama/akita
Version:
State Management Tailored-Made for JS Applications
1,923 lines (1,889 loc) • 207 kB
JavaScript
import { __assign, __values, __spread, __read, __rest, __extends, __decorate, __metadata } from 'tslib';
import { BehaviorSubject, of, Subject, ReplaySubject, from, isObservable, combineLatest, merge, EMPTY } from 'rxjs';
import { tap, distinctUntilChanged, map, filter, switchMap, skip, delay, take, debounceTime, pairwise, auditTime } from 'rxjs/operators';
/**
* @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
*/
// @internal
/**
* @template T
* @param {?} value
* @return {?}
*/
function isArray(value) {
return Array.isArray(value);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template T
* @param {?} arr
* @return {?}
*/
function isEmpty(arr) {
if (isArray(arr)) {
return arr.length === 0;
}
return false;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template E
* @param {?} entities
* @param {?} idKey
* @param {?} preAddEntity
* @return {?}
*/
function toEntitiesObject(entities, idKey, preAddEntity) {
var e_1, _a;
/** @type {?} */
var acc = {
entities: {},
ids: []
};
try {
for (var entities_1 = __values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) {
var entity = entities_1_1.value;
// evaluate the middleware first to support dynamic ids
/** @type {?} */
var current = preAddEntity(entity);
acc.entities[current[idKey]] = current;
acc.ids.push(current[idKey]);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
}
finally { if (e_1) throw e_1.error; }
}
return acc;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template E
* @param {?} entities
* @param {?} id
* @return {?}
*/
function hasEntity(entities, id) {
return entities.hasOwnProperty(id);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template E
* @param {?} state
* @return {?}
*/
function hasActiveState(state) {
return state.hasOwnProperty('active');
}
// @internal
/**
* @param {?} active
* @return {?}
*/
function isMultiActiveState(active) {
return isArray(active);
}
// @internal
/**
* @template E
* @param {?} __0
* @return {?}
*/
function resolveActiveEntity(_a) {
var active = _a.active, ids = _a.ids, entities = _a.entities;
if (isMultiActiveState(active)) {
return getExitingActives(active, ids);
}
if (hasEntity(entities, active) === false) {
return null;
}
return active;
}
// @internal
/**
* @param {?} currentActivesIds
* @param {?} newIds
* @return {?}
*/
function getExitingActives(currentActivesIds, newIds) {
/** @type {?} */
var filtered = currentActivesIds.filter((/**
* @param {?} id
* @return {?}
*/
function (id) { return newIds.indexOf(id) > -1; }));
/** Return the same reference if nothing has changed */
if (filtered.length === currentActivesIds.length) {
return currentActivesIds;
}
return filtered;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template Entity
* @param {?} state
* @return {?}
*/
function isEntityState(state) {
return state.entities && state.ids;
}
// @internal
/**
* @template E
* @param {?} entities
* @param {?} preAddEntity
* @return {?}
*/
function applyMiddleware(entities, preAddEntity) {
var e_1, _a;
/** @type {?} */
var mapped = {};
try {
for (var _b = __values(Object.keys(entities)), _c = _b.next(); !_c.done; _c = _b.next()) {
var id = _c.value;
mapped[id] = preAddEntity(entities[id]);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return mapped;
}
// @internal
/**
* @template S, E
* @param {?} __0
* @return {?}
*/
function setEntities(_a) {
var state = _a.state, entities = _a.entities, idKey = _a.idKey, preAddEntity = _a.preAddEntity, isNativePreAdd = _a.isNativePreAdd;
/** @type {?} */
var newEntities;
/** @type {?} */
var newIds;
if (isArray(entities)) {
/** @type {?} */
var resolve = toEntitiesObject(entities, idKey, preAddEntity);
newEntities = resolve.entities;
newIds = resolve.ids;
}
else if (isEntityState(entities)) {
newEntities = isNativePreAdd ? entities.entities : applyMiddleware(entities.entities, preAddEntity);
newIds = entities.ids;
}
else {
// it's an object
newEntities = isNativePreAdd ? entities : applyMiddleware(entities, preAddEntity);
newIds = Object.keys(newEntities).map((/**
* @param {?} id
* @return {?}
*/
function (id) { return (isNaN((/** @type {?} */ (id))) ? id : Number(id)); }));
}
/** @type {?} */
var newState = __assign({}, state, { entities: newEntities, ids: newIds, loading: false });
if (hasActiveState(state)) {
newState.active = resolveActiveEntity((/** @type {?} */ (newState)));
}
return newState;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
var
// @internal
AkitaError = /** @class */ (function (_super) {
__extends(AkitaError, _super);
function AkitaError(message) {
return _super.call(this, message) || this;
}
return AkitaError;
}(Error));
// @internal
/**
* @param {?} name
* @param {?} className
* @return {?}
*/
function assertStoreHasName(name, className) {
if (!name) {
console.error("@StoreConfig({ name }) is missing in " + className);
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var currentAction = {
type: null,
entityIds: null,
skip: false
};
/** @type {?} */
var customActionActive = false;
/**
* @return {?}
*/
function resetCustomAction() {
customActionActive = false;
}
// public API for custom actions. Custom action always wins
/**
* @param {?} type
* @param {?=} entityIds
* @return {?}
*/
function logAction(type, entityIds) {
setAction(type, entityIds);
customActionActive = true;
}
/**
* @param {?} type
* @param {?=} entityIds
* @return {?}
*/
function setAction(type, entityIds) {
if (customActionActive === false) {
currentAction.type = type;
currentAction.entityIds = entityIds;
}
}
/**
* @param {?=} skip
* @return {?}
*/
function setSkipAction(skip$$1) {
if (skip$$1 === void 0) { skip$$1 = true; }
currentAction.skip = skip$$1;
}
/**
* @param {?} action
* @param {?=} entityIds
* @return {?}
*/
function action(action, entityIds) {
return (/**
* @param {?} target
* @param {?} propertyKey
* @param {?} descriptor
* @return {?}
*/
function (target, propertyKey, descriptor) {
/** @type {?} */
var originalMethod = descriptor.value;
descriptor.value = (/**
* @param {...?} args
* @return {?}
*/
function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
logAction(action, entityIds);
return originalMethod.apply(this, args);
});
return descriptor;
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/** @type {?} */
var transactionFinished = new Subject();
// @internal
/** @type {?} */
var transactionInProcess = new BehaviorSubject(false);
// @internal
/** @type {?} */
var transactionManager = {
activeTransactions: 0,
batchTransaction: null
};
// @internal
/**
* @return {?}
*/
function startBatch() {
if (!isTransactionInProcess()) {
transactionManager.batchTransaction = new Subject();
}
transactionManager.activeTransactions++;
transactionInProcess.next(true);
}
// @internal
/**
* @return {?}
*/
function endBatch() {
if (--transactionManager.activeTransactions === 0) {
transactionManager.batchTransaction.next(true);
transactionManager.batchTransaction.complete();
transactionInProcess.next(false);
transactionFinished.next(true);
}
}
// @internal
/**
* @return {?}
*/
function isTransactionInProcess() {
return transactionManager.activeTransactions > 0;
}
// @internal
/**
* @return {?}
*/
function commit() {
return transactionManager.batchTransaction ? transactionManager.batchTransaction.asObservable() : of(true);
}
/**
* A logical transaction.
* Use this transaction to optimize the dispatch of all the stores.
* The following code will update the store, BUT emits only once
*
* \@example
* applyTransaction(() => {
* this.todosStore.add(new Todo(1, title));
* this.todosStore.add(new Todo(2, title));
* });
*
* @template T
* @param {?} action
* @param {?=} thisArg
* @return {?}
*/
function applyTransaction(action$$1, thisArg) {
if (thisArg === void 0) { thisArg = undefined; }
startBatch();
try {
return action$$1.apply(thisArg);
}
finally {
logAction('@Transaction');
endBatch();
}
}
/**
* A logical transaction.
* Use this transaction to optimize the dispatch of all the stores.
*
* The following code will update the store, BUT emits only once.
*
* \@example
* \@transaction
* addTodos() {
* this.todosStore.add(new Todo(1, title));
* this.todosStore.add(new Todo(2, title));
* }
*
*
* @return {?}
*/
function transaction() {
return (/**
* @param {?} target
* @param {?} propertyKey
* @param {?} descriptor
* @return {?}
*/
function (target, propertyKey, descriptor) {
/** @type {?} */
var originalMethod = descriptor.value;
descriptor.value = (/**
* @param {...?} args
* @return {?}
*/
function () {
var _this = this;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return applyTransaction((/**
* @return {?}
*/
function () {
return originalMethod.apply(_this, args);
}), this);
});
return descriptor;
});
}
/**
*
* RxJS custom operator that wraps the callback inside transaction
*
* \@example
*
* return http.get().pipe(
* withTransaction(response > {
* store.setActive(1);
* store.update();
* store.updateEntity(1, {});
* })
* )
*
* @template T
* @param {?} transactionFn
* @return {?}
*/
function withTransaction(transactionFn) {
return (/**
* @param {?} source
* @return {?}
*/
function (source) {
return source.pipe(tap((/**
* @param {?} value
* @return {?}
*/
function (value) { return applyTransaction((/**
* @return {?}
*/
function () { return transactionFn(value); })); })));
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} o
* @return {?}
*/
function deepFreeze(o) {
Object.freeze(o);
/** @type {?} */
var oIsFunction = typeof o === 'function';
/** @type {?} */
var hasOwnProp = Object.prototype.hasOwnProperty;
Object.getOwnPropertyNames(o).forEach((/**
* @param {?} prop
* @return {?}
*/
function (prop) {
if (hasOwnProp.call(o, prop) &&
(oIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true) &&
o[prop] !== null &&
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
!Object.isFrozen(o[prop])) {
deepFreeze(o[prop]);
}
}));
return o;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var configKey = 'akitaConfig';
/**
* @param {?} metadata
* @return {?}
*/
function StoreConfig(metadata) {
return (/**
* @param {?} constructor
* @return {?}
*/
function (constructor) {
constructor[configKey] = { idKey: 'id' };
for (var i = 0, keys = Object.keys(metadata); i < keys.length; i++) {
/** @type {?} */
var key = keys[i];
/* name is preserved read only key */
if (key === 'name') {
constructor[configKey]['storeName'] = metadata[key];
}
else {
constructor[configKey][key] = metadata[key];
}
}
});
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var CONFIG = {
resettable: false
};
/**
* @param {?} config
* @return {?}
*/
function akitaConfig(config) {
CONFIG = __assign({}, CONFIG, config);
}
// @internal
/**
* @return {?}
*/
function getAkitaConfig() {
return CONFIG;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} value
* @return {?}
*/
function toBoolean(value) {
return value != null && "" + value !== 'false';
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} value
* @return {?}
*/
function isPlainObject(value) {
return toBoolean(value) && value.constructor.name === 'Object';
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} value
* @return {?}
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/** @type {?} */
var $$deleteStore = new Subject();
// @internal
/** @type {?} */
var $$addStore = new ReplaySubject(50, 5000);
// @internal
/** @type {?} */
var $$updateStore = new Subject();
// @internal
/**
* @param {?} storeName
* @return {?}
*/
function dispatchDeleted(storeName) {
$$deleteStore.next(storeName);
}
// @internal
/**
* @param {?} storeName
* @return {?}
*/
function dispatchAdded(storeName) {
$$addStore.next(storeName);
}
// @internal
/**
* @param {?} storeName
* @return {?}
*/
function dispatchUpdate(storeName) {
$$updateStore.next(storeName);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var __DEV__ = true;
/**
* @return {?}
*/
function enableAkitaProdMode() {
__DEV__ = false;
}
// @internal
/**
* @return {?}
*/
function isDev() {
return __DEV__;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var isBrowser = typeof window !== 'undefined';
/** @type {?} */
var isNativeScript = typeof global !== 'undefined' && typeof ((/** @type {?} */ (global))).__runtimeVersion !== 'undefined';
// @internal
/** @type {?} */
var isNotBrowser = !isBrowser && !isNativeScript;
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/** @type {?} */
var __stores__ = {};
// @internal
/** @type {?} */
var __queries__ = {};
if (isBrowser && isDev()) {
((/** @type {?} */ (window))).$$stores = __stores__;
((/** @type {?} */ (window))).$$queries = __queries__;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
*
* Store for managing any type of data
*
* \@example
*
* export interface SessionState {
* token: string;
* userDetails: UserDetails
* }
*
* export function createInitialState(): SessionState {
* return {
* token: '',
* userDetails: null
* };
* }
*
* \@StoreConfig({ name: 'session' })
* export class SessionStore extends Store<SessionState> {
* constructor() {
* super(createInitialState());
* }
* }
* @template S
*/
var /**
*
* Store for managing any type of data
*
* \@example
*
* export interface SessionState {
* token: string;
* userDetails: UserDetails
* }
*
* export function createInitialState(): SessionState {
* return {
* token: '',
* userDetails: null
* };
* }
*
* \@StoreConfig({ name: 'session' })
* export class SessionStore extends Store<SessionState> {
* constructor() {
* super(createInitialState());
* }
* }
* @template S
*/
Store = /** @class */ (function () {
function Store(initialState, options) {
if (options === void 0) { options = {}; }
this.options = options;
this.inTransaction = false;
this.cache = {
active: new BehaviorSubject(false),
ttl: null
};
this.onInit((/** @type {?} */ (initialState)));
}
/**
* Set the loading state
*
* @example
*
* store.setLoading(true)
*
*/
/**
* Set the loading state
*
* \@example
*
* store.setLoading(true)
*
* @param {?=} loading
* @return {?}
*/
Store.prototype.setLoading = /**
* Set the loading state
*
* \@example
*
* store.setLoading(true)
*
* @param {?=} loading
* @return {?}
*/
function (loading) {
if (loading === void 0) { loading = false; }
if (loading !== ((/** @type {?} */ (this._value()))).loading) {
isDev() && setAction('Set Loading');
this._setState((/**
* @param {?} state
* @return {?}
*/
function (state) { return ((/** @type {?} */ (__assign({}, state, { loading: loading })))); }));
}
};
/**
*
* Set whether the data is cached
*
* @example
*
* store.setHasCache(true)
* store.setHasCache(false)
* store.setHasCache(true, { restartTTL: true })
*
*/
/**
*
* Set whether the data is cached
*
* \@example
*
* store.setHasCache(true)
* store.setHasCache(false)
* store.setHasCache(true, { restartTTL: true })
*
* @param {?} hasCache
* @param {?=} options
* @return {?}
*/
Store.prototype.setHasCache = /**
*
* Set whether the data is cached
*
* \@example
*
* store.setHasCache(true)
* store.setHasCache(false)
* store.setHasCache(true, { restartTTL: true })
*
* @param {?} hasCache
* @param {?=} options
* @return {?}
*/
function (hasCache, options) {
var _this = this;
if (options === void 0) { options = { restartTTL: false }; }
if (hasCache !== this.cache.active.value) {
this.cache.active.next(hasCache);
}
if (options.restartTTL) {
/** @type {?} */
var ttlConfig = this.cacheConfig && this.cacheConfig.ttl;
if (ttlConfig) {
if (this.cache.ttl !== null) {
clearTimeout(this.cache.ttl);
}
this.cache.ttl = (/** @type {?} */ (setTimeout((/**
* @return {?}
*/
function () { return _this.setHasCache(false); }), ttlConfig)));
}
}
};
/**
* Set the error state
*
* @example
*
* store.setError({text: 'unable to load data' })
*
*/
/**
* Set the error state
*
* \@example
*
* store.setError({text: 'unable to load data' })
*
* @template T
* @param {?} error
* @return {?}
*/
Store.prototype.setError = /**
* Set the error state
*
* \@example
*
* store.setError({text: 'unable to load data' })
*
* @template T
* @param {?} error
* @return {?}
*/
function (error) {
if (error !== ((/** @type {?} */ (this._value()))).error) {
isDev() && setAction('Set Error');
this._setState((/**
* @param {?} state
* @return {?}
*/
function (state) { return ((/** @type {?} */ (__assign({}, state, { error: error })))); }));
}
};
// @internal
// @internal
/**
* @template R
* @param {?} project
* @return {?}
*/
Store.prototype._select =
// @internal
/**
* @template R
* @param {?} project
* @return {?}
*/
function (project) {
return this.store.asObservable().pipe(map(project), distinctUntilChanged());
};
// @internal
// @internal
/**
* @return {?}
*/
Store.prototype._value =
// @internal
/**
* @return {?}
*/
function () {
return this.storeValue;
};
// @internal
// @internal
/**
* @return {?}
*/
Store.prototype._cache =
// @internal
/**
* @return {?}
*/
function () {
return this.cache.active;
};
Object.defineProperty(Store.prototype, "config", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return this.constructor[configKey] || {};
},
enumerable: true,
configurable: true
});
Object.defineProperty(Store.prototype, "storeName", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return ((/** @type {?} */ (this.config))).storeName || ((/** @type {?} */ (this.options))).storeName || this.options.name;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Store.prototype, "deepFreeze", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return this.config.deepFreezeFn || this.options.deepFreezeFn || deepFreeze;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Store.prototype, "cacheConfig", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return this.config.cache || this.options.cache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Store.prototype, "resettable", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return this.config.resettable || this.options.resettable;
},
enumerable: true,
configurable: true
});
// @internal
// @internal
/**
* @param {?} newStateFn
* @param {?=} _dispatchAction
* @return {?}
*/
Store.prototype._setState =
// @internal
/**
* @param {?} newStateFn
* @param {?=} _dispatchAction
* @return {?}
*/
function (newStateFn, _dispatchAction) {
if (_dispatchAction === void 0) { _dispatchAction = true; }
this.storeValue = __DEV__ ? this.deepFreeze(newStateFn(this._value())) : newStateFn(this._value());
if (!this.store) {
this.store = new BehaviorSubject(this.storeValue);
return;
}
if (isTransactionInProcess()) {
this.handleTransaction();
return;
}
this.dispatch(this.storeValue, _dispatchAction);
};
/**
*
* Reset the current store back to the initial value
*
* @example
*
* store.reset()
*
*/
/**
*
* Reset the current store back to the initial value
*
* \@example
*
* store.reset()
*
* @return {?}
*/
Store.prototype.reset = /**
*
* Reset the current store back to the initial value
*
* \@example
*
* store.reset()
*
* @return {?}
*/
function () {
var _this = this;
if (this.isResettable()) {
isDev() && setAction('Reset');
this._setState((/**
* @return {?}
*/
function () { return Object.assign({}, _this._initialState); }));
this.setHasCache(false);
}
else {
isDev() && console.warn("You need to enable the reset functionality");
}
};
/**
* @param {?} stateOrCallback
* @return {?}
*/
Store.prototype.update = /**
* @param {?} stateOrCallback
* @return {?}
*/
function (stateOrCallback) {
var _this = this;
isDev() && setAction('Update');
this._setState((/**
* @param {?} state
* @return {?}
*/
function (state) {
/** @type {?} */
var newState = isFunction(stateOrCallback) ? stateOrCallback(state) : stateOrCallback;
/** @type {?} */
var merged = _this.akitaPreUpdate(state, (/** @type {?} */ (__assign({}, state, newState))));
return isPlainObject(state) ? merged : new ((/** @type {?} */ (state))).constructor(merged);
}));
};
/**
* @param {?} newOptions
* @return {?}
*/
Store.prototype.updateStoreConfig = /**
* @param {?} newOptions
* @return {?}
*/
function (newOptions) {
this.options = __assign({}, this.options, newOptions);
};
// @internal
// @internal
/**
* @param {?} _
* @param {?} nextState
* @return {?}
*/
Store.prototype.akitaPreUpdate =
// @internal
/**
* @param {?} _
* @param {?} nextState
* @return {?}
*/
function (_, nextState) {
return nextState;
};
/**
* @return {?}
*/
Store.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy();
};
/**
*
* Destroy the store
*
* @example
*
* store.destroy()
*
*/
/**
*
* Destroy the store
*
* \@example
*
* store.destroy()
*
* @return {?}
*/
Store.prototype.destroy = /**
*
* Destroy the store
*
* \@example
*
* store.destroy()
*
* @return {?}
*/
function () {
if (isNotBrowser)
return;
if (!((/** @type {?} */ (window))).hmrEnabled && this === __stores__[this.storeName]) {
delete __stores__[this.storeName];
dispatchDeleted(this.storeName);
this.setHasCache(false);
this.cache.active.complete();
}
};
/**
* @private
* @param {?} initialState
* @return {?}
*/
Store.prototype.onInit = /**
* @private
* @param {?} initialState
* @return {?}
*/
function (initialState) {
__stores__[this.storeName] = this;
this._setState((/**
* @return {?}
*/
function () { return initialState; }));
dispatchAdded(this.storeName);
if (this.isResettable()) {
this._initialState = initialState;
}
isDev() && assertStoreHasName(this.storeName, this.constructor.name);
};
/**
* @private
* @param {?} state
* @param {?=} _dispatchAction
* @return {?}
*/
Store.prototype.dispatch = /**
* @private
* @param {?} state
* @param {?=} _dispatchAction
* @return {?}
*/
function (state, _dispatchAction) {
if (_dispatchAction === void 0) { _dispatchAction = true; }
this.store.next(state);
if (_dispatchAction) {
dispatchUpdate(this.storeName);
resetCustomAction();
}
};
/**
* @private
* @return {?}
*/
Store.prototype.watchTransaction = /**
* @private
* @return {?}
*/
function () {
var _this = this;
commit().subscribe((/**
* @return {?}
*/
function () {
_this.inTransaction = false;
_this.dispatch(_this._value());
}));
};
/**
* @private
* @return {?}
*/
Store.prototype.isResettable = /**
* @private
* @return {?}
*/
function () {
if (this.resettable === false) {
return false;
}
return this.resettable || getAkitaConfig().resettable;
};
/**
* @private
* @return {?}
*/
Store.prototype.handleTransaction = /**
* @private
* @return {?}
*/
function () {
if (!this.inTransaction) {
this.watchTransaction();
this.inTransaction = true;
}
};
return Store;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} v
* @return {?}
*/
function isNil(v) {
return v === null || v === undefined;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} value
* @return {?}
*/
function isObject(value) {
/** @type {?} */
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} idOrOptions
* @param {?} ids
* @param {?} currentActive
* @return {?}
*/
function getActiveEntities(idOrOptions, ids, currentActive) {
/** @type {?} */
var result;
if (isArray(idOrOptions)) {
result = idOrOptions;
}
else {
if (isObject(idOrOptions)) {
if (isNil(currentActive))
return;
((/** @type {?} */ (idOrOptions))) = Object.assign({ wrap: true }, idOrOptions);
/** @type {?} */
var currentIdIndex = ids.indexOf((/** @type {?} */ (currentActive)));
if (((/** @type {?} */ (idOrOptions))).prev) {
/** @type {?} */
var isFirst = currentIdIndex === 0;
if (isFirst && !((/** @type {?} */ (idOrOptions))).wrap)
return;
result = isFirst ? ids[ids.length - 1] : ((/** @type {?} */ (ids[currentIdIndex - 1])));
}
else if (((/** @type {?} */ (idOrOptions))).next) {
/** @type {?} */
var isLast = ids.length === currentIdIndex + 1;
if (isLast && !((/** @type {?} */ (idOrOptions))).wrap)
return;
result = isLast ? ids[0] : ((/** @type {?} */ (ids[currentIdIndex + 1])));
}
}
else {
if (idOrOptions === currentActive)
return;
result = (/** @type {?} */ (idOrOptions));
}
}
return result;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template S, E
* @param {?} __0
* @return {?}
*/
function addEntities(_a) {
var state = _a.state, entities = _a.entities, idKey = _a.idKey, _b = _a.options, options = _b === void 0 ? {} : _b, preAddEntity = _a.preAddEntity;
var e_1, _c;
/** @type {?} */
var newEntities = {};
/** @type {?} */
var newIds = [];
/** @type {?} */
var hasNewEntities = false;
try {
for (var entities_1 = __values(entities), entities_1_1 = entities_1.next(); !entities_1_1.done; entities_1_1 = entities_1.next()) {
var entity = entities_1_1.value;
if (hasEntity(state.entities, entity[idKey]) === false) {
// evaluate the middleware first to support dynamic ids
/** @type {?} */
var current = preAddEntity(entity);
/** @type {?} */
var entityId = current[idKey];
newEntities[entityId] = current;
if (options.prepend)
newIds.unshift(entityId);
else
newIds.push(entityId);
hasNewEntities = true;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (entities_1_1 && !entities_1_1.done && (_c = entities_1.return)) _c.call(entities_1);
}
finally { if (e_1) throw e_1.error; }
}
return hasNewEntities
? {
newState: __assign({}, state, { entities: __assign({}, state.entities, newEntities), ids: options.prepend ? __spread(newIds, state.ids) : __spread(state.ids, newIds) }),
newIds: newIds
}
: null;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template T
* @param {?} value
* @return {?}
*/
function coerceArray(value) {
if (isNil(value)) {
return [];
}
return Array.isArray(value) ? value : [value];
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template S, E
* @param {?} __0
* @return {?}
*/
function removeEntities(_a) {
var state = _a.state, ids = _a.ids;
var e_1, _b;
if (isNil(ids))
return removeAllEntities(state);
/** @type {?} */
var entities = state.entities;
/** @type {?} */
var newEntities = {};
try {
for (var _c = __values(state.ids), _d = _c.next(); !_d.done; _d = _c.next()) {
var id = _d.value;
if (ids.includes(id) === false) {
newEntities[id] = entities[id];
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
/** @type {?} */
var newState = __assign({}, state, { entities: newEntities, ids: state.ids.filter((/**
* @param {?} current
* @return {?}
*/
function (current) { return ids.includes(current) === false; })) });
if (hasActiveState(state)) {
newState.active = resolveActiveEntity(newState);
}
return newState;
}
// @internal
/**
* @template S
* @param {?} state
* @return {?}
*/
function removeAllEntities(state) {
return __assign({}, state, { entities: {}, ids: [], active: isMultiActiveState(state.active) ? [] : null });
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/** @type {?} */
var getInitialEntitiesState = (/**
* @return {?}
*/
function () {
return ((/** @type {?} */ ({
entities: {},
ids: [],
loading: true,
error: null
})));
});
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} val
* @return {?}
*/
function isDefined(val) {
return isNil(val) === false;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @template S, E
* @param {?} __0
* @return {?}
*/
function updateEntities(_a) {
var state = _a.state, ids = _a.ids, idKey = _a.idKey, newStateOrFn = _a.newStateOrFn, preUpdateEntity = _a.preUpdateEntity;
var e_1, _b;
/** @type {?} */
var updatedEntities = {};
/** @type {?} */
var isUpdatingIdKey = false;
/** @type {?} */
var idToUpdate;
try {
for (var ids_1 = __values(ids), ids_1_1 = ids_1.next(); !ids_1_1.done; ids_1_1 = ids_1.next()) {
var id = ids_1_1.value;
// if the entity doesn't exist don't do anything
if (hasEntity(state.entities, id) === false) {
continue;
}
/** @type {?} */
var oldEntity = state.entities[id];
/** @type {?} */
var newState = isFunction(newStateOrFn) ? newStateOrFn(oldEntity) : newStateOrFn;
/** @type {?} */
var isIdChanged = newState.hasOwnProperty(idKey) && newState[idKey] !== oldEntity[idKey];
/** @type {?} */
var newEntity = void 0;
idToUpdate = id;
if (isIdChanged) {
isUpdatingIdKey = true;
idToUpdate = newState[idKey];
}
/** @type {?} */
var merged = __assign({}, oldEntity, newState);
if (isPlainObject(oldEntity)) {
newEntity = merged;
}
else {
/**
* In case that new state is class of it's own, there's
* a possibility that it will be different than the old
* class.
* For example, Old state is an instance of animal class
* and new state is instance of person class.
* To avoid run over new person class with the old animal
* class we check if the new state is a class of it's own.
* If so, use it. Otherwise, use the old state class
*/
if (isPlainObject(newState)) {
newEntity = new ((/** @type {?} */ (oldEntity))).constructor(merged);
}
else {
newEntity = new ((/** @type {?} */ (newState))).constructor(merged);
}
}
updatedEntities[idToUpdate] = preUpdateEntity(oldEntity, newEntity);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (ids_1_1 && !ids_1_1.done && (_b = ids_1.return)) _b.call(ids_1);
}
finally { if (e_1) throw e_1.error; }
}
/** @type {?} */
var updatedIds = state.ids;
/** @type {?} */
var stateEntities = state.entities;
if (isUpdatingIdKey) {
var _c = __read(ids, 1), id_1 = _c[0];
var _d = state.entities, _e = id_1, deletedEntity = _d[_e], rest = __rest(_d, [typeof _e === "symbol" ? _e : _e + ""]);
stateEntities = rest;
updatedIds = state.ids.map((/**
* @param {?} current
* @return {?}
*/
function (current) { return (current === id_1 ? idToUpdate : current); }));
}
return __assign({}, state, { entities: __assign({}, stateEntities, updatedEntities), ids: updatedIds });
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
// @internal
/**
* @param {?} value
* @return {?}
*/
function isUndefined(value) {
return value === undefined;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
var EntityActions = {
Set: 0,
Add: 1,
Update: 2,
Remove: 3,
};
EntityActions[EntityActions.Set] = 'Set';
EntityActions[EntityActions.Add] = 'Add';
EntityActions[EntityActions.Update] = 'Update';
EntityActions[EntityActions.Remove] = 'Remove';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
var DEFAULT_ID_KEY = 'id';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
*
* Store for managing a collection of entities
*
* \@example
*
* export interface WidgetsState extends EntityState<Widget> { }
*
* \@StoreConfig({ name: 'widgets' })
* export class WidgetsStore extends EntityStore<WidgetsState> {
* constructor() {
* super();
* }
* }
*
*
* @template S, EntityType, IDType
*/
var EntityStore = /** @class */ (function (_super) {
__extends(EntityStore, _super);
function EntityStore(initialState, options) {
if (initialState === void 0) { initialState = {}; }
if (options === void 0) { options = {}; }
var _this = _super.call(this, __assign({}, getInitialEntitiesState(), initialState), options) || this;
_this.options = options;
_this.entityActions = new Subject();
return _this;
}
Object.defineProperty(EntityStore.prototype, "selectEntityAction$", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return this.entityActions.asObservable();
},
enumerable: true,
configurable: true
});
Object.defineProperty(EntityStore.prototype, "idKey", {
// @internal
get:
// @internal
/**
* @return {?}
*/
function () {
return ((/** @type {?} */ (this.config))).idKey || this.options.idKey || DEFAULT_ID_KEY;
},
enumerable: true,
configurable: true
});
/**
*
* Replace current collection with provided collection
*
* @example
*
* this.store.set([Entity, Entity])
* this.store.set({ids: [], entities: {}})
* this.store.set({ 1: {}, 2: {}})
*
*/
/**
*
* Replace current collection with provided collection
*
* \@example
*
* this.store.set([Entity, Entity])
* this.store.set({ids: [], entities: {}})
* this.store.set({ 1: {}, 2: {}})
*
* @param {?} entities
* @return {?}
*/
EntityStore.prototype.set = /**
*
* Replace current collection with provided collection
*
* \@example
*
* this.store.set([Entity, Entity])
* this.store.set({ids: [], entities: {}})
* this.store.set({ 1: {}, 2: {}})
*
* @param {?} entities
* @return {?}
*/
function (entities) {
var _this = this;
if (isNil(entities))
return;
isDev() && setAction('Set Entity');
/** @type {?} */
var isNativePreAdd = this.akitaPreAddEntity === EntityStore.prototype.akitaPreAddEntity;
this._setState((/**
* @param {?} state
* @return {?}
*/
function (state) {
return setEntities({
state: state,
entities: entities,
idKey: _this.idKey,
preAddEntity: _this.akitaPreAddEntity,
isNativePreAdd: isNativePreAdd
});
}));
this.setHasCache(true, { restartTTL: true });
if (this.hasInitialUIState()) {
this.handleUICreation();
}
this.entityActions.next({ type: EntityActions.Set, ids: this.ids });
};
/**
* Add entities
*
* @example
*
* this.store.add([Entity, Entity])
* this.store.add(Entity)
* this.store.add(Entity, { prepend: true })
*
* this.store.add(Entity, { loading: false })
*/
/**
* Add entities
*
* \@example
*
* this.store.add([Entity, Entity])
* this.store.add(Entity)
* this.store.add(Entity, { prepend: true })
*
* this.store.add(Entity, { loading: false })
* @param {?} entities
* @param {?=} options
* @return {?}
*/
EntityStore.prototype.add = /**
* Add entities
*
* \@example
*
* this.store.add([Entity, Entity])
* this.store.add(Entity)
* this.store.add(Entity, { prepend: true })
*
* this.store.add(Entity, { loading: false })
* @param {?} entities
* @param {?=} options
* @return {?}
*/
function (entities, options) {
if (options === void 0) { options = { loading: false }; }
/** @type {?} */
var collection = coerceArray(entities);
if (isEmpty(collection))
return;
/** @type {?} */
var data = addEntities({
state: this._value(),
preAddEntity: this.akitaPreAddEntity,
entities: collection,
idKey: this.idKey,
options: options
});
if (data) {
isDev() && setAction('Add Entity');
data.newState.loading = options.loading;
this._setState((/**
* @return {?}
*/
function () { return data.newState; }));
if (this.hasInitialUIState()) {
this.handleUICreation(true);
}
this.entityActions.next({ type: EntityActions.Add, ids: data.newIds });
}
};
/**
* @param {?} idsOrFnOrState
* @param {?=} newStateOrFn
* @return {?}
*/
EntityStore.prototype.update = /**
* @param {?} idsOrFnOrState
* @param {?=} newStateOrFn
* @return {?}
*/
function (idsOrFnOrState, newStateOrFn) {
var _this = this;
if (isUndefined(newStateOrFn)) {
_super.prototype.update.call(this, (/** @type {?} */ (idsOrFnOrState)));
return;
}
/** @type {?} */
var ids = [];
if (isFunction(idsOrFnOrState)) {
// We need to filter according the predicate function
ids = this.ids.filter((/**
* @param {?} id
* @return {?}
*/
function (id) { return ((/** @type {?} */ (idsOrFnOrState)))(_this.entities[id]); }));
}
else {
// If it's nil we want all of them
ids = isNil(idsOrFnOrState) ? this.ids : coerceArray((/** @type {?} */ (idsOrFnOrState)));
}
if (isEmpty(ids))
return;
isDev() && setAction('Update Entity', ids);
this._setState((/**
* @param {?} state
* @return {?}
*/
function (state) {
return updateEntities({
idKey: _this.idKey,
ids: ids,
preUpdateEntity: _this.akitaPreUpdateEntity,
state: state,
newStateOrFn: newStateOrFn
});
}));
this.entityActions.next({ type: EntityActions.Update, ids: ids });
};
/**
*
* Create or update
*
* @example
*
* store.upsert(1, { active: true })
* store.upsert([2, 3], { active: true })
* store.upsert([2, 3], entity => ({ isOpen: !entity.isOpen}))
*
*/
/**
*
* Create or update
*
* \@example
*
* store.upsert(1, { active: true })
* store.upsert([2, 3], { active: true })
* store.upsert([2, 3], entity => ({ isOpen: !entity.isOpen}))
*
* @param {?} ids
* @param {?} newState
* @param {?=} options
* @return {?}
*/
EntityStore.prototype.upsert = /**
*
* Create or update
*
* \@example
*
* store.upsert(1, { active: true })
* store.upsert([2, 3], { active: true })
* store.upsert([2, 3], entity => ({ isOpen: !entity.isOpen}))
*
* @param {?} ids
* @param {?} newState
* @param {?=} options
* @return {?}
*/
function (ids, newState, options) {
var _this = this;
if (options === void 0) { options = {}; }
/** @type {?} */
var toArray = coerceArray(ids);
/** @type {?} */
var predicate = (/**
* @param {?} isUpdate
* @return {?}
*/
function (isUpdate) { return (/**
* @param {?} id
* @return {?}
*/
function (id) { return hasEntity(_this