@microphi/store 0.2.10 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/effect/effect.mjs +75 -0
- package/esm2020/lib/list/list.mjs +75 -0
- package/esm2020/lib/reduce/reduce.mjs +26 -0
- package/esm2020/lib/store/store.mjs +101 -0
- package/esm2020/lib/utilities/scan-instance.mjs +19 -0
- package/esm2020/microphi-store.mjs +5 -0
- package/esm2020/public-api.mjs +8 -0
- package/fesm2015/microphi-store.mjs +305 -0
- package/fesm2015/microphi-store.mjs.map +1 -0
- package/fesm2020/microphi-store.mjs +303 -0
- package/fesm2020/microphi-store.mjs.map +1 -0
- package/index.d.ts +6 -0
- package/lib/effect/effect.d.ts +62 -0
- package/lib/effect/effect.d.ts.map +1 -0
- package/lib/list/list.d.ts +2 -1
- package/lib/list/list.d.ts.map +1 -0
- package/lib/reduce/reduce.d.ts +12 -0
- package/lib/reduce/reduce.d.ts.map +1 -0
- package/lib/store/store.d.ts +39 -0
- package/lib/store/store.d.ts.map +1 -0
- package/lib/utilities/scan-instance.d.ts +3 -0
- package/lib/utilities/scan-instance.d.ts.map +1 -0
- package/microphi-store.d.ts.map +1 -0
- package/package.json +23 -17
- package/public-api.d.ts +4 -8
- package/public-api.d.ts.map +1 -0
- package/bundles/microphi-store.umd.js +0 -996
- package/bundles/microphi-store.umd.js.map +0 -1
- package/bundles/microphi-store.umd.min.js +0 -16
- package/bundles/microphi-store.umd.min.js.map +0 -1
- package/esm2015/lib/actions.js +0 -105
- package/esm2015/lib/base-store.js +0 -156
- package/esm2015/lib/effect.js +0 -11
- package/esm2015/lib/http-status/http-status.interceptor.js +0 -31
- package/esm2015/lib/http-status/http-status.store.js +0 -63
- package/esm2015/lib/list/list.js +0 -80
- package/esm2015/lib/observable-list/observable-list.js +0 -119
- package/esm2015/lib/reduce.js +0 -15
- package/esm2015/lib/store.js +0 -13
- package/esm2015/microphi-store.js +0 -5
- package/esm2015/public-api.js +0 -13
- package/esm5/lib/actions.js +0 -110
- package/esm5/lib/base-store.js +0 -177
- package/esm5/lib/effect.js +0 -11
- package/esm5/lib/http-status/http-status.interceptor.js +0 -33
- package/esm5/lib/http-status/http-status.store.js +0 -66
- package/esm5/lib/list/list.js +0 -126
- package/esm5/lib/observable-list/observable-list.js +0 -250
- package/esm5/lib/reduce.js +0 -15
- package/esm5/lib/store.js +0 -13
- package/esm5/microphi-store.js +0 -5
- package/esm5/public-api.js +0 -13
- package/fesm2015/microphi-store.js +0 -586
- package/fesm2015/microphi-store.js.map +0 -1
- package/fesm5/microphi-store.js +0 -788
- package/fesm5/microphi-store.js.map +0 -1
- package/lib/actions.d.ts +0 -77
- package/lib/base-store.d.ts +0 -31
- package/lib/effect.d.ts +0 -2
- package/lib/http-status/http-status.interceptor.d.ts +0 -7
- package/lib/http-status/http-status.store.d.ts +0 -17
- package/lib/observable-list/observable-list.d.ts +0 -29
- package/lib/reduce.d.ts +0 -7
- package/lib/store.d.ts +0 -9
- package/microphi-store.d.ts +0 -4
- package/microphi-store.metadata.json +0 -1
|
@@ -1,586 +0,0 @@
|
|
|
1
|
-
import { getDebugger } from '@microgamma/loggator';
|
|
2
|
-
import { Subject, BehaviorSubject, Observable, throwError } from 'rxjs';
|
|
3
|
-
import { tap, takeUntil, catchError, map, delay } from 'rxjs/operators';
|
|
4
|
-
import { __decorate } from 'tslib';
|
|
5
|
-
import { ɵɵdefineInjectable, Injectable } from '@angular/core';
|
|
6
|
-
|
|
7
|
-
const REQUEST_SUFFIX = '_REQUEST';
|
|
8
|
-
const RESPONSE_SUFFIX = '_RESPONSE';
|
|
9
|
-
const ERROR_SUFFIX = '_ERROR';
|
|
10
|
-
/**
|
|
11
|
-
* Action are defined with an enum. Such as:
|
|
12
|
-
*
|
|
13
|
-
* emun {
|
|
14
|
-
* GET_ALL,
|
|
15
|
-
* GET_ONE,
|
|
16
|
-
* DELETE,
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* For each action defined a REQUEST, a RESPONSE and an ERROR are associated to it.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*/
|
|
23
|
-
class Actions {
|
|
24
|
-
constructor(actions) {
|
|
25
|
-
/**
|
|
26
|
-
* Example:
|
|
27
|
-
* {
|
|
28
|
-
* 0: { request: 'ACTION_NAME_REQUEST', response: 'ACTION_NAME_RESPONSE', error: 'ACTION_NAME_ERROR' }
|
|
29
|
-
* [....]
|
|
30
|
-
* }
|
|
31
|
-
*/
|
|
32
|
-
this.actions = {};
|
|
33
|
-
/**
|
|
34
|
-
* Example:
|
|
35
|
-
* {
|
|
36
|
-
* ACTION_NAME: 0
|
|
37
|
-
* [....]
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
|
-
*/
|
|
41
|
-
this.names = {};
|
|
42
|
-
/**
|
|
43
|
-
* Example:
|
|
44
|
-
* {
|
|
45
|
-
* 0: 'ACTION_NAME',
|
|
46
|
-
* [....]
|
|
47
|
-
*
|
|
48
|
-
* }
|
|
49
|
-
*/
|
|
50
|
-
this.codes = {};
|
|
51
|
-
/**
|
|
52
|
-
* Example:
|
|
53
|
-
* {
|
|
54
|
-
* ACTION_NAME': { request: 'ACTION_NAME_REQUEST', response: 'ACTION_NAME_RESPONSE', error: 'ACTION_NAME_ERROR' }
|
|
55
|
-
* [....]
|
|
56
|
-
* }
|
|
57
|
-
*/
|
|
58
|
-
this.restActionsByName = {};
|
|
59
|
-
Object.keys(actions).forEach((key) => {
|
|
60
|
-
if (+key >= 0) {
|
|
61
|
-
this.codes[key] = actions[key];
|
|
62
|
-
this.actions[key] = Actions.createAction(actions[key]);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
this.names[key] = actions[key];
|
|
66
|
-
this.restActionsByName[key] = Actions.createAction(key);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
static createAction(key) {
|
|
71
|
-
return {
|
|
72
|
-
request: `${key}${REQUEST_SUFFIX}`,
|
|
73
|
-
response: `${key}${RESPONSE_SUFFIX}`,
|
|
74
|
-
error: `${key}${ERROR_SUFFIX}`,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
getByName(actionName) {
|
|
78
|
-
return this.names[actionName];
|
|
79
|
-
}
|
|
80
|
-
getByCode(code) {
|
|
81
|
-
return this.codes[code];
|
|
82
|
-
}
|
|
83
|
-
getActionsByCode(key) {
|
|
84
|
-
return this.actions[key];
|
|
85
|
-
}
|
|
86
|
-
getActionsByName(actionName) {
|
|
87
|
-
const code = this.getByName(actionName);
|
|
88
|
-
return this.getActionsByCode(code);
|
|
89
|
-
}
|
|
90
|
-
getActionNameFromChild(childAction) {
|
|
91
|
-
let actionName;
|
|
92
|
-
Object.keys(this.restActionsByName).forEach((restAction) => {
|
|
93
|
-
const restActions = this.restActionsByName[restAction];
|
|
94
|
-
if (restActions.response === childAction || restActions.request === childAction || restActions.error === childAction) {
|
|
95
|
-
actionName = restAction;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
return actionName;
|
|
99
|
-
}
|
|
100
|
-
getActionCodeFromChild(childAction) {
|
|
101
|
-
let actionCode;
|
|
102
|
-
Object.keys(this.actions).forEach((restAction) => {
|
|
103
|
-
const restActions = this.actions[restAction];
|
|
104
|
-
if (restActions.response === childAction || restActions.request === childAction || restActions.error === childAction) {
|
|
105
|
-
actionCode = restAction;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
return Number(actionCode);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const StoreMetadata = '@Store';
|
|
113
|
-
function Store(options) {
|
|
114
|
-
const d = getDebugger(`microphi:@Store:${options.name}`);
|
|
115
|
-
return (target) => {
|
|
116
|
-
d('running store decorator');
|
|
117
|
-
Reflect.defineMetadata(StoreMetadata, options, target);
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function getStoreMetadata(instance) {
|
|
121
|
-
return Reflect.getMetadata(StoreMetadata, instance.constructor);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const ReduceMetadata = '@Reduce';
|
|
125
|
-
function Reduce(onAction) {
|
|
126
|
-
return (target, key) => {
|
|
127
|
-
const d = getDebugger(`microphi:@Reduce:${target.constructor.name}`);
|
|
128
|
-
const reducer = Reflect.getMetadata(ReduceMetadata, target) || {};
|
|
129
|
-
reducer[onAction] = key;
|
|
130
|
-
d('stored reducers', reducer);
|
|
131
|
-
return Reflect.defineMetadata(ReduceMetadata, reducer, target);
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
function getReduceMetadata(instance) {
|
|
135
|
-
return Reflect.getMetadata(ReduceMetadata, instance) || {};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
class BaseStore {
|
|
139
|
-
constructor() {
|
|
140
|
-
this.logger = getDebugger(`microphi:BaseStore:${this.constructor.name}`);
|
|
141
|
-
this.actions$ = new Subject();
|
|
142
|
-
this._loading$ = new Subject();
|
|
143
|
-
this._error$ = new Subject();
|
|
144
|
-
this.destroy$ = new Subject();
|
|
145
|
-
this.storeMetadata = getStoreMetadata(this);
|
|
146
|
-
this.logger('@Store', this.storeMetadata);
|
|
147
|
-
this._store$ = new BehaviorSubject(this.storeMetadata.initialState);
|
|
148
|
-
// dereference initial state so that is does not leak between instances
|
|
149
|
-
this._state = Object.assign({}, this.storeMetadata.initialState);
|
|
150
|
-
this.logger('InitialState', this.state);
|
|
151
|
-
this.actionsMetadata = new Actions(this.storeMetadata.actions);
|
|
152
|
-
const reducerMetadata = getReduceMetadata(this);
|
|
153
|
-
this.logger('Reducers', reducerMetadata);
|
|
154
|
-
const remappedReducers = this.parseReducers(reducerMetadata);
|
|
155
|
-
this.logger('remapped reducers', remappedReducers);
|
|
156
|
-
const effectsMetadata = Reflect.getMetadata('@Effect', this) || {};
|
|
157
|
-
this.logger('Effects', effectsMetadata);
|
|
158
|
-
const remappedEffects = this.remapEffects(effectsMetadata);
|
|
159
|
-
this.logger('remapped effects', remappedEffects);
|
|
160
|
-
this.actions$.pipe(tap((action) => {
|
|
161
|
-
this._loading$.next({
|
|
162
|
-
type: action.type,
|
|
163
|
-
code: this.actionsMetadata.getActionCodeFromChild(action.type),
|
|
164
|
-
payload: action.payload,
|
|
165
|
-
status: action.type.endsWith('_REQUEST')
|
|
166
|
-
});
|
|
167
|
-
}), takeUntil(this.destroy$)).subscribe((action) => {
|
|
168
|
-
this.logger('got type', action);
|
|
169
|
-
const type = action.type;
|
|
170
|
-
// effects are associated with requests
|
|
171
|
-
if (type.endsWith(REQUEST_SUFFIX)) {
|
|
172
|
-
if (remappedEffects.hasOwnProperty(type)) {
|
|
173
|
-
const effectName = remappedEffects[type];
|
|
174
|
-
this.logger('should call', effectName);
|
|
175
|
-
if (this[effectName] instanceof Function) {
|
|
176
|
-
const retValue = this[effectName](action.payload);
|
|
177
|
-
if (retValue instanceof Observable) {
|
|
178
|
-
retValue.pipe(catchError((err) => {
|
|
179
|
-
console.error(`@Effect: ${effectName} thrown the following error`);
|
|
180
|
-
console.error(err);
|
|
181
|
-
this._loading$.next({
|
|
182
|
-
status: false,
|
|
183
|
-
payload: action.payload,
|
|
184
|
-
code: this.actionsMetadata.getActionCodeFromChild(action.type),
|
|
185
|
-
type: action.type,
|
|
186
|
-
});
|
|
187
|
-
this._error$.next({ action: this.actionsMetadata.getActionCodeFromChild(action.type), error: err });
|
|
188
|
-
return throwError(err);
|
|
189
|
-
}), takeUntil(this.destroy$)).subscribe((value) => {
|
|
190
|
-
this.logger('got data', value);
|
|
191
|
-
this.actions$.next({
|
|
192
|
-
type: remappedEffects[effectName],
|
|
193
|
-
payload: value
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
// if there is no effect associated with this action then we can proceed calling the reducer associated
|
|
201
|
-
this.actions$.next({
|
|
202
|
-
type: type.replace(REQUEST_SUFFIX, RESPONSE_SUFFIX),
|
|
203
|
-
payload: action.payload
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
else if (type.endsWith(RESPONSE_SUFFIX)) {
|
|
208
|
-
const fn = remappedReducers[action.type];
|
|
209
|
-
this.logger('should call fn', fn);
|
|
210
|
-
if (this[remappedReducers[action.type]]) {
|
|
211
|
-
try {
|
|
212
|
-
this.state = this[remappedReducers[action.type]](this.state, action.payload);
|
|
213
|
-
}
|
|
214
|
-
catch (e) {
|
|
215
|
-
// we don't need to stop loading here at it has already been stopped
|
|
216
|
-
console.error(`@Reduce ${fn} thrown an error`, e);
|
|
217
|
-
this._error$.next({ action: this.actionsMetadata.getActionCodeFromChild(action.type), error: e });
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}, (err) => {
|
|
222
|
-
this.logger('got error', err);
|
|
223
|
-
// TODO should handle the error or should we change loading$ to a more generic status$ so we can pass altogether
|
|
224
|
-
// loadings and errors events?
|
|
225
|
-
this._error$.next(err);
|
|
226
|
-
console.error(err);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
get state() {
|
|
230
|
-
return this._state;
|
|
231
|
-
}
|
|
232
|
-
set state(value) {
|
|
233
|
-
this.logger('setting new state', value);
|
|
234
|
-
this._state = value;
|
|
235
|
-
this._store$.next(value);
|
|
236
|
-
if (this.storeMetadata.useLocalStorage) {
|
|
237
|
-
this.logger('saving on localStorage');
|
|
238
|
-
localStorage.setItem(this.storeMetadata.name, JSON.stringify(value));
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
get store$() {
|
|
242
|
-
return this._store$.asObservable();
|
|
243
|
-
}
|
|
244
|
-
get loading$() {
|
|
245
|
-
return this._loading$.asObservable();
|
|
246
|
-
}
|
|
247
|
-
get error$() {
|
|
248
|
-
return this._error$.asObservable();
|
|
249
|
-
}
|
|
250
|
-
dispatch(type, payload) {
|
|
251
|
-
const requestAction = this.actionsMetadata.getActionsByCode(type).request;
|
|
252
|
-
this.logger('dispatching type', requestAction);
|
|
253
|
-
this.actions$.next({ type: requestAction, payload });
|
|
254
|
-
}
|
|
255
|
-
parseReducers(reducers) {
|
|
256
|
-
const remappedReducers = {};
|
|
257
|
-
Object.keys(reducers).forEach((action) => {
|
|
258
|
-
if (+action >= 0) {
|
|
259
|
-
const _action = Number(action);
|
|
260
|
-
// this.logger('remapping', type, 'to');
|
|
261
|
-
const realAction = this.actionsMetadata.getActionsByCode(_action).response;
|
|
262
|
-
// this.logger('real type to map to', realAction);
|
|
263
|
-
remappedReducers[realAction] = reducers[action];
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
return remappedReducers;
|
|
267
|
-
}
|
|
268
|
-
remapEffects(effectsMetadata) {
|
|
269
|
-
const remappedEffects = {};
|
|
270
|
-
Object.keys(effectsMetadata).forEach((action) => {
|
|
271
|
-
// effects should react to REQUEST events
|
|
272
|
-
if (+action >= 0) {
|
|
273
|
-
const _action = Number(action);
|
|
274
|
-
const realAction = this.actionsMetadata.getActionsByCode(_action).request;
|
|
275
|
-
remappedEffects[realAction] = effectsMetadata[action];
|
|
276
|
-
// mapping the effect function so that it can return a response type
|
|
277
|
-
remappedEffects[effectsMetadata[action]] = this.actionsMetadata.getActionsByCode(_action).response;
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
return remappedEffects;
|
|
281
|
-
}
|
|
282
|
-
ngOnDestroy() {
|
|
283
|
-
this.destroy$.next();
|
|
284
|
-
this.destroy$.complete();
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function Effect(onAction) {
|
|
289
|
-
return (target, key) => {
|
|
290
|
-
const d = getDebugger(`microphi:@Effect:${target.constructor.name}`);
|
|
291
|
-
d('decorating', key, 'with type', onAction);
|
|
292
|
-
const effects = Reflect.getMetadata('@Effect', target) || {};
|
|
293
|
-
effects[onAction] = key;
|
|
294
|
-
return Reflect.defineMetadata('@Effect', effects, target);
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
class ObservableList {
|
|
299
|
-
constructor(items, idFieldName = 'id') {
|
|
300
|
-
this.idFieldName = idFieldName;
|
|
301
|
-
this.ids = new Set();
|
|
302
|
-
this.data = new Map();
|
|
303
|
-
const ids = items.map((i) => i[this.idFieldName]);
|
|
304
|
-
this.ids = new Set(ids);
|
|
305
|
-
for (const id of ids) {
|
|
306
|
-
this.data.set(id, new BehaviorSubject(items[id]));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
static difference(setA, setB) {
|
|
310
|
-
const _difference = new Set(setA);
|
|
311
|
-
for (const elem of setB) {
|
|
312
|
-
_difference.delete(elem);
|
|
313
|
-
}
|
|
314
|
-
return _difference;
|
|
315
|
-
}
|
|
316
|
-
static intersection(setA, setB) {
|
|
317
|
-
const _intersection = new Set();
|
|
318
|
-
for (const elem of setB) {
|
|
319
|
-
if (setA.has(elem)) {
|
|
320
|
-
_intersection.add(elem);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return _intersection;
|
|
324
|
-
}
|
|
325
|
-
static symmetricDifference(setA, setB) {
|
|
326
|
-
const _difference = new Set(setA);
|
|
327
|
-
for (const elem of setB) {
|
|
328
|
-
if (_difference.has(elem)) {
|
|
329
|
-
_difference.delete(elem);
|
|
330
|
-
}
|
|
331
|
-
else {
|
|
332
|
-
_difference.add(elem);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return _difference;
|
|
336
|
-
}
|
|
337
|
-
*[Symbol.iterator]() {
|
|
338
|
-
// tslint:disable-next-line:forin
|
|
339
|
-
for (const id of this.ids.values()) {
|
|
340
|
-
yield this.data.get(id);
|
|
341
|
-
// yield this.data[id];
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
push(...items) {
|
|
345
|
-
const id = this.idFieldName;
|
|
346
|
-
for (const item of items) {
|
|
347
|
-
if (this.data.has(item[id])) {
|
|
348
|
-
// check whether the item changed;
|
|
349
|
-
const storedItem = this.data.get(item[id]).getValue();
|
|
350
|
-
const shouldUpdate = Object.keys(storedItem).some((key) => {
|
|
351
|
-
return storedItem[key] !== item[key];
|
|
352
|
-
});
|
|
353
|
-
if (shouldUpdate) {
|
|
354
|
-
this.data.get(item[id]).next(item);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
this.ids.add(item[id]);
|
|
359
|
-
this.data.set(item[id], new BehaviorSubject(item));
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
updateOne(item) {
|
|
364
|
-
if (this.data.has(item[this.idFieldName])) {
|
|
365
|
-
this.data.get(item[this.idFieldName]).next(item);
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
console.warn('item not found', item);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
toJSON() {
|
|
372
|
-
const data = [];
|
|
373
|
-
this.data.forEach((value) => {
|
|
374
|
-
data.push(value.getValue());
|
|
375
|
-
});
|
|
376
|
-
return data;
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Will update items that are already present only if they need to be updated and remove items that are not present.
|
|
380
|
-
* @param items items of the list
|
|
381
|
-
*/
|
|
382
|
-
set(...items) {
|
|
383
|
-
const newIds = items.map((i) => i[this.idFieldName]);
|
|
384
|
-
const intersection = ObservableList.intersection(this.ids, newIds);
|
|
385
|
-
for (const id of intersection) {
|
|
386
|
-
this.updateOne(items[id]);
|
|
387
|
-
}
|
|
388
|
-
const itemsToRemove = ObservableList.difference(this.ids, newIds);
|
|
389
|
-
for (const id of itemsToRemove) {
|
|
390
|
-
this.removeItem(id);
|
|
391
|
-
}
|
|
392
|
-
const itemsToAdd = ObservableList.difference(newIds, this.ids);
|
|
393
|
-
for (const id of itemsToAdd) {
|
|
394
|
-
this.addItem(items[id]);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Remove an item from the list given its id
|
|
399
|
-
* @param id id of the item to remove
|
|
400
|
-
*/
|
|
401
|
-
removeItem(id) {
|
|
402
|
-
this.ids.delete(id);
|
|
403
|
-
this.data.delete(id);
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Adds an new item to the list
|
|
407
|
-
* @param item the item to be added
|
|
408
|
-
*/
|
|
409
|
-
addItem(item) {
|
|
410
|
-
const id = item[this.idFieldName];
|
|
411
|
-
this.ids.add(id);
|
|
412
|
-
this.data.set(id, new BehaviorSubject(item));
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
var HttpActions;
|
|
417
|
-
(function (HttpActions) {
|
|
418
|
-
HttpActions[HttpActions["REQUEST"] = 0] = "REQUEST";
|
|
419
|
-
HttpActions[HttpActions["RESPONSE"] = 1] = "RESPONSE";
|
|
420
|
-
HttpActions[HttpActions["ERROR"] = 2] = "ERROR";
|
|
421
|
-
})(HttpActions || (HttpActions = {}));
|
|
422
|
-
let HttpStatusStore = class HttpStatusStore extends BaseStore {
|
|
423
|
-
constructor() {
|
|
424
|
-
super(...arguments);
|
|
425
|
-
// TODO: add explicit constructor
|
|
426
|
-
this.isLoading$ = this.store$.pipe(map((state) => {
|
|
427
|
-
return state.isLoading;
|
|
428
|
-
}));
|
|
429
|
-
}
|
|
430
|
-
onRequest() {
|
|
431
|
-
return {
|
|
432
|
-
isLoading: true
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
onResponse() {
|
|
436
|
-
return {
|
|
437
|
-
isLoading: false
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
onError(state, err) {
|
|
441
|
-
return {
|
|
442
|
-
isLoading: false,
|
|
443
|
-
error: err
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
HttpStatusStore.ɵprov = ɵɵdefineInjectable({ factory: function HttpStatusStore_Factory() { return new HttpStatusStore(); }, token: HttpStatusStore, providedIn: "root" });
|
|
448
|
-
__decorate([
|
|
449
|
-
Reduce(HttpActions.REQUEST)
|
|
450
|
-
], HttpStatusStore.prototype, "onRequest", null);
|
|
451
|
-
__decorate([
|
|
452
|
-
Reduce(HttpActions.RESPONSE)
|
|
453
|
-
], HttpStatusStore.prototype, "onResponse", null);
|
|
454
|
-
__decorate([
|
|
455
|
-
Reduce(HttpActions.ERROR)
|
|
456
|
-
], HttpStatusStore.prototype, "onError", null);
|
|
457
|
-
HttpStatusStore = __decorate([
|
|
458
|
-
Store({
|
|
459
|
-
name: 'httpStatusStore',
|
|
460
|
-
initialState: {
|
|
461
|
-
isLoading: false,
|
|
462
|
-
error: null
|
|
463
|
-
},
|
|
464
|
-
actions: HttpActions
|
|
465
|
-
}),
|
|
466
|
-
Injectable({
|
|
467
|
-
providedIn: 'root'
|
|
468
|
-
})
|
|
469
|
-
], HttpStatusStore);
|
|
470
|
-
|
|
471
|
-
let HttpStatusInterceptor = class HttpStatusInterceptor {
|
|
472
|
-
constructor(httpStatusStore) {
|
|
473
|
-
this.httpStatusStore = httpStatusStore;
|
|
474
|
-
}
|
|
475
|
-
intercept(req, next) {
|
|
476
|
-
this.httpStatusStore.dispatch(HttpActions.REQUEST);
|
|
477
|
-
// extend server response observable with logging
|
|
478
|
-
return next.handle(req)
|
|
479
|
-
.pipe(delay(100), tap(
|
|
480
|
-
// Succeeds when there is a response; ignore other events
|
|
481
|
-
() => {
|
|
482
|
-
this.httpStatusStore.dispatch(HttpActions.RESPONSE);
|
|
483
|
-
},
|
|
484
|
-
// Operation failed; error is an HttpErrorResponse
|
|
485
|
-
(error) => {
|
|
486
|
-
this.httpStatusStore.dispatch(HttpActions.ERROR, error);
|
|
487
|
-
}));
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
HttpStatusInterceptor.ctorParameters = () => [
|
|
491
|
-
{ type: HttpStatusStore }
|
|
492
|
-
];
|
|
493
|
-
HttpStatusInterceptor = __decorate([
|
|
494
|
-
Injectable()
|
|
495
|
-
], HttpStatusInterceptor);
|
|
496
|
-
|
|
497
|
-
class List {
|
|
498
|
-
constructor(entities, IDField) {
|
|
499
|
-
this.IDField = IDField;
|
|
500
|
-
this.entities = new Map();
|
|
501
|
-
/**
|
|
502
|
-
* maps entities position from the original array to their ids
|
|
503
|
-
*/
|
|
504
|
-
this.ids = [];
|
|
505
|
-
this.ids = entities.map((e) => this.getId(e));
|
|
506
|
-
entities
|
|
507
|
-
.forEach((item, idx) => {
|
|
508
|
-
const id = item[IDField];
|
|
509
|
-
this.entities.set(id, item);
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
get size() {
|
|
513
|
-
if (this.ids.length !== this.entities.size) {
|
|
514
|
-
throw new Error(`Size Mismatch ${this.ids.length} !== ${this.entities.size}`);
|
|
515
|
-
}
|
|
516
|
-
return this.entities.size;
|
|
517
|
-
}
|
|
518
|
-
get(id) {
|
|
519
|
-
return this.entities.get(id);
|
|
520
|
-
}
|
|
521
|
-
getId(entity) {
|
|
522
|
-
return entity[this.IDField];
|
|
523
|
-
}
|
|
524
|
-
*[Symbol.iterator]() {
|
|
525
|
-
// tslint:disable-next-line:forin
|
|
526
|
-
for (const idx in this.ids) {
|
|
527
|
-
const id = this.ids[idx];
|
|
528
|
-
yield this.entities.get(id);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
upsert(...entities) {
|
|
532
|
-
entities.forEach((e) => {
|
|
533
|
-
const id = this.getId(e);
|
|
534
|
-
if (!this.entities.has(id)) {
|
|
535
|
-
this.ids.push(id);
|
|
536
|
-
}
|
|
537
|
-
this.entities.set(id, e);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
prepend(...entities) {
|
|
541
|
-
entities.reverse().forEach((e) => {
|
|
542
|
-
const id = this.getId(e);
|
|
543
|
-
if (this.entities.has(id)) {
|
|
544
|
-
console.warn(`Entity with id '${id}' already exists, moving to the top of the list. Entity will be updated`);
|
|
545
|
-
this.delete(e);
|
|
546
|
-
}
|
|
547
|
-
this.ids.unshift(id);
|
|
548
|
-
this.entities.set(id, e);
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
delete(...entities) {
|
|
552
|
-
entities.forEach((e) => {
|
|
553
|
-
const id = this.getId(e);
|
|
554
|
-
const indexOfId = this.ids.findIndex((_id) => _id === id);
|
|
555
|
-
if (indexOfId < 0) {
|
|
556
|
-
console.warn(`Cannot find id: ${id}`);
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
this.ids.splice(indexOfId, 1);
|
|
560
|
-
this.entities.delete(id);
|
|
561
|
-
}
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
append(...entities) {
|
|
565
|
-
entities.forEach((e) => {
|
|
566
|
-
const id = this.getId(e);
|
|
567
|
-
if (this.entities.has(id)) {
|
|
568
|
-
console.warn(`Entity with id '${id}' already exists, moving to the end of the list. Entity will be updated.`);
|
|
569
|
-
this.delete(e);
|
|
570
|
-
}
|
|
571
|
-
this.ids.push(id);
|
|
572
|
-
this.entities.set(id, e);
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
/*
|
|
578
|
-
* Public API Surface of store
|
|
579
|
-
*/
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Generated bundle index. Do not edit.
|
|
583
|
-
*/
|
|
584
|
-
|
|
585
|
-
export { Actions, BaseStore, ERROR_SUFFIX, Effect, HttpActions, HttpStatusInterceptor, HttpStatusStore, List, ObservableList, REQUEST_SUFFIX, RESPONSE_SUFFIX, Reduce, ReduceMetadata, Store, StoreMetadata, getReduceMetadata, getStoreMetadata };
|
|
586
|
-
//# sourceMappingURL=microphi-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"microphi-store.js","sources":["ng://@microphi/store/lib/actions.ts","ng://@microphi/store/lib/store.ts","ng://@microphi/store/lib/reduce.ts","ng://@microphi/store/lib/base-store.ts","ng://@microphi/store/lib/effect.ts","ng://@microphi/store/lib/observable-list/observable-list.ts","ng://@microphi/store/lib/http-status/http-status.store.ts","ng://@microphi/store/lib/http-status/http-status.interceptor.ts","ng://@microphi/store/lib/list/list.ts","ng://@microphi/store/public-api.ts","ng://@microphi/store/microphi-store.ts"],"sourcesContent":["export const REQUEST_SUFFIX = '_REQUEST';\nexport const RESPONSE_SUFFIX = '_RESPONSE';\nexport const ERROR_SUFFIX = '_ERROR';\n\nexport interface Action {\n type: string;\n payload: any;\n}\n\nexport interface RestActions {\n request: string;\n response: string;\n error: string;\n}\n\n\n/**\n * Action are defined with an enum. Such as:\n *\n * emun {\n * GET_ALL,\n * GET_ONE,\n * DELETE,\n * }\n *\n * For each action defined a REQUEST, a RESPONSE and an ERROR are associated to it.\n *\n *\n */\nexport class Actions<A extends any> {\n\n /**\n * Example:\n * {\n * 0: { request: 'ACTION_NAME_REQUEST', response: 'ACTION_NAME_RESPONSE', error: 'ACTION_NAME_ERROR' }\n * [....]\n * }\n */\n public actions: {\n [k: number]: RestActions;\n } = {};\n\n /**\n * Example:\n * {\n * ACTION_NAME: 0\n * [....]\n * }\n *\n */\n public names: {\n [actionName: string]: number;\n } = {};\n\n /**\n * Example:\n * {\n * 0: 'ACTION_NAME',\n * [....]\n *\n * }\n */\n public codes: {\n [actionCode: number]: string\n } = {};\n\n /**\n * Example:\n * {\n * ACTION_NAME': { request: 'ACTION_NAME_REQUEST', response: 'ACTION_NAME_RESPONSE', error: 'ACTION_NAME_ERROR' }\n * [....]\n * }\n */\n public restActionsByName: {\n [name: string]: RestActions;\n } = {};\n\n constructor(actions: A) {\n Object.keys(actions).forEach((key) => {\n if (+key >= 0) {\n\n this.codes[key] = actions[key];\n\n this.actions[key] = Actions.createAction(actions[key]);\n\n } else {\n this.names[key] = actions[key];\n\n this.restActionsByName[key] = Actions.createAction(key);\n }\n\n });\n }\n\n private static createAction(key: string): RestActions {\n return {\n request: `${key}${REQUEST_SUFFIX}`,\n response: `${key}${RESPONSE_SUFFIX}`,\n error: `${key}${ERROR_SUFFIX}`,\n };\n }\n\n public getByName(actionName: string) {\n return this.names[actionName];\n }\n\n public getByCode(code: number) {\n return this.codes[code];\n }\n\n public getActionsByCode(key: number) {\n return this.actions[key];\n }\n\n public getActionsByName(actionName: string) {\n const code = this.getByName(actionName);\n return this.getActionsByCode(code);\n }\n\n public getActionNameFromChild(childAction: string): string {\n let actionName;\n\n Object.keys(this.restActionsByName).forEach((restAction) => {\n const restActions = this.restActionsByName[restAction];\n if (restActions.response === childAction || restActions.request === childAction || restActions.error === childAction) {\n actionName = restAction;\n }\n });\n\n return actionName;\n }\n\n public getActionCodeFromChild(childAction: string): number {\n let actionCode;\n\n Object.keys(this.actions).forEach((restAction) => {\n const restActions = this.actions[restAction];\n if (restActions.response === childAction || restActions.request === childAction || restActions.error === childAction) {\n actionCode = restAction;\n }\n });\n\n return Number(actionCode);\n }\n\n}\n","import { getDebugger } from '@microgamma/loggator';\n\nexport const StoreMetadata = '@Store';\n\nexport interface StoreOptions {\n initialState: any;\n name: string;\n actions: any;\n useLocalStorage?: boolean;\n}\n\nexport function Store(options: StoreOptions) {\n\n const d = getDebugger(`microphi:@Store:${options.name}`);\n\n return (target) => {\n\n d('running store decorator');\n\n Reflect.defineMetadata(StoreMetadata, options, target);\n };\n}\n\nexport function getStoreMetadata(instance): StoreOptions {\n return Reflect.getMetadata(StoreMetadata, instance.constructor);\n}\n\n\n","import { BaseStore } from './base-store';\nimport { getDebugger } from '@microgamma/loggator';\n\nexport const ReduceMetadata = '@Reduce';\n\nexport interface Reducers {\n [actionName: number]: string;\n}\n\nexport function Reduce(onAction: number) {\n return <Store extends BaseStore<any>>(target: Store, key: string) => {\n const d = getDebugger(`microphi:@Reduce:${target.constructor.name}`);\n\n const reducer = Reflect.getMetadata(ReduceMetadata, target) || {};\n\n reducer[onAction] = key;\n\n d('stored reducers', reducer);\n\n return Reflect.defineMetadata(ReduceMetadata, reducer, target);\n\n };\n}\n\nexport function getReduceMetadata(instance): Reducers {\n return Reflect.getMetadata(ReduceMetadata, instance) || {};\n}\n","import { getDebugger } from '@microgamma/loggator';\nimport { BehaviorSubject, Observable, Subject, throwError } from 'rxjs';\nimport { getStoreMetadata, StoreOptions } from './store';\nimport { Action, Actions, REQUEST_SUFFIX, RESPONSE_SUFFIX } from './actions';\nimport { getReduceMetadata } from './reduce';\nimport { catchError, takeUntil, tap } from 'rxjs/operators';\nimport { OnDestroy } from '@angular/core';\n\nexport abstract class BaseStore<T extends {}> implements OnDestroy {\n\n private logger = getDebugger(`microphi:BaseStore:${this.constructor.name}`);\n\n private readonly storeMetadata: StoreOptions;\n private readonly actionsMetadata: Actions<any>;\n\n private _state: T;\n private get state(): T {\n return this._state;\n }\n private set state(value: T) {\n this.logger('setting new state', value);\n this._state = value;\n this._store$.next(value);\n if (this.storeMetadata.useLocalStorage) {\n this.logger('saving on localStorage');\n localStorage.setItem(this.storeMetadata.name, JSON.stringify(value));\n }\n }\n\n private _store$: BehaviorSubject<T>;\n\n public get store$(): Observable<T> {\n return this._store$.asObservable();\n }\n\n private actions$ = new Subject<{\n type: string,\n payload: any\n }>();\n\n private _loading$ = new Subject<{\n type: string,\n code?: number,\n payload: any,\n status: boolean\n }>();\n\n get loading$(): Observable<{ type: string; code?: number; payload: any; status: boolean }> {\n return this._loading$.asObservable();\n }\n\n private _error$ = new Subject<{\n action: number,\n error: any\n }>();\n\n get error$(): Observable<{ action: number; error: any }> {\n return this._error$.asObservable();\n }\n\n private destroy$: Subject<any> = new Subject<any>();\n\n constructor() {\n\n this.storeMetadata = getStoreMetadata(this);\n this.logger('@Store', this.storeMetadata);\n\n this._store$ = new BehaviorSubject(this.storeMetadata.initialState);\n // dereference initial state so that is does not leak between instances\n this._state = Object.assign( {}, this.storeMetadata.initialState);\n this.logger('InitialState', this.state);\n\n this.actionsMetadata = new Actions(this.storeMetadata.actions);\n\n const reducerMetadata = getReduceMetadata(this);\n this.logger('Reducers', reducerMetadata);\n const remappedReducers = this.parseReducers(reducerMetadata);\n this.logger('remapped reducers', remappedReducers);\n\n\n const effectsMetadata = Reflect.getMetadata('@Effect', this) || {};\n this.logger('Effects', effectsMetadata);\n const remappedEffects = this.remapEffects(effectsMetadata);\n this.logger('remapped effects', remappedEffects);\n\n this.actions$.pipe(\n tap((action: Action) => {\n this._loading$.next({\n type: action.type,\n code: this.actionsMetadata.getActionCodeFromChild(action.type),\n payload: action.payload,\n status: action.type.endsWith('_REQUEST')\n });\n\n }),\n takeUntil(this.destroy$),\n ).subscribe( (action: Action) => {\n this.logger('got type', action);\n\n const type = action.type;\n\n // effects are associated with requests\n if (type.endsWith(REQUEST_SUFFIX)) {\n if (remappedEffects.hasOwnProperty(type)) {\n\n const effectName = remappedEffects[type];\n this.logger('should call', effectName);\n\n\n if (this[effectName] instanceof Function) {\n\n const retValue = this[effectName](action.payload) as Observable<any>;\n\n if (retValue instanceof Observable) {\n retValue.pipe(\n catchError((err) => {\n console.error(`@Effect: ${effectName} thrown the following error`);\n console.error(err);\n this._loading$.next({\n status: false,\n payload: action.payload,\n code: this.actionsMetadata.getActionCodeFromChild(action.type),\n type: action.type,\n });\n this._error$.next({action: this.actionsMetadata.getActionCodeFromChild(action.type), error: err});\n return throwError(err);\n }),\n takeUntil(this.destroy$)\n ).subscribe((value) => {\n this.logger('got data', value);\n\n this.actions$.next({\n type: remappedEffects[effectName],\n payload: value\n });\n });\n }\n\n }\n\n } else {\n // if there is no effect associated with this action then we can proceed calling the reducer associated\n this.actions$.next({\n type: type.replace(REQUEST_SUFFIX, RESPONSE_SUFFIX),\n payload: action.payload\n });\n\n }\n } else if (type.endsWith(RESPONSE_SUFFIX)) {\n\n const fn = remappedReducers[action.type];\n this.logger('should call fn', fn);\n\n if (this[remappedReducers[action.type]]) {\n try {\n this.state = this[remappedReducers[action.type]](this.state, action.payload);\n } catch (e) {\n\n // we don't need to stop loading here at it has already been stopped\n\n console.error(`@Reduce ${fn} thrown an error`, e);\n this._error$.next({action: this.actionsMetadata.getActionCodeFromChild(action.type), error: e});\n }\n }\n\n }\n\n }, (err) => {\n this.logger('got error', err);\n // TODO should handle the error or should we change loading$ to a more generic status$ so we can pass altogether\n // loadings and errors events?\n this._error$.next(err);\n console.error(err);\n });\n\n }\n\n public dispatch(type: number, payload?: any) {\n\n const requestAction = this.actionsMetadata.getActionsByCode(type).request;\n this.logger('dispatching type', requestAction);\n\n this.actions$.next({type: requestAction, payload});\n }\n\n private parseReducers(reducers) {\n const remappedReducers = {};\n\n Object.keys(reducers).forEach((action) => {\n if (+action >= 0) {\n const _action: number = Number(action);\n // this.logger('remapping', type, 'to');\n const realAction = this.actionsMetadata.getActionsByCode(_action).response;\n // this.logger('real type to map to', realAction);\n remappedReducers[realAction] = reducers[action];\n }\n });\n\n return remappedReducers;\n }\n\n private remapEffects(effectsMetadata: {}) {\n const remappedEffects = {};\n\n Object.keys(effectsMetadata).forEach((action) => {\n // effects should react to REQUEST events\n\n if (+action >= 0) {\n const _action = Number(action);\n\n const realAction = this.actionsMetadata.getActionsByCode(_action).request;\n\n remappedEffects[realAction] = effectsMetadata[action];\n // mapping the effect function so that it can return a response type\n remappedEffects[effectsMetadata[action]] = this.actionsMetadata.getActionsByCode(_action).response;\n }\n });\n\n return remappedEffects;\n }\n\n public ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n}\n","import { getDebugger } from '@microgamma/loggator';\nimport { BaseStore } from './base-store';\n\nexport function Effect(onAction: number) {\n\n return <Store extends BaseStore<any>>(target: Store, key: string) => {\n\n const d = getDebugger(`microphi:@Effect:${target.constructor.name}`);\n\n d('decorating', key, 'with type', onAction);\n\n const effects = Reflect.getMetadata('@Effect', target) || {};\n\n effects[onAction] = key;\n\n return Reflect.defineMetadata('@Effect', effects, target);\n };\n}\n","import { BehaviorSubject } from 'rxjs';\n\nexport class ObservableList<T extends {}> {\n private readonly ids: Set<string> = new Set<string>();\n private data: Map<string, BehaviorSubject<T>> = new Map();\n\n private static difference(setA, setB): Set<string> {\n const _difference: Set<string> = new Set(setA);\n for (const elem of setB) {\n _difference.delete(elem);\n }\n return _difference;\n }\n\n private static intersection(setA, setB): Set<string> {\n const _intersection: Set<string> = new Set();\n for (const elem of setB) {\n if (setA.has(elem)) {\n _intersection.add(elem);\n }\n }\n return _intersection;\n }\n\n private static symmetricDifference(setA, setB): Set<string> {\n const _difference: Set<string> = new Set(setA);\n for (const elem of setB) {\n if (_difference.has(elem)) {\n _difference.delete(elem);\n } else {\n _difference.add(elem);\n }\n }\n return _difference;\n }\n\n constructor(items: T[], private idFieldName = 'id') {\n const ids = items.map((i) => i[this.idFieldName]);\n this.ids = new Set(ids);\n for (const id of ids) {\n this.data.set(id, new BehaviorSubject(items[id]));\n }\n\n\n }\n\n *[Symbol.iterator](): IterableIterator<BehaviorSubject<T>> {\n\n\n // tslint:disable-next-line:forin\n for (const id of this.ids.values()) {\n yield this.data.get(id);\n // yield this.data[id];\n }\n\n }\n\n public push(...items: T[]) {\n const id = this.idFieldName;\n\n for (const item of items) {\n\n if (this.data.has(item[id])) {\n // check whether the item changed;\n\n const storedItem = this.data.get(item[id]).getValue();\n const shouldUpdate = Object.keys(storedItem).some((key) => {\n return storedItem[key] !== item[key];\n });\n\n if (shouldUpdate) {\n this.data.get(item[id]).next(item);\n }\n } else {\n this.ids.add(item[id]);\n this.data.set(item[id], new BehaviorSubject(item));\n }\n\n }\n\n }\n\n public updateOne(item: T) {\n if (this.data.has(item[this.idFieldName])) {\n\n this.data.get(item[this.idFieldName]).next(item);\n } else {\n console.warn('item not found', item);\n }\n }\n\n public toJSON() {\n\n const data = [];\n\n this.data.forEach((value) => {\n data.push(value.getValue());\n });\n\n return data;\n }\n\n /**\n * Will update items that are already present only if they need to be updated and remove items that are not present.\n * @param items items of the list\n */\n public set(...items: T[]): void {\n const newIds: string[] = items.map((i) => i[this.idFieldName]);\n\n const intersection: Set<string> = ObservableList.intersection(this.ids, newIds);\n\n for (const id of intersection) {\n this.updateOne(items[id]);\n }\n\n const itemsToRemove: Set<string> = ObservableList.difference(this.ids, newIds);\n\n for (const id of itemsToRemove) {\n this.removeItem(id);\n }\n\n const itemsToAdd: Set<string> = ObservableList.difference(newIds, this.ids);\n\n for (const id of itemsToAdd) {\n this.addItem(items[id]);\n }\n\n }\n\n /**\n * Remove an item from the list given its id\n * @param id id of the item to remove\n */\n public removeItem(id: string) {\n this.ids.delete(id);\n this.data.delete(id);\n }\n\n /**\n * Adds an new item to the list\n * @param item the item to be added\n */\n private addItem(item: T) {\n const id = item[this.idFieldName];\n this.ids.add(id);\n this.data.set(id, new BehaviorSubject(item));\n\n }\n}\n","import { map } from 'rxjs/operators';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Store } from '../store';\nimport { BaseStore } from '../base-store';\nimport { Reduce } from '../reduce';\n\nexport interface HttpState {\n isLoading: boolean;\n error?: HttpErrorResponse;\n}\n\nexport enum HttpActions {\n REQUEST,\n RESPONSE,\n ERROR\n}\n\n@Store({\n name: 'httpStatusStore',\n initialState: {\n isLoading: false,\n error: null\n },\n actions: HttpActions\n})\n@Injectable({\n providedIn: 'root'\n})\nexport class HttpStatusStore extends BaseStore<HttpState> {\n // TODO: add explicit constructor\n\n\n\n public isLoading$ = this.store$.pipe(\n map((state) => {\n return state.isLoading;\n })\n );\n\n\n @Reduce(HttpActions.REQUEST)\n private onRequest(): HttpState {\n return {\n isLoading: true\n };\n }\n\n @Reduce(HttpActions.RESPONSE)\n private onResponse(): HttpState {\n return {\n isLoading: false\n };\n }\n\n @Reduce(HttpActions.ERROR)\n public onError(state: HttpState, err): HttpState {\n return {\n isLoading: false,\n error: err\n };\n }\n\n}\n","import { delay, tap } from 'rxjs/operators';\nimport { Injectable } from '@angular/core';\nimport { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { HttpActions, HttpStatusStore } from './http-status.store';\n\n@Injectable()\nexport class HttpStatusInterceptor implements HttpInterceptor {\n constructor(private httpStatusStore: HttpStatusStore) {}\n\n intercept(req: HttpRequest<any>, next: HttpHandler) {\n\n this.httpStatusStore.dispatch(HttpActions.REQUEST);\n\n // extend server response observable with logging\n return next.handle(req)\n .pipe(\n delay(100),\n tap(\n // Succeeds when there is a response; ignore other events\n () => {\n this.httpStatusStore.dispatch(HttpActions.RESPONSE);\n\n },\n // Operation failed; error is an HttpErrorResponse\n (error) => {\n this.httpStatusStore.dispatch(HttpActions.ERROR, error);\n }\n )\n );\n }\n}\n","import { $Keys } from 'utility-types';\n\nexport class List<EntityType extends {}> implements Iterable<EntityType> {\n\n public readonly entities = new Map<any, EntityType>();\n\n /**\n * maps entities position from the original array to their ids\n */\n private readonly ids: any[] = [];\n\n public get size() {\n if (this.ids.length !== this.entities.size) {\n\n throw new Error(`Size Mismatch ${this.ids.length} !== ${this.entities.size}`);\n }\n\n return this.entities.size;\n }\n\n public get(id) {\n return this.entities.get(id);\n }\n private getId(entity: EntityType) {\n return entity[this.IDField];\n }\n\n constructor(entities: EntityType[], private IDField: $Keys<EntityType>) {\n\n this.ids = entities.map((e) => this.getId(e));\n\n entities\n .forEach((item, idx) => {\n const id = item[IDField];\n this.entities.set(id, item);\n });\n }\n\n *[Symbol.iterator](): IterableIterator<EntityType> {\n // tslint:disable-next-line:forin\n for (const idx in this.ids) {\n const id = this.ids[idx];\n yield this.entities.get(id);\n }\n }\n\n public upsert(...entities: EntityType[]) {\n entities.forEach((e) => {\n const id = this.getId(e);\n\n if (!this.entities.has(id)) {\n this.ids.push(id);\n }\n\n this.entities.set(id, e);\n });\n }\n\n public prepend(...entities: EntityType[]) {\n entities.reverse().forEach((e) => {\n const id = this.getId(e);\n\n if (this.entities.has(id)) {\n console.warn(`Entity with id '${id}' already exists, moving to the top of the list. Entity will be updated`);\n this.delete(e);\n }\n\n this.ids.unshift(id);\n\n this.entities.set(id, e);\n\n });\n }\n\n public delete(...entities: EntityType[]) {\n entities.forEach((e) => {\n const id = this.getId(e);\n const indexOfId = this.ids.findIndex((_id) => _id === id);\n\n if (indexOfId < 0) {\n console.warn(`Cannot find id: ${id}`);\n } else {\n this.ids.splice(indexOfId, 1);\n this.entities.delete(id);\n }\n\n });\n }\n\n public append(...entities: EntityType[]) {\n entities.forEach((e) => {\n const id = this.getId(e);\n if (this.entities.has(id)) {\n console.warn(`Entity with id '${id}' already exists, moving to the end of the list. Entity will be updated.`);\n this.delete(e);\n }\n\n this.ids.push(id);\n this.entities.set(id, e);\n });\n }\n}\n","/*\n * Public API Surface of store\n */\n\nexport * from './lib/actions';\nexport * from './lib/base-store';\nexport * from './lib/effect';\nexport * from './lib/reduce';\nexport * from './lib/store';\nexport * from './lib/observable-list/observable-list';\n\nexport * from './lib/http-status/http-status.interceptor';\nexport * from './lib/http-status/http-status.store';\nexport * from './lib/list/list';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;MAAa,cAAc,GAAG,WAAW;MAC5B,eAAe,GAAG,YAAY;MAC9B,YAAY,GAAG,SAAS;AAcrC;;;;;;;;;;;;;MAaa,OAAO;IAgDlB,YAAY,OAAU;;;;;;;;QAvCf,YAAO,GAEV,EAAE,CAAC;;;;;;;;;QAUA,UAAK,GAER,EAAE,CAAC;;;;;;;;;QAUA,UAAK,GAER,EAAE,CAAC;;;;;;;;QASA,sBAAiB,GAEpB,EAAE,CAAC;QAGL,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG;YAC/B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAEb,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBAE/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;aAExD;iBAAM;gBACL,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;gBAE/B,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;aACzD;SAEF,CAAC,CAAC;KACJ;IAEO,OAAO,YAAY,CAAC,GAAW;QACrC,OAAO;YACL,OAAO,EAAE,GAAG,GAAG,GAAG,cAAc,EAAE;YAClC,QAAQ,EAAE,GAAG,GAAG,GAAG,eAAe,EAAE;YACpC,KAAK,EAAE,GAAG,GAAG,GAAG,YAAY,EAAE;SAC/B,CAAC;KACH;IAEM,SAAS,CAAC,UAAkB;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;KAC/B;IAEM,SAAS,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;KACzB;IAEM,gBAAgB,CAAC,GAAW;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;KAC1B;IAEM,gBAAgB,CAAC,UAAkB;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;KACpC;IAEM,sBAAsB,CAAC,WAAmB;QAC/C,IAAI,UAAU,CAAC;QAEf,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;YACrD,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;YACvD,IAAI,WAAW,CAAC,QAAQ,KAAK,WAAW,IAAI,WAAW,CAAC,OAAO,KAAK,WAAW,IAAI,WAAW,CAAC,KAAK,KAAK,WAAW,EAAE;gBACpH,UAAU,GAAG,UAAU,CAAC;aACzB;SACF,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;KACnB;IAEM,sBAAsB,CAAC,WAAmB;QAC/C,IAAI,UAAU,CAAC;QAEf,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;YAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,WAAW,CAAC,QAAQ,KAAK,WAAW,IAAI,WAAW,CAAC,OAAO,KAAK,WAAW,IAAI,WAAW,CAAC,KAAK,KAAK,WAAW,EAAE;gBACpH,UAAU,GAAG,UAAU,CAAC;aACzB;SACF,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC;KAC3B;;;MC7IU,aAAa,GAAG,QAAQ,CAAC;AAStC,SAAgB,KAAK,CAAC,OAAqB;IAEzC,MAAM,CAAC,GAAG,WAAW,CAAC,mBAAmB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzD,OAAO,CAAC,MAAM;QAEZ,CAAC,CAAC,yBAAyB,CAAC,CAAC;QAE7B,OAAO,CAAC,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAQ;IACvC,OAAO,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClE,CAAC;;MCtBY,cAAc,GAAG,SAAS,CAAC;AAMxC,SAAgB,MAAM,CAAC,QAAgB;IACrC,OAAO,CAA+B,MAAa,EAAE,GAAW;QAC9D,MAAM,CAAC,GAAG,WAAW,CAAC,oBAAoB,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAErE,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAElE,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;QAExB,CAAC,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAE9B,OAAO,OAAO,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;KAEhE,CAAC;AACJ,CAAC;AAED,SAAgB,iBAAiB,CAAC,QAAQ;IACxC,OAAO,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;;MClBqB,SAAS;IAsD7B;QApDQ,WAAM,GAAG,WAAW,CAAC,sBAAsB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAyBpE,aAAQ,GAAG,IAAI,OAAO,EAG1B,CAAC;QAEG,cAAS,GAAG,IAAI,OAAO,EAK3B,CAAC;QAMG,YAAO,GAAG,IAAI,OAAO,EAGzB,CAAC;QAMG,aAAQ,GAAiB,IAAI,OAAO,EAAO,CAAC;QAIlD,IAAI,CAAC,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAE1C,IAAI,CAAC,OAAO,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;;QAEpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAE,EAAE,EAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,CAAC,eAAe,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAE/D,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACzC,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;QAGnD,MAAM,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;QAEjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,GAAG,CAAC,CAAC,MAAc;YACjB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC9D,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;aACzC,CAAC,CAAC;SAEJ,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAE,CAAC,MAAc;YAC1B,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAEhC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;;YAGzB,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;gBACjC,IAAI,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;oBAExC,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;oBACzC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;oBAGvC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,QAAQ,EAAE;wBAExC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAoB,CAAC;wBAErE,IAAI,QAAQ,YAAY,UAAU,EAAE;4BAClC,QAAQ,CAAC,IAAI,CACX,UAAU,CAAC,CAAC,GAAG;gCACb,OAAO,CAAC,KAAK,CAAC,YAAY,UAAU,6BAA6B,CAAC,CAAC;gCACnE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gCACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oCAClB,MAAM,EAAE,KAAK;oCACb,OAAO,EAAE,MAAM,CAAC,OAAO;oCACvB,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;oCAC9D,IAAI,EAAE,MAAM,CAAC,IAAI;iCAClB,CAAC,CAAC;gCACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC,CAAC;gCAClG,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;6BACxB,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB,CAAC,SAAS,CAAC,CAAC,KAAK;gCAChB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;gCAE/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oCACjB,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC;oCACjC,OAAO,EAAE,KAAK;iCACf,CAAC,CAAC;6BACJ,CAAC,CAAC;yBACJ;qBAEF;iBAEF;qBAAM;;oBAEL,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACjB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,eAAe,CAAC;wBACnD,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB,CAAC,CAAC;iBAEJ;aACF;iBAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;gBAEzC,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;gBAElC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;oBACvC,IAAI;wBACF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;qBAC9E;oBAAC,OAAO,CAAC,EAAE;;wBAIV,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;wBAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC,CAAC;qBACjG;iBACF;aAEF;SAEF,EAAE,CAAC,GAAG;YACL,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;;;YAG9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACpB,CAAC,CAAC;KAEJ;IA/JD,IAAY,KAAK;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;KACpB;IACD,IAAY,KAAK,CAAC,KAAQ;QACxB,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE;YACtC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;YACtC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;SACtE;KACF;IAID,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;KACpC;IAcD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;KACtC;IAOD,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;KACpC;IAuHM,QAAQ,CAAC,IAAY,EAAE,OAAa;QAEzC,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAE/C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAC,CAAC,CAAC;KACpD;IAEO,aAAa,CAAC,QAAQ;QAC5B,MAAM,gBAAgB,GAAG,EAAE,CAAC;QAE5B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;YACnC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE;gBAChB,MAAM,OAAO,GAAW,MAAM,CAAC,MAAM,CAAC,CAAC;;gBAEvC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;;gBAE3E,gBAAgB,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;aACjD;SACF,CAAC,CAAC;QAEH,OAAO,gBAAgB,CAAC;KACzB;IAEO,YAAY,CAAC,eAAmB;QACtC,MAAM,eAAe,GAAG,EAAE,CAAC;QAE3B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;;YAG1C,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE;gBAChB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAE/B,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;gBAE1E,eAAe,CAAC,UAAU,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;;gBAEtD,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;aACpG;SACF,CAAC,CAAC;QAEH,OAAO,eAAe,CAAC;KACxB;IAEM,WAAW;QAChB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;KAC1B;CAEF;;SC/Ne,MAAM,CAAC,QAAgB;IAErC,OAAO,CAA+B,MAAa,EAAE,GAAW;QAE9D,MAAM,CAAC,GAAG,WAAW,CAAC,oBAAoB,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAErE,CAAC,CAAC,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE5C,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAE7D,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;QAExB,OAAO,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;KAC3D,CAAC;AACJ,CAAC;;MCfY,cAAc;IAkCzB,YAAY,KAAU,EAAU,cAAc,IAAI;QAAlB,gBAAW,GAAX,WAAW,CAAO;QAjCjC,QAAG,GAAgB,IAAI,GAAG,EAAU,CAAC;QAC9C,SAAI,GAAoC,IAAI,GAAG,EAAE,CAAC;QAiCxD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SACnD;KAGF;IAtCO,OAAO,UAAU,CAAC,IAAI,EAAE,IAAI;QAClC,MAAM,WAAW,GAAgB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;YACvB,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SAC1B;QACD,OAAO,WAAW,CAAC;KACpB;IAEO,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI;QACpC,MAAM,aAAa,GAAgB,IAAI,GAAG,EAAE,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;YACvB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBAClB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aACzB;SACF;QACD,OAAO,aAAa,CAAC;KACtB;IAEO,OAAO,mBAAmB,CAAC,IAAI,EAAE,IAAI;QAC3C,MAAM,WAAW,GAAgB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;YACvB,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACzB,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAC1B;iBAAM;gBACL,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aACvB;SACF;QACD,OAAO,WAAW,CAAC;KACpB;IAYD,EAAE,MAAM,CAAC,QAAQ,CAAC;;QAIhB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE;YAClC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;;SAEzB;KAEF;IAEM,IAAI,CAAC,GAAG,KAAU;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YAExB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE;;gBAG3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACtD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG;oBACpD,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;iBACtC,CAAC,CAAC;gBAEH,IAAI,YAAY,EAAE;oBAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACpC;aACF;iBAAM;gBACL,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;aACpD;SAEF;KAEF;IAEM,SAAS,CAAC,IAAO;QACtB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE;YAEzC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClD;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;SACtC;KACF;IAEM,MAAM;QAEX,MAAM,IAAI,GAAG,EAAE,CAAC;QAEhB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK;YACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;SAC7B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;KACb;;;;;IAMM,GAAG,CAAC,GAAG,KAAU;QACtB,MAAM,MAAM,GAAa,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAE/D,MAAM,YAAY,GAAgB,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAEhF,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE;YAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;SAC3B;QAED,MAAM,aAAa,GAAgB,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE/E,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE;YAC9B,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;SACrB;QAED,MAAM,UAAU,GAAgB,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAE5E,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE;YAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;SACzB;KAEF;;;;;IAMM,UAAU,CAAC,EAAU;QAC1B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;KACtB;;;;;IAMO,OAAO,CAAC,IAAO;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;KAE9C;CACF;;ICxIW,WAIX;AAJD,WAAY,WAAW;IACrB,mDAAO,CAAA;IACP,qDAAQ,CAAA;IACR,+CAAK,CAAA;AACP,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAaD,IAAa,eAAe,GAA5B,MAAa,eAAgB,SAAQ,SAAoB;IAAzD;;;QAKS,eAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAClC,GAAG,CAAC,CAAC,KAAK;YACR,OAAO,KAAK,CAAC,SAAS,CAAC;SACxB,CAAC,CACH,CAAC;KAyBH;IArBS,SAAS;QACf,OAAO;YACL,SAAS,EAAE,IAAI;SAChB,CAAC;KACH;IAGO,UAAU;QAChB,OAAO;YACL,SAAS,EAAE,KAAK;SACjB,CAAC;KACH;IAGM,OAAO,CAAC,KAAgB,EAAE,GAAG;QAClC,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,GAAG;SACX,CAAC;KACH;CAEF,CAAA;;AArBC;IADC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;gDAK3B;AAGD;IADC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;iDAK5B;AAGD;IADC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;8CAMzB;AAhCU,eAAe;IAX3B,KAAK,CAAC;QACL,IAAI,EAAE,iBAAiB;QACvB,YAAY,EAAE;YACZ,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,IAAI;SACZ;QACD,OAAO,EAAE,WAAW;KACrB,CAAC;IACD,UAAU,CAAC;QACV,UAAU,EAAE,MAAM;KACnB,CAAC;GACW,eAAe,CAkC3B;;ICzDY,qBAAqB,GAAlC,MAAa,qBAAqB;IAChC,YAAoB,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;KAAI;IAExD,SAAS,CAAC,GAAqB,EAAE,IAAiB;QAEhD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;;QAGnD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;aACpB,IAAI,CACH,KAAK,CAAC,GAAG,CAAC,EACV,GAAG;;QAED;YACE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;SAErD;;QAED,CAAC,KAAK;YACJ,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SACzD,CACF,CACF,CAAC;KACL;CACF,CAAA;;YAvBsC,eAAe;;AADzC,qBAAqB;IADjC,UAAU,EAAE;GACA,qBAAqB,CAwBjC;;MC5BY,IAAI;IAyBf,YAAY,QAAsB,EAAU,OAA0B;QAA1B,YAAO,GAAP,OAAO,CAAmB;QAvBtD,aAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;;;;QAKrC,QAAG,GAAU,EAAE,CAAC;QAoB/B,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9C,QAAQ;aACL,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG;YACjB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;SAC7B,CAAC,CAAC;KACN;IAzBD,IAAW,IAAI;QACb,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAE1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,MAAM,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;SAC/E;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KAC3B;IAEM,GAAG,CAAC,EAAE;QACX,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;KAC9B;IACO,KAAK,CAAC,MAAkB;QAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KAC7B;IAaD,EAAE,MAAM,CAAC,QAAQ,CAAC;;QAEhB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;YAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAC7B;KACF;IAEM,MAAM,CAAC,GAAG,QAAsB;QACrC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAEzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aACnB;YAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAC1B,CAAC,CAAC;KACJ;IAEM,OAAO,CAAC,GAAG,QAAsB;QACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAEzB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,yEAAyE,CAAC,CAAC;gBAC7G,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aAChB;YAED,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAErB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAE1B,CAAC,CAAC;KACJ;IAEM,MAAM,CAAC,GAAG,QAAsB;QACrC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC;YAE1D,IAAI,SAAS,GAAG,CAAC,EAAE;gBACjB,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;aACvC;iBAAM;gBACL,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;aAC1B;SAEF,CAAC,CAAC;KACJ;IAEM,MAAM,CAAC,GAAG,QAAsB;QACrC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACjB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,0EAA0E,CAAC,CAAC;gBAC9G,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aAChB;YAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAC1B,CAAC,CAAC;KACJ;CACF;;ACrGD;;GAEG;;ACFH;;GAEG;;;;"}
|