@microphi/store 2.7.3 → 2.8.1
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/lib/cjs/index.d.ts +3 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +3 -0
- package/lib/cjs/lib/operators/cache.d.ts +20 -0
- package/lib/cjs/lib/operators/cache.d.ts.map +1 -0
- package/lib/cjs/lib/operators/cache.js +38 -0
- package/lib/cjs/lib/operators/debounce.d.ts +12 -0
- package/lib/cjs/lib/operators/debounce.d.ts.map +1 -0
- package/lib/cjs/lib/operators/debounce.js +39 -0
- package/lib/cjs/lib/store/store.d.ts +4 -19
- package/lib/cjs/lib/store/store.d.ts.map +1 -1
- package/lib/cjs/lib/store/store.js +56 -45
- package/lib/cjs/lib/store/types.d.ts +23 -0
- package/lib/cjs/lib/store/types.d.ts.map +1 -0
- package/lib/cjs/lib/store/types.js +2 -0
- package/lib/esm/index.d.ts +3 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +3 -0
- package/lib/esm/lib/operators/cache.d.ts +20 -0
- package/lib/esm/lib/operators/cache.d.ts.map +1 -0
- package/lib/esm/lib/operators/cache.js +34 -0
- package/lib/esm/lib/operators/debounce.d.ts +12 -0
- package/lib/esm/lib/operators/debounce.d.ts.map +1 -0
- package/lib/esm/lib/operators/debounce.js +32 -0
- package/lib/esm/lib/store/store.d.ts +4 -19
- package/lib/esm/lib/store/store.d.ts.map +1 -1
- package/lib/esm/lib/store/store.js +57 -46
- package/lib/esm/lib/store/types.d.ts +23 -0
- package/lib/esm/lib/store/types.d.ts.map +1 -0
- package/lib/esm/lib/store/types.js +1 -0
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/package.json +2 -2
package/lib/cjs/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export * from './lib/store/store';
|
|
2
2
|
export * from './lib/effect/effect';
|
|
3
3
|
export * from './lib/reduce/reduce';
|
|
4
|
+
export * from './lib/operators/cache';
|
|
5
|
+
export * from './lib/operators/debounce';
|
|
6
|
+
export * from './lib/store/types';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC"}
|
package/lib/cjs/index.js
CHANGED
|
@@ -7,3 +7,6 @@ const tslib_1 = require("tslib");
|
|
|
7
7
|
tslib_1.__exportStar(require("./lib/store/store"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./lib/effect/effect"), exports);
|
|
9
9
|
tslib_1.__exportStar(require("./lib/reduce/reduce"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./lib/operators/cache"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./lib/operators/debounce"), exports);
|
|
12
|
+
tslib_1.__exportStar(require("./lib/store/types"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Store } from '../store/store';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { Fn, Key } from '../store/types';
|
|
4
|
+
export declare const CacheSymbol: unique symbol;
|
|
5
|
+
export interface CacheOptions {
|
|
6
|
+
/**
|
|
7
|
+
* time to live in milliseconds
|
|
8
|
+
*/
|
|
9
|
+
ttl?: number;
|
|
10
|
+
/**
|
|
11
|
+
* This function has the same arguments as the decorated method
|
|
12
|
+
*/
|
|
13
|
+
trackBy?: (...args: any[]) => string | number;
|
|
14
|
+
}
|
|
15
|
+
export type EffectMethod = (...args: any[]) => Observable<any>;
|
|
16
|
+
/**
|
|
17
|
+
* Caches an effect's value
|
|
18
|
+
*/
|
|
19
|
+
export declare function Cache(options?: CacheOptions): <S extends Store<any, any>>(_target: S, property: Key, descriptor: TypedPropertyDescriptor<Fn>) => void;
|
|
20
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/lib/operators/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAmB,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,GAAC,MAAM,CAAC;CAC7C;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,wCAEE,CAAC,YAAY,GAAG,cAAc,wBAAwB,EAAE,CAAC,UA2CtG"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Cache = exports.CacheSymbol = void 0;
|
|
4
|
+
exports.CacheSymbol = Symbol('@Cache');
|
|
5
|
+
/**
|
|
6
|
+
* Caches an effect's value
|
|
7
|
+
*/
|
|
8
|
+
function Cache(options) {
|
|
9
|
+
return (_target, property, descriptor) => {
|
|
10
|
+
const originalFn = descriptor.value;
|
|
11
|
+
if (originalFn) {
|
|
12
|
+
descriptor.value = function (...args) {
|
|
13
|
+
const root = this;
|
|
14
|
+
const cache = root[exports.CacheSymbol];
|
|
15
|
+
// this can grow huge
|
|
16
|
+
// shall we put some sort of cap?
|
|
17
|
+
const key = options?.trackBy ? options.trackBy(...args) : JSON.stringify(args);
|
|
18
|
+
const id = `${property}:${key}`;
|
|
19
|
+
const cached = cache.get(id);
|
|
20
|
+
if (cached) {
|
|
21
|
+
// check ttl given timestamp
|
|
22
|
+
const timestamp = cached.timestamp;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const ttl = now - timestamp;
|
|
25
|
+
const maxTtl = options?.ttl || 300000; // 5 minutes
|
|
26
|
+
if (ttl <= maxTtl) {
|
|
27
|
+
const value = cached.value;
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const retValue = originalFn.apply(this, args);
|
|
32
|
+
cache.set(id, { value: retValue, timestamp: Date.now() });
|
|
33
|
+
return retValue;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
exports.Cache = Cache;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { Class } from 'utility-types';
|
|
3
|
+
import { Store } from '../store/store';
|
|
4
|
+
import { Fn, Key } from '../store/types';
|
|
5
|
+
/**
|
|
6
|
+
* Add a debounce to each dispatch of this action
|
|
7
|
+
*/
|
|
8
|
+
export declare function DebounceTime(time: number): <T extends Fn, S extends Store<any, any>>(target: S, key: Key, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T>;
|
|
9
|
+
export declare function getDebounceTimeMetadata<T>(klass: Class<T>, key: string): any;
|
|
10
|
+
export declare function getDebounceTimeMetadataFromInstance(instance: object, key: string): number;
|
|
11
|
+
export declare function getDebounce<T extends object>(instance: T, key: string): number;
|
|
12
|
+
//# sourceMappingURL=debounce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../../src/lib/operators/debounce.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAKzC;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,qDAEkB,CAAC,OAAO,GAAG,cAAc,wBAAwB,CAAC,CAAC,gCAI7G;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAEtE;AAED,wBAAgB,mCAAmC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAQhF;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc9E"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDebounce = exports.getDebounceTimeMetadataFromInstance = exports.getDebounceTimeMetadata = exports.DebounceTime = void 0;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const scan_instance_1 = require("../utilities/scan-instance");
|
|
6
|
+
const DebounceSymbol = Symbol.for('@DebounceTime');
|
|
7
|
+
/**
|
|
8
|
+
* Add a debounce to each dispatch of this action
|
|
9
|
+
*/
|
|
10
|
+
function DebounceTime(time) {
|
|
11
|
+
return (target, key, descriptor) => {
|
|
12
|
+
Reflect.defineMetadata(DebounceSymbol, time, target, key);
|
|
13
|
+
return descriptor;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
exports.DebounceTime = DebounceTime;
|
|
17
|
+
function getDebounceTimeMetadata(klass, key) {
|
|
18
|
+
return Reflect.getMetadata(DebounceSymbol, klass.prototype, key);
|
|
19
|
+
}
|
|
20
|
+
exports.getDebounceTimeMetadata = getDebounceTimeMetadata;
|
|
21
|
+
function getDebounceTimeMetadataFromInstance(instance, key) {
|
|
22
|
+
let debounce = 0;
|
|
23
|
+
(0, scan_instance_1.scanInstance)(instance, (proto) => {
|
|
24
|
+
debounce = Reflect.getMetadata(DebounceSymbol, proto, key);
|
|
25
|
+
});
|
|
26
|
+
return debounce;
|
|
27
|
+
}
|
|
28
|
+
exports.getDebounceTimeMetadataFromInstance = getDebounceTimeMetadataFromInstance;
|
|
29
|
+
function getDebounce(instance, key) {
|
|
30
|
+
let debounce = 0;
|
|
31
|
+
(0, scan_instance_1.scanInstance)(instance, (proto) => {
|
|
32
|
+
const value = Reflect.getMetadata(DebounceSymbol, proto, key);
|
|
33
|
+
if (value) {
|
|
34
|
+
debounce = value;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return debounce;
|
|
38
|
+
}
|
|
39
|
+
exports.getDebounce = getDebounce;
|
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
import { BehaviorSubject, Observable } from 'rxjs';
|
|
2
|
-
import { Reducer } from '../reduce/reduce';
|
|
3
2
|
import { Effect } from '../effect/effect';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export type makeEffects<Actions> = {
|
|
8
|
-
[k in keyof Actions]: Actions[k] extends PureReducer<Primitive> ? never : Actions[k];
|
|
9
|
-
};
|
|
10
|
-
export type makeStore<State, Actions> = {
|
|
11
|
-
[k in keyof makeEffects<Actions>]: makeEffects<Actions>[k];
|
|
12
|
-
} & {
|
|
13
|
-
[k in keyof Actions as `on${Capitalize<string & k>}`]: Actions[k] extends (...args: any) => Observable<infer O> ? (state: State, payload: O) => State : Actions[k] extends PureReducer<infer O> ? (state?: State, payload?: O) => State : (state?: State) => State;
|
|
14
|
-
};
|
|
15
|
-
export interface LoadingState<A> {
|
|
16
|
-
code: keyof A;
|
|
17
|
-
payload?: any;
|
|
18
|
-
response?: any;
|
|
19
|
-
error?: any;
|
|
20
|
-
status: boolean;
|
|
21
|
-
}
|
|
3
|
+
import { Reducer } from '../reduce/reduce';
|
|
4
|
+
import { getPayloadFromActionType, LoadingState } from './types';
|
|
5
|
+
import { CacheSymbol } from '../operators/cache';
|
|
22
6
|
export declare abstract class Store<State, A> {
|
|
23
7
|
private initialState;
|
|
8
|
+
private [CacheSymbol];
|
|
24
9
|
private readonly actions;
|
|
25
10
|
readonly effects: Effect[];
|
|
26
11
|
readonly reducers: Reducer[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/lib/store/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/lib/store/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAS,UAAU,EAAe,MAAM,MAAM,CAAC;AAEvE,OAAO,EAAE,MAAM,EAA8B,MAAM,kBAAkB,CAAC;AAEtE,OAAO,EAAe,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAM,wBAAwB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,8BAAsB,KAAK,CAAC,KAAK,EAAE,CAAC;IA0BtB,OAAO,CAAC,YAAY;IAxBhC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAkE;IAEvF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoE;IAE5F,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAE3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;IAG7B,OAAO,CAAC,SAAS,CAAkC;IAEnD,IAAW,QAAQ,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAEjD;IAED,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,CAGhD;IAEF,IAAW,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,CAErC;gBAEmB,YAAY,EAAE,KAAK;IA4FvC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC;IAMrC,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC;IAOhE,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EACxB,MAAM,EAAE,CAAC,EACT,GAAG,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAa5C,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,WAAW;IAU1B,OAAO,CAAC,YAAY;CAarB"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.Store = void 0;
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
6
|
const rxjs_1 = require("rxjs");
|
|
5
|
-
const reduce_1 = require("../reduce/reduce");
|
|
6
7
|
const operators_1 = require("rxjs/operators");
|
|
7
8
|
const effect_1 = require("../effect/effect");
|
|
9
|
+
const debounce_1 = require("../operators/debounce");
|
|
10
|
+
const reduce_1 = require("../reduce/reduce");
|
|
11
|
+
const cache_1 = require("../operators/cache");
|
|
8
12
|
class Store {
|
|
9
13
|
get loading$() {
|
|
10
14
|
return this._loading$.asObservable();
|
|
@@ -14,6 +18,7 @@ class Store {
|
|
|
14
18
|
}
|
|
15
19
|
constructor(initialState) {
|
|
16
20
|
this.initialState = initialState;
|
|
21
|
+
this[_a] = new Map();
|
|
17
22
|
this.actions = new Map();
|
|
18
23
|
this._loading$ = new rxjs_1.Subject();
|
|
19
24
|
this._store$ = new rxjs_1.BehaviorSubject(
|
|
@@ -21,57 +26,64 @@ class Store {
|
|
|
21
26
|
JSON.parse(JSON.stringify(this.initialState)));
|
|
22
27
|
this.effects = (0, effect_1.getEffects)(this);
|
|
23
28
|
this.reducers = (0, reduce_1.getReducers)(this);
|
|
24
|
-
|
|
25
|
-
const actions = [].concat(this.effects, this.reducers);
|
|
29
|
+
const actions = [...this.effects, ...this.reducers];
|
|
26
30
|
const actionsSet = new Set();
|
|
27
31
|
actions.forEach(({ action }) => actionsSet.add(action));
|
|
28
32
|
actionsSet.forEach((key) => {
|
|
29
33
|
this.actions.set(key, new rxjs_1.Subject());
|
|
30
34
|
const effect = this.effects.find((e) => e.action === key);
|
|
31
35
|
const operator = Store.getOperator(effect.strategy);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
return this[name](...payload).pipe((0, operators_1.tap)((response) => {
|
|
36
|
+
const action = this.actions.get(key);
|
|
37
|
+
const pipeline = [];
|
|
38
|
+
if (action) {
|
|
39
|
+
const debounce = (0, debounce_1.getDebounce)(this, key);
|
|
40
|
+
if (debounce) {
|
|
41
|
+
pipeline.push((0, operators_1.debounceTime)(debounce));
|
|
42
|
+
}
|
|
43
|
+
pipeline.push((0, operators_1.withLatestFrom)(this._store$), (0, operators_1.tap)(([{ payload }]) => {
|
|
42
44
|
this._loading$.next({
|
|
43
|
-
payload,
|
|
44
|
-
|
|
45
|
-
status: false,
|
|
46
|
-
// here the action is done. The action is the only async call
|
|
47
|
-
// we can assume the loading is done as the effect is not async
|
|
45
|
+
payload: payload,
|
|
46
|
+
status: true,
|
|
48
47
|
code: key,
|
|
49
48
|
});
|
|
50
|
-
}),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
49
|
+
}), operator(([{ name, payload }]) => {
|
|
50
|
+
const method = name;
|
|
51
|
+
return this[method](...payload).pipe((0, operators_1.tap)((response) => {
|
|
52
|
+
this._loading$.next({
|
|
53
|
+
payload,
|
|
54
|
+
response,
|
|
55
|
+
status: false,
|
|
56
|
+
// here the action is done. The action is the only async call
|
|
57
|
+
// we can assume the loading is done as the effect is not async
|
|
58
|
+
code: key,
|
|
59
|
+
});
|
|
60
|
+
}),
|
|
61
|
+
// the above is
|
|
62
|
+
(0, operators_1.map)((response) => {
|
|
63
|
+
// if an inner observable emits again the reducer will be triggered again
|
|
64
|
+
// allowing for state changes from the outside.
|
|
65
|
+
// Which sounds terrible said like that but if can actually be handy.
|
|
66
|
+
// For example when a connection state changes:
|
|
67
|
+
//
|
|
68
|
+
// store.dispatch('connect') ->
|
|
69
|
+
// connection happens successfully ->
|
|
70
|
+
// onConnect is called -> state updated
|
|
71
|
+
//
|
|
72
|
+
// ... some time later
|
|
73
|
+
//
|
|
74
|
+
// network connection is lost connection is lost
|
|
75
|
+
// by convention reducer name must be
|
|
76
|
+
// on + Action
|
|
77
|
+
const reducerName = `on${(name[0]).toUpperCase()}${name.slice(1)}`;
|
|
78
|
+
return this[reducerName](this._store$.getValue(), response);
|
|
79
|
+
}),
|
|
80
|
+
// error need to be swallowed here too otherwise the observable chain will be broken
|
|
81
|
+
// meaning that once an action goes into an error it cannot be dispatched again
|
|
82
|
+
(0, operators_1.catchError)((error) => this.swallowError(key, error, payload)));
|
|
83
|
+
}));
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
action.pipe(...pipeline).subscribe(this._store$);
|
|
86
|
+
}
|
|
75
87
|
});
|
|
76
88
|
}
|
|
77
89
|
select(projection) {
|
|
@@ -87,11 +99,9 @@ class Store {
|
|
|
87
99
|
const name = (typeof this[action] === 'function' ? action : 'noopEffect');
|
|
88
100
|
this.actions.get(action)?.next({ name, payload });
|
|
89
101
|
}
|
|
90
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
91
102
|
static noopEffect(payload) {
|
|
92
103
|
return (0, rxjs_1.of)(payload);
|
|
93
104
|
}
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
95
105
|
static getOperator(strategyFn) {
|
|
96
106
|
if (strategyFn === 'mergeMap') {
|
|
97
107
|
return operators_1.mergeMap;
|
|
@@ -115,3 +125,4 @@ class Store {
|
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
127
|
exports.Store = Store;
|
|
128
|
+
_a = cache_1.CacheSymbol;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { Brand, Primitive } from 'utility-types';
|
|
3
|
+
export type Key = string | symbol;
|
|
4
|
+
export type Fn = (...args: any[]) => any;
|
|
5
|
+
export type anything = Record<string, unknown>;
|
|
6
|
+
export type getPayloadFromActionType<A, C extends keyof A> = A[C] extends Fn ? A[C] extends () => any ? never[] : A[C] extends (...args: infer T) => any ? T : never[] : A[C][];
|
|
7
|
+
export type PureReducer<T extends Primitive> = Brand<T, 'reducer'>;
|
|
8
|
+
export type makeEffects<Actions> = {
|
|
9
|
+
[k in keyof Actions]: Actions[k] extends PureReducer<Primitive> ? never : Actions[k];
|
|
10
|
+
};
|
|
11
|
+
export type makeStore<State, Actions> = {
|
|
12
|
+
[k in keyof makeEffects<Actions>]: makeEffects<Actions>[k];
|
|
13
|
+
} & {
|
|
14
|
+
[k in keyof Actions as `on${Capitalize<string & k>}`]: Actions[k] extends (...args: any) => Observable<infer O> ? (state: State, payload: O) => State : Actions[k] extends PureReducer<infer O> ? (state?: State, payload?: O) => State : (state?: State) => State;
|
|
15
|
+
};
|
|
16
|
+
export interface LoadingState<A> {
|
|
17
|
+
code: keyof A;
|
|
18
|
+
payload?: any;
|
|
19
|
+
response?: any;
|
|
20
|
+
error?: any;
|
|
21
|
+
status: boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/lib/store/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC;AAElC,MAAM,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;AAEzC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,wBAAwB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IACvD,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,GACpC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,GAAG,GAC9C,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAE7B,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,SAAS,IAAI,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAEnE,MAAM,MAAM,WAAW,CAAC,OAAO,IAAI;KAEhC,CAAC,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,GAC3D,KAAK,GACL,OAAO,CAAC,CAAC,CAAC;CACf,CAAA;AAED,MAAM,MAAM,SAAS,CAAC,KAAK,EAAE,OAAO,IAClC;KACG,CAAC,IAAI,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3D,GAID;KAEG,CAAC,IAAI,MAAM,OAAO,IAAI,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC,GAC7G,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,KAAK,GACnC,OAAO,CAAC,CAAC,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,GACrC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,KAAK,GACrC,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,KAAK;CAE7B,CAAC;AAEJ,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;CACjB"}
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export * from './lib/store/store';
|
|
2
2
|
export * from './lib/effect/effect';
|
|
3
3
|
export * from './lib/reduce/reduce';
|
|
4
|
+
export * from './lib/operators/cache';
|
|
5
|
+
export * from './lib/operators/debounce';
|
|
6
|
+
export * from './lib/store/types';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC"}
|
package/lib/esm/index.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Store } from '../store/store';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { Fn, Key } from '../store/types';
|
|
4
|
+
export declare const CacheSymbol: unique symbol;
|
|
5
|
+
export interface CacheOptions {
|
|
6
|
+
/**
|
|
7
|
+
* time to live in milliseconds
|
|
8
|
+
*/
|
|
9
|
+
ttl?: number;
|
|
10
|
+
/**
|
|
11
|
+
* This function has the same arguments as the decorated method
|
|
12
|
+
*/
|
|
13
|
+
trackBy?: (...args: any[]) => string | number;
|
|
14
|
+
}
|
|
15
|
+
export type EffectMethod = (...args: any[]) => Observable<any>;
|
|
16
|
+
/**
|
|
17
|
+
* Caches an effect's value
|
|
18
|
+
*/
|
|
19
|
+
export declare function Cache(options?: CacheOptions): <S extends Store<any, any>>(_target: S, property: Key, descriptor: TypedPropertyDescriptor<Fn>) => void;
|
|
20
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/lib/operators/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAEzC,eAAO,MAAM,WAAW,eAAmB,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,GAAC,MAAM,CAAC;CAC7C;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,wCAEE,CAAC,YAAY,GAAG,cAAc,wBAAwB,EAAE,CAAC,UA2CtG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const CacheSymbol = Symbol('@Cache');
|
|
2
|
+
/**
|
|
3
|
+
* Caches an effect's value
|
|
4
|
+
*/
|
|
5
|
+
export function Cache(options) {
|
|
6
|
+
return (_target, property, descriptor) => {
|
|
7
|
+
const originalFn = descriptor.value;
|
|
8
|
+
if (originalFn) {
|
|
9
|
+
descriptor.value = function (...args) {
|
|
10
|
+
const root = this;
|
|
11
|
+
const cache = root[CacheSymbol];
|
|
12
|
+
// this can grow huge
|
|
13
|
+
// shall we put some sort of cap?
|
|
14
|
+
const key = options?.trackBy ? options.trackBy(...args) : JSON.stringify(args);
|
|
15
|
+
const id = `${property}:${key}`;
|
|
16
|
+
const cached = cache.get(id);
|
|
17
|
+
if (cached) {
|
|
18
|
+
// check ttl given timestamp
|
|
19
|
+
const timestamp = cached.timestamp;
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const ttl = now - timestamp;
|
|
22
|
+
const maxTtl = options?.ttl || 300000; // 5 minutes
|
|
23
|
+
if (ttl <= maxTtl) {
|
|
24
|
+
const value = cached.value;
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const retValue = originalFn.apply(this, args);
|
|
29
|
+
cache.set(id, { value: retValue, timestamp: Date.now() });
|
|
30
|
+
return retValue;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { Class } from 'utility-types';
|
|
3
|
+
import { Store } from '../store/store';
|
|
4
|
+
import { Fn, Key } from '../store/types';
|
|
5
|
+
/**
|
|
6
|
+
* Add a debounce to each dispatch of this action
|
|
7
|
+
*/
|
|
8
|
+
export declare function DebounceTime(time: number): <T extends Fn, S extends Store<any, any>>(target: S, key: Key, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T>;
|
|
9
|
+
export declare function getDebounceTimeMetadata<T>(klass: Class<T>, key: string): any;
|
|
10
|
+
export declare function getDebounceTimeMetadataFromInstance(instance: object, key: string): number;
|
|
11
|
+
export declare function getDebounce<T extends object>(instance: T, key: string): number;
|
|
12
|
+
//# sourceMappingURL=debounce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../../../src/lib/operators/debounce.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAKzC;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,qDAEkB,CAAC,OAAO,GAAG,cAAc,wBAAwB,CAAC,CAAC,gCAI7G;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAEtE;AAED,wBAAgB,mCAAmC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAQhF;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAc9E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { scanInstance } from '../utilities/scan-instance';
|
|
3
|
+
const DebounceSymbol = Symbol.for('@DebounceTime');
|
|
4
|
+
/**
|
|
5
|
+
* Add a debounce to each dispatch of this action
|
|
6
|
+
*/
|
|
7
|
+
export function DebounceTime(time) {
|
|
8
|
+
return (target, key, descriptor) => {
|
|
9
|
+
Reflect.defineMetadata(DebounceSymbol, time, target, key);
|
|
10
|
+
return descriptor;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function getDebounceTimeMetadata(klass, key) {
|
|
14
|
+
return Reflect.getMetadata(DebounceSymbol, klass.prototype, key);
|
|
15
|
+
}
|
|
16
|
+
export function getDebounceTimeMetadataFromInstance(instance, key) {
|
|
17
|
+
let debounce = 0;
|
|
18
|
+
scanInstance(instance, (proto) => {
|
|
19
|
+
debounce = Reflect.getMetadata(DebounceSymbol, proto, key);
|
|
20
|
+
});
|
|
21
|
+
return debounce;
|
|
22
|
+
}
|
|
23
|
+
export function getDebounce(instance, key) {
|
|
24
|
+
let debounce = 0;
|
|
25
|
+
scanInstance(instance, (proto) => {
|
|
26
|
+
const value = Reflect.getMetadata(DebounceSymbol, proto, key);
|
|
27
|
+
if (value) {
|
|
28
|
+
debounce = value;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return debounce;
|
|
32
|
+
}
|
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
import { BehaviorSubject, Observable } from 'rxjs';
|
|
2
|
-
import { Reducer } from '../reduce/reduce';
|
|
3
2
|
import { Effect } from '../effect/effect';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export type makeEffects<Actions> = {
|
|
8
|
-
[k in keyof Actions]: Actions[k] extends PureReducer<Primitive> ? never : Actions[k];
|
|
9
|
-
};
|
|
10
|
-
export type makeStore<State, Actions> = {
|
|
11
|
-
[k in keyof makeEffects<Actions>]: makeEffects<Actions>[k];
|
|
12
|
-
} & {
|
|
13
|
-
[k in keyof Actions as `on${Capitalize<string & k>}`]: Actions[k] extends (...args: any) => Observable<infer O> ? (state: State, payload: O) => State : Actions[k] extends PureReducer<infer O> ? (state?: State, payload?: O) => State : (state?: State) => State;
|
|
14
|
-
};
|
|
15
|
-
export interface LoadingState<A> {
|
|
16
|
-
code: keyof A;
|
|
17
|
-
payload?: any;
|
|
18
|
-
response?: any;
|
|
19
|
-
error?: any;
|
|
20
|
-
status: boolean;
|
|
21
|
-
}
|
|
3
|
+
import { Reducer } from '../reduce/reduce';
|
|
4
|
+
import { getPayloadFromActionType, LoadingState } from './types';
|
|
5
|
+
import { CacheSymbol } from '../operators/cache';
|
|
22
6
|
export declare abstract class Store<State, A> {
|
|
23
7
|
private initialState;
|
|
8
|
+
private [CacheSymbol];
|
|
24
9
|
private readonly actions;
|
|
25
10
|
readonly effects: Effect[];
|
|
26
11
|
readonly reducers: Reducer[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/lib/store/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/lib/store/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAS,UAAU,EAAe,MAAM,MAAM,CAAC;AAEvE,OAAO,EAAE,MAAM,EAA8B,MAAM,kBAAkB,CAAC;AAEtE,OAAO,EAAe,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAM,wBAAwB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,8BAAsB,KAAK,CAAC,KAAK,EAAE,CAAC;IA0BtB,OAAO,CAAC,YAAY;IAxBhC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAkE;IAEvF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoE;IAE5F,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAE3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;IAG7B,OAAO,CAAC,SAAS,CAAkC;IAEnD,IAAW,QAAQ,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAEjD;IAED,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,CAGhD;IAEF,IAAW,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,CAErC;gBAEmB,YAAY,EAAE,KAAK;IA4FvC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC;IAMrC,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC;IAOhE,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,EACxB,MAAM,EAAE,CAAC,EACT,GAAG,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAa5C,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,WAAW;IAU1B,OAAO,CAAC,YAAY;CAarB"}
|