@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.
Files changed (66) hide show
  1. package/esm2020/lib/effect/effect.mjs +75 -0
  2. package/esm2020/lib/list/list.mjs +75 -0
  3. package/esm2020/lib/reduce/reduce.mjs +26 -0
  4. package/esm2020/lib/store/store.mjs +101 -0
  5. package/esm2020/lib/utilities/scan-instance.mjs +19 -0
  6. package/esm2020/microphi-store.mjs +5 -0
  7. package/esm2020/public-api.mjs +8 -0
  8. package/fesm2015/microphi-store.mjs +305 -0
  9. package/fesm2015/microphi-store.mjs.map +1 -0
  10. package/fesm2020/microphi-store.mjs +303 -0
  11. package/fesm2020/microphi-store.mjs.map +1 -0
  12. package/index.d.ts +6 -0
  13. package/lib/effect/effect.d.ts +62 -0
  14. package/lib/effect/effect.d.ts.map +1 -0
  15. package/lib/list/list.d.ts +2 -1
  16. package/lib/list/list.d.ts.map +1 -0
  17. package/lib/reduce/reduce.d.ts +12 -0
  18. package/lib/reduce/reduce.d.ts.map +1 -0
  19. package/lib/store/store.d.ts +39 -0
  20. package/lib/store/store.d.ts.map +1 -0
  21. package/lib/utilities/scan-instance.d.ts +3 -0
  22. package/lib/utilities/scan-instance.d.ts.map +1 -0
  23. package/microphi-store.d.ts.map +1 -0
  24. package/package.json +23 -17
  25. package/public-api.d.ts +4 -8
  26. package/public-api.d.ts.map +1 -0
  27. package/bundles/microphi-store.umd.js +0 -996
  28. package/bundles/microphi-store.umd.js.map +0 -1
  29. package/bundles/microphi-store.umd.min.js +0 -16
  30. package/bundles/microphi-store.umd.min.js.map +0 -1
  31. package/esm2015/lib/actions.js +0 -105
  32. package/esm2015/lib/base-store.js +0 -156
  33. package/esm2015/lib/effect.js +0 -11
  34. package/esm2015/lib/http-status/http-status.interceptor.js +0 -31
  35. package/esm2015/lib/http-status/http-status.store.js +0 -63
  36. package/esm2015/lib/list/list.js +0 -80
  37. package/esm2015/lib/observable-list/observable-list.js +0 -119
  38. package/esm2015/lib/reduce.js +0 -15
  39. package/esm2015/lib/store.js +0 -13
  40. package/esm2015/microphi-store.js +0 -5
  41. package/esm2015/public-api.js +0 -13
  42. package/esm5/lib/actions.js +0 -110
  43. package/esm5/lib/base-store.js +0 -177
  44. package/esm5/lib/effect.js +0 -11
  45. package/esm5/lib/http-status/http-status.interceptor.js +0 -33
  46. package/esm5/lib/http-status/http-status.store.js +0 -66
  47. package/esm5/lib/list/list.js +0 -126
  48. package/esm5/lib/observable-list/observable-list.js +0 -250
  49. package/esm5/lib/reduce.js +0 -15
  50. package/esm5/lib/store.js +0 -13
  51. package/esm5/microphi-store.js +0 -5
  52. package/esm5/public-api.js +0 -13
  53. package/fesm2015/microphi-store.js +0 -586
  54. package/fesm2015/microphi-store.js.map +0 -1
  55. package/fesm5/microphi-store.js +0 -788
  56. package/fesm5/microphi-store.js.map +0 -1
  57. package/lib/actions.d.ts +0 -77
  58. package/lib/base-store.d.ts +0 -31
  59. package/lib/effect.d.ts +0 -2
  60. package/lib/http-status/http-status.interceptor.d.ts +0 -7
  61. package/lib/http-status/http-status.store.d.ts +0 -17
  62. package/lib/observable-list/observable-list.d.ts +0 -29
  63. package/lib/reduce.d.ts +0 -7
  64. package/lib/store.d.ts +0 -9
  65. package/microphi-store.d.ts +0 -4
  66. package/microphi-store.metadata.json +0 -1
@@ -0,0 +1,75 @@
1
+ import { scanInstance } from '../utilities/scan-instance';
2
+ export const EffectSymbol = Symbol.for('@Effect');
3
+ /**
4
+ * Tags a method as an effect <br>
5
+ *
6
+ * Strategy is one of the following rxjs pipe-able operators:
7
+ * - `mergeMap`
8
+ * - `concatMap`
9
+ * - `switchMap`
10
+ *
11
+ * As an example consider the following:
12
+ * suppose there's an effect that takes 10 ms to return and then a reducer is called.<br>
13
+ * Suppose we dispatch its event, the following diagram demonstrate what happens<br>
14
+ * <code>
15
+ * `D -> E -> (10) -> R`<br>
16
+ * </code>
17
+ * Event is dispatched `D`, event is executed `E`, takes 10ms and finally reducer is called with result from `E`
18
+ *
19
+ * Now let's suppose we dispatch again the same while `E` is still pending (executing) and suppose we call it with a different argument.
20
+ *
21
+ *
22
+ * `D(a) -> E -> D(b)`
23
+ *
24
+ *
25
+ * what happens next depends on the strategy used.<br>
26
+ *
27
+ *
28
+ * If `switchMap` is used (default)
29
+ *
30
+ * `D(a) -> E(a) -> D(b) -> E(b) -> R(b)`
31
+ *
32
+ * the second dispatch cancels the first and so only `R(b)` is executed
33
+ *
34
+ *
35
+ * If `mergeMap` is used
36
+ *
37
+ * `D(a) -> E(a) -> D(b) -> E(b) -> R(a) -> R(b)
38
+ *
39
+ * effects are executed in parallel and the first to come is the first served
40
+ *
41
+ * i.e.: lets say E(a) takes longer to respond then
42
+ *
43
+ * `D(a) -> D(b) -> E(b) -> R(b) -> E(a) -> -> R(a)`
44
+ *
45
+ *
46
+ * If `concatMap` is used then the order of calls is respected.
47
+ *
48
+ * in the case above we'll have whatever the timings are on the effects
49
+ *
50
+ * `D(a) -> D(b) -> E(a) -> R(a) -> E(b) -> -> R(b)`
51
+ *
52
+ * @param strategy
53
+ * @constructor
54
+ */
55
+ export function Effect(strategy = 'switchMap') {
56
+ // return Reflect.metadata(EffectSymbol, strategy);
57
+ return (target, propertyKey) => {
58
+ // return Reflect.metadata(EffectSymbol, strategy)(target, propertyKey);
59
+ return Reflect.defineMetadata(EffectSymbol, strategy, target, propertyKey);
60
+ };
61
+ }
62
+ export function getEffectMetadata(klass, key) {
63
+ return Reflect.getMetadata(EffectSymbol, klass, key);
64
+ }
65
+ export function getEffects(instance) {
66
+ const effects = [];
67
+ scanInstance(instance, (proto, key) => {
68
+ const strategy = getEffectMetadata(proto, key);
69
+ if (strategy) {
70
+ effects.push({ action: key, strategy, });
71
+ }
72
+ });
73
+ return effects;
74
+ }
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3RvcmUvc3JjL2xpYi9lZmZlY3QvZWZmZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQVMxRCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUVsRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbURHO0FBQ0gsTUFBTSxVQUFVLE1BQU0sQ0FBQyxXQUEyQixXQUFXO0lBQzNELG1EQUFtRDtJQUNuRCxPQUFPLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxFQUFFO1FBQzdCLHdFQUF3RTtRQUN4RSxPQUFPLE9BQU8sQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDN0UsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxLQUFhLEVBQUUsR0FBVztJQUMxRCxPQUFPLE9BQU8sQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztBQUN2RCxDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FBbUIsUUFBVztJQUV0RCxNQUFNLE9BQU8sR0FBYSxFQUFFLENBQUM7SUFFN0IsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUVwQyxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsSUFBSSxRQUFRLEVBQUU7WUFDWixPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxRQUFRLEdBQUUsQ0FBQyxDQUFDO1NBQ3hDO0lBRUgsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RvcmUgfSBmcm9tICcuLi9zdG9yZS9zdG9yZSc7XG5pbXBvcnQgeyAkS2V5cyB9IGZyb20gJ3V0aWxpdHktdHlwZXMnO1xuaW1wb3J0IHsgc2Nhbkluc3RhbmNlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL3NjYW4taW5zdGFuY2UnO1xuXG5leHBvcnQgdHlwZSBFZmZlY3RTdHJhdGVneSA9ICdzd2l0Y2hNYXAnIHwgJ21lcmdlTWFwJyB8ICdjb25jYXRNYXAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEVmZmVjdCB7XG4gIGFjdGlvbjogc3RyaW5nO1xuICBzdHJhdGVneTogRWZmZWN0U3RyYXRlZ3k7XG59XG5cbmV4cG9ydCBjb25zdCBFZmZlY3RTeW1ib2wgPSBTeW1ib2wuZm9yKCdARWZmZWN0Jyk7XG5cbi8qKlxuICogVGFncyBhIG1ldGhvZCBhcyBhbiBlZmZlY3QgPGJyPlxuICpcbiAqIFN0cmF0ZWd5IGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nIHJ4anMgcGlwZS1hYmxlIG9wZXJhdG9yczpcbiAqIC0gYG1lcmdlTWFwYFxuICogLSBgY29uY2F0TWFwYFxuICogLSBgc3dpdGNoTWFwYFxuICpcbiAqIEFzIGFuIGV4YW1wbGUgY29uc2lkZXIgdGhlIGZvbGxvd2luZzpcbiAqIHN1cHBvc2UgdGhlcmUncyBhbiBlZmZlY3QgdGhhdCB0YWtlcyAxMCBtcyB0byByZXR1cm4gYW5kIHRoZW4gYSByZWR1Y2VyIGlzIGNhbGxlZC48YnI+XG4gKiBTdXBwb3NlIHdlIGRpc3BhdGNoIGl0cyBldmVudCwgdGhlIGZvbGxvd2luZyBkaWFncmFtIGRlbW9uc3RyYXRlIHdoYXQgaGFwcGVuczxicj5cbiAqICA8Y29kZT5cbiAqIGBEIC0+IEUgLT4gKDEwKSAtPiBSYDxicj5cbiAqICA8L2NvZGU+XG4gKiBFdmVudCBpcyBkaXNwYXRjaGVkIGBEYCwgZXZlbnQgaXMgZXhlY3V0ZWQgYEVgLCB0YWtlcyAxMG1zIGFuZCBmaW5hbGx5IHJlZHVjZXIgaXMgY2FsbGVkIHdpdGggcmVzdWx0IGZyb20gYEVgXG4gKlxuICogTm93IGxldCdzIHN1cHBvc2Ugd2UgZGlzcGF0Y2ggYWdhaW4gdGhlIHNhbWUgd2hpbGUgYEVgIGlzIHN0aWxsIHBlbmRpbmcgKGV4ZWN1dGluZykgYW5kIHN1cHBvc2Ugd2UgY2FsbCBpdCB3aXRoIGEgZGlmZmVyZW50IGFyZ3VtZW50LlxuICpcbiAqXG4gKiBgRChhKSAtPiBFIC0+IEQoYilgXG4gKlxuICpcbiAqIHdoYXQgaGFwcGVucyBuZXh0IGRlcGVuZHMgb24gdGhlIHN0cmF0ZWd5IHVzZWQuPGJyPlxuICpcbiAqXG4gKiBJZiBgc3dpdGNoTWFwYCBpcyB1c2VkIChkZWZhdWx0KVxuICpcbiAqIGBEKGEpIC0+IEUoYSkgLT4gRChiKSAtPiBFKGIpIC0+IFIoYilgXG4gKlxuICogdGhlIHNlY29uZCBkaXNwYXRjaCBjYW5jZWxzIHRoZSBmaXJzdCBhbmQgc28gb25seSBgUihiKWAgaXMgZXhlY3V0ZWRcbiAqXG4gKlxuICogSWYgYG1lcmdlTWFwYCBpcyB1c2VkXG4gKlxuICogYEQoYSkgLT4gRShhKSAtPiBEKGIpIC0+IEUoYikgLT4gUihhKSAtPiBSKGIpXG4gKlxuICogZWZmZWN0cyBhcmUgZXhlY3V0ZWQgaW4gcGFyYWxsZWwgYW5kIHRoZSBmaXJzdCB0byBjb21lIGlzIHRoZSBmaXJzdCBzZXJ2ZWRcbiAqXG4gKiBpLmUuOiBsZXRzIHNheSBFKGEpIHRha2VzIGxvbmdlciB0byByZXNwb25kIHRoZW5cbiAqXG4gKiBgRChhKSAtPiBEKGIpIC0+IEUoYikgLT4gIFIoYikgLT4gRShhKSAtPiAtPiBSKGEpYFxuICpcbiAqXG4gKiBJZiBgY29uY2F0TWFwYCBpcyB1c2VkIHRoZW4gdGhlIG9yZGVyIG9mIGNhbGxzIGlzIHJlc3BlY3RlZC5cbiAqXG4gKiBpbiB0aGUgY2FzZSBhYm92ZSB3ZSdsbCBoYXZlIHdoYXRldmVyIHRoZSB0aW1pbmdzIGFyZSBvbiB0aGUgZWZmZWN0c1xuICpcbiAqIGBEKGEpIC0+IEQoYikgLT4gRShhKSAtPiAgUihhKSAtPiBFKGIpIC0+IC0+IFIoYilgXG4gKlxuICogQHBhcmFtIHN0cmF0ZWd5XG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEVmZmVjdChzdHJhdGVneTogRWZmZWN0U3RyYXRlZ3kgPSAnc3dpdGNoTWFwJyk6IE1ldGhvZERlY29yYXRvciB7XG4gIC8vIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKEVmZmVjdFN5bWJvbCwgc3RyYXRlZ3kpO1xuICByZXR1cm4gKHRhcmdldCwgcHJvcGVydHlLZXkpID0+IHtcbiAgICAvLyByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShFZmZlY3RTeW1ib2wsIHN0cmF0ZWd5KSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICByZXR1cm4gUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShFZmZlY3RTeW1ib2wsIHN0cmF0ZWd5LCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVmZmVjdE1ldGFkYXRhKGtsYXNzOiBvYmplY3QsIGtleTogc3RyaW5nKSB7XG4gIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhKEVmZmVjdFN5bWJvbCwga2xhc3MsIGtleSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFZmZlY3RzPFQgZXh0ZW5kcyBvYmplY3Q+KGluc3RhbmNlOiBUKTogRWZmZWN0W10ge1xuXG4gIGNvbnN0IGVmZmVjdHM6IEVmZmVjdFtdID0gW107XG5cbiAgc2Nhbkluc3RhbmNlKGluc3RhbmNlLCAocHJvdG8sIGtleSkgPT4ge1xuXG4gICAgY29uc3Qgc3RyYXRlZ3kgPSBnZXRFZmZlY3RNZXRhZGF0YShwcm90bywga2V5KTtcbiAgICBpZiAoc3RyYXRlZ3kpIHtcbiAgICAgIGVmZmVjdHMucHVzaCh7YWN0aW9uOiBrZXksIHN0cmF0ZWd5LH0pO1xuICAgIH1cblxuICB9KTtcblxuICByZXR1cm4gZWZmZWN0cztcbn1cbiJdfQ==
@@ -0,0 +1,75 @@
1
+ export class List {
2
+ constructor(IDField, entities = []) {
3
+ this.IDField = IDField;
4
+ this.entities = new Map();
5
+ /**
6
+ * maps entities position from the original array to their ids
7
+ */
8
+ this.ids = [];
9
+ this.ids = entities.map((e) => this.getId(e));
10
+ entities
11
+ .forEach((item, idx) => {
12
+ const id = item[IDField];
13
+ this.entities.set(id, item);
14
+ });
15
+ }
16
+ get size() {
17
+ if (this.ids.length !== this.entities.size) {
18
+ throw new Error(`Size Mismatch ${this.ids.length} !== ${this.entities.size}`);
19
+ }
20
+ return this.entities.size;
21
+ }
22
+ get(id) {
23
+ return this.entities.get(id);
24
+ }
25
+ getId(entity) {
26
+ return entity[this.IDField];
27
+ }
28
+ *[Symbol.iterator]() {
29
+ // tslint:disable-next-line:forin
30
+ for (const idx in this.ids) {
31
+ const id = this.ids[idx];
32
+ yield this.entities.get(id);
33
+ }
34
+ }
35
+ upsert(...entities) {
36
+ entities.forEach((e) => {
37
+ const id = this.getId(e);
38
+ if (!this.entities.has(id)) {
39
+ this.ids.push(id);
40
+ }
41
+ this.entities.set(id, e);
42
+ });
43
+ }
44
+ prepend(...entities) {
45
+ entities.reverse().forEach((e) => {
46
+ const id = this.getId(e);
47
+ if (this.entities.has(id)) {
48
+ this.delete(e);
49
+ }
50
+ this.ids.unshift(id);
51
+ this.entities.set(id, e);
52
+ });
53
+ }
54
+ delete(...entities) {
55
+ entities.forEach((e) => {
56
+ const id = this.getId(e);
57
+ const indexOfId = this.ids.findIndex((_id) => _id === id);
58
+ if (indexOfId >= 0) {
59
+ this.ids.splice(indexOfId, 1);
60
+ this.entities.delete(id);
61
+ }
62
+ });
63
+ }
64
+ append(...entities) {
65
+ entities.forEach((e) => {
66
+ const id = this.getId(e);
67
+ if (this.entities.has(id)) {
68
+ this.delete(e);
69
+ }
70
+ this.ids.push(id);
71
+ this.entities.set(id, e);
72
+ });
73
+ }
74
+ }
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlL3NyYy9saWIvbGlzdC9saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE1BQU0sT0FBTyxJQUFJO0lBeUJmLFlBQW9CLE9BQTBCLEVBQUUsV0FBeUIsRUFBRTtRQUF2RCxZQUFPLEdBQVAsT0FBTyxDQUFtQjtRQXZCOUIsYUFBUSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO1FBRXREOztXQUVHO1FBQ2MsUUFBRyxHQUFVLEVBQUUsQ0FBQztRQW9CL0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFOUMsUUFBUTthQUNMLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNyQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQXpCRCxJQUFXLElBQUk7UUFDYixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO1lBRTFDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxRQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUMvRTtRQUVELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDNUIsQ0FBQztJQUVNLEdBQUcsQ0FBQyxFQUFFO1FBQ1gsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FB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QUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ICRLZXlzIH0gZnJvbSAndXRpbGl0eS10eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBMaXN0PEVudGl0eVR5cGUgZXh0ZW5kcyB7fT4gaW1wbGVtZW50cyBJdGVyYWJsZTxFbnRpdHlUeXBlPiB7XG5cbiAgcHVibGljIHJlYWRvbmx5IGVudGl0aWVzID0gbmV3IE1hcDxhbnksIEVudGl0eVR5cGU+KCk7XG5cbiAgLyoqXG4gICAqIG1hcHMgZW50aXRpZXMgcG9zaXRpb24gZnJvbSB0aGUgb3JpZ2luYWwgYXJyYXkgdG8gdGhlaXIgaWRzXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGlkczogYW55W10gPSBbXTtcblxuICBwdWJsaWMgZ2V0IHNpemUoKSB7XG4gICAgaWYgKHRoaXMuaWRzLmxlbmd0aCAhPT0gdGhpcy5lbnRpdGllcy5zaXplKSB7XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2l6ZSBNaXNtYXRjaCAke3RoaXMuaWRzLmxlbmd0aH0gIT09ICR7dGhpcy5lbnRpdGllcy5zaXplfWApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmVudGl0aWVzLnNpemU7XG4gIH1cblxuICBwdWJsaWMgZ2V0KGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXRpZXMuZ2V0KGlkKTtcbiAgfVxuICBwcml2YXRlIGdldElkKGVudGl0eTogRW50aXR5VHlwZSkge1xuICAgIHJldHVybiBlbnRpdHlbdGhpcy5JREZpZWxkXTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgSURGaWVsZDogJEtleXM8RW50aXR5VHlwZT4sIGVudGl0aWVzOiBFbnRpdHlUeXBlW10gPSBbXSkge1xuXG4gICAgdGhpcy5pZHMgPSBlbnRpdGllcy5tYXAoKGUpID0+IHRoaXMuZ2V0SWQoZSkpO1xuXG4gICAgZW50aXRpZXNcbiAgICAgIC5mb3JFYWNoKChpdGVtLCBpZHgpID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBpdGVtW0lERmllbGRdO1xuICAgICAgICB0aGlzLmVudGl0aWVzLnNldChpZCwgaXRlbSk7XG4gICAgICB9KTtcbiAgfVxuXG4gICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBJdGVyYWJsZUl0ZXJhdG9yPEVudGl0eVR5cGU+IHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Zm9yaW5cbiAgICBmb3IgKGNvbnN0IGlkeCBpbiB0aGlzLmlkcykge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLmlkc1tpZHhdO1xuICAgICAgeWllbGQgdGhpcy5lbnRpdGllcy5nZXQoaWQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB1cHNlcnQoLi4uZW50aXRpZXM6IEVudGl0eVR5cGVbXSkge1xuICAgIGVudGl0aWVzLmZvckVhY2goKGUpID0+IHtcbiAgICAgIGNvbnN0IGlkID0gdGhpcy5nZXRJZChlKTtcblxuICAgICAgaWYgKCF0aGlzLmVudGl0aWVzLmhhcyhpZCkpIHtcbiAgICAgICAgdGhpcy5pZHMucHVzaChpZCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZW50aXRpZXMuc2V0KGlkLCBlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBwcmVwZW5kKC4uLmVudGl0aWVzOiBFbnRpdHlUeXBlW10pIHtcbiAgICBlbnRpdGllcy5yZXZlcnNlKCkuZm9yRWFjaCgoZSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLmdldElkKGUpO1xuXG4gICAgICBpZiAodGhpcy5lbnRpdGllcy5oYXMoaWQpKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlKGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlkcy51bnNoaWZ0KGlkKTtcblxuICAgICAgdGhpcy5lbnRpdGllcy5zZXQoaWQsIGUpO1xuXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlKC4uLmVudGl0aWVzOiBFbnRpdHlUeXBlW10pIHtcbiAgICBlbnRpdGllcy5mb3JFYWNoKChlKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMuZ2V0SWQoZSk7XG4gICAgICBjb25zdCBpbmRleE9mSWQgPSB0aGlzLmlkcy5maW5kSW5kZXgoKF9pZCkgPT4gX2lkID09PSBpZCk7XG5cbiAgICAgIGlmIChpbmRleE9mSWQgPj0gMCkge1xuICAgICAgICB0aGlzLmlkcy5zcGxpY2UoaW5kZXhPZklkLCAxKTtcbiAgICAgICAgdGhpcy5lbnRpdGllcy5kZWxldGUoaWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFwcGVuZCguLi5lbnRpdGllczogRW50aXR5VHlwZVtdKSB7XG4gICAgZW50aXRpZXMuZm9yRWFjaCgoZSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLmdldElkKGUpO1xuXG4gICAgICBpZiAodGhpcy5lbnRpdGllcy5oYXMoaWQpKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlKGUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlkcy5wdXNoKGlkKTtcbiAgICAgIHRoaXMuZW50aXRpZXMuc2V0KGlkLCBlKTtcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,26 @@
1
+ import 'reflect-metadata';
2
+ import { scanInstance } from '../utilities/scan-instance';
3
+ export const ReduceSymbol = Symbol('@Reduce');
4
+ export function Reduce() {
5
+ return (target, propertyKey) => {
6
+ // by convention a reducer have name such as onFindAll
7
+ // where findAll is the associated action
8
+ // with the following we extract the action's name
9
+ const action = propertyKey.slice(2, 3).toLowerCase() + propertyKey.slice(3);
10
+ return Reflect.defineMetadata(ReduceSymbol, action, target, propertyKey);
11
+ };
12
+ }
13
+ export function getReduceMetadata(klass, key) {
14
+ return Reflect.getMetadata(ReduceSymbol, klass, key);
15
+ }
16
+ export function getReducers(instance) {
17
+ const reducers = [];
18
+ scanInstance(instance, (proto, key) => {
19
+ const metadata = getReduceMetadata(proto, key);
20
+ if (metadata) {
21
+ reducers.push({ action: metadata });
22
+ }
23
+ });
24
+ return reducers;
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3RvcmUvc3JjL2xpYi9yZWR1Y2UvcmVkdWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzFELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7QUFNOUMsTUFBTSxVQUFVLE1BQU07SUFDcEIsT0FBTyxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsRUFBRTtRQUM3QixzREFBc0Q7UUFDdEQseUNBQXlDO1FBQ3pDLGtEQUFrRDtRQUNsRCxNQUFNLE1BQU0sR0FBSSxXQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUksV0FBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEcsT0FBTyxPQUFPLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQzNFLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBaUIsRUFBRSxHQUFXO0lBQzlELE9BQU8sT0FBTyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLFFBQWdCO0lBRTFDLE1BQU0sUUFBUSxHQUF3QixFQUFFLENBQUM7SUFFekMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUVwQyxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsSUFBSSxRQUFRLEVBQUU7WUFDWixRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7U0FDbkM7SUFFSCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnO1xuaW1wb3J0IHsgc2Nhbkluc3RhbmNlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL3NjYW4taW5zdGFuY2UnO1xuaW1wb3J0IHsgQ2xhc3MgfSBmcm9tICd1dGlsaXR5LXR5cGVzJztcblxuZXhwb3J0IGNvbnN0IFJlZHVjZVN5bWJvbCA9IFN5bWJvbCgnQFJlZHVjZScpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlZHVjZXIge1xuICBhY3Rpb246IHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFJlZHVjZSgpOiBNZXRob2REZWNvcmF0b3Ige1xuICByZXR1cm4gKHRhcmdldCwgcHJvcGVydHlLZXkpID0+IHtcbiAgICAvLyBieSBjb252ZW50aW9uIGEgcmVkdWNlciBoYXZlIG5hbWUgc3VjaCBhcyBvbkZpbmRBbGxcbiAgICAvLyB3aGVyZSBmaW5kQWxsIGlzIHRoZSBhc3NvY2lhdGVkIGFjdGlvblxuICAgIC8vIHdpdGggdGhlIGZvbGxvd2luZyB3ZSBleHRyYWN0IHRoZSBhY3Rpb24ncyBuYW1lXG4gICAgY29uc3QgYWN0aW9uID0gKHByb3BlcnR5S2V5IGFzIHN0cmluZykuc2xpY2UoMiwgMykudG9Mb3dlckNhc2UoKSArIChwcm9wZXJ0eUtleSBhcyBzdHJpbmcpLnNsaWNlKDMpO1xuXG4gICAgcmV0dXJuIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoUmVkdWNlU3ltYm9sLCBhY3Rpb24sIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVkdWNlTWV0YWRhdGEoa2xhc3M6IENsYXNzPGFueT4sIGtleTogc3RyaW5nKSB7XG4gIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhKFJlZHVjZVN5bWJvbCwga2xhc3MsIGtleSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZWR1Y2VycyhpbnN0YW5jZTogb2JqZWN0KToge2FjdGlvbjogc3RyaW5nO31bXSB7XG5cbiAgY29uc3QgcmVkdWNlcnM6IHthY3Rpb246IHN0cmluZzt9W10gPSBbXTtcblxuICBzY2FuSW5zdGFuY2UoaW5zdGFuY2UsIChwcm90bywga2V5KSA9PiB7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IGdldFJlZHVjZU1ldGFkYXRhKHByb3RvLCBrZXkpO1xuICAgIGlmIChtZXRhZGF0YSkge1xuICAgICAgcmVkdWNlcnMucHVzaCh7YWN0aW9uOiBtZXRhZGF0YX0pO1xuICAgIH1cblxuICB9KTtcblxuICByZXR1cm4gcmVkdWNlcnM7XG59XG4iXX0=
@@ -0,0 +1,101 @@
1
+ import { BehaviorSubject, EMPTY, of, Subject } from 'rxjs';
2
+ import { getReducers } from '../reduce/reduce';
3
+ import { catchError, concatMap, filter, map, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators';
4
+ import { getEffects } from '../effect/effect';
5
+ export class Store {
6
+ constructor(initialState) {
7
+ this.initialState = initialState;
8
+ this.actions = new Map();
9
+ this._loading$ = new Subject();
10
+ this._store$ = new BehaviorSubject(
11
+ // we need this in order to decouple initial state between instances
12
+ JSON.parse(JSON.stringify(this.initialState)));
13
+ this.effects = getEffects(this);
14
+ this.reducers = getReducers(this);
15
+ const actions = [].concat(this.effects, this.reducers);
16
+ const actionsSet = new Set();
17
+ actions.forEach(({ action }) => actionsSet.add(action));
18
+ actionsSet.forEach((key) => {
19
+ this.actions.set(key, new Subject());
20
+ // @ts-ignore
21
+ const operator = Store.getOperator(this.effects[key]?.strategy);
22
+ // @ts-ignore
23
+ this.actions.get(key).pipe(withLatestFrom(this._store$), tap(([{ payload }]) => {
24
+ this._loading$.next({
25
+ payload: payload,
26
+ status: true,
27
+ code: key,
28
+ });
29
+ }), operator(([{ name, payload }]) => {
30
+ // @ts-ignore
31
+ return this[name](...payload).pipe(tap((response) => {
32
+ this._loading$.next({
33
+ payload,
34
+ response,
35
+ status: false,
36
+ // here the action is done. The action is the only async call
37
+ // we can assume the loading is done as the effect is not async
38
+ code: key,
39
+ });
40
+ }),
41
+ // the above is
42
+ map((response) => {
43
+ // by convention reducer name must be
44
+ // on + Action
45
+ const reducerName = `on${(name[0]).toUpperCase()}${name.slice(1)}`;
46
+ // @ts-ignore
47
+ return this[reducerName](this._store$.getValue(), response);
48
+ }),
49
+ // error need to be swallowed here too otherwise the observable chain will be broken
50
+ // meaning that once an action goes into an error it cannot be dispatched again
51
+ catchError((error) => this.swallowError(key, error, payload)));
52
+ })).subscribe(this._store$);
53
+ });
54
+ }
55
+ get loading$() {
56
+ return this._loading$.asObservable();
57
+ }
58
+ get state$() {
59
+ return this._store$.asObservable();
60
+ }
61
+ select(projection) {
62
+ return this.state$.pipe(map(projection));
63
+ }
64
+ getLoadingFor(action) {
65
+ return this.loading$.pipe(filter(({ code }) => code === action), map(({ status }) => status));
66
+ }
67
+ dispatch(action, ...payload) {
68
+ if (!this.actions.has(action)) {
69
+ throw new Error(`Cannot find action ${String(action)}`);
70
+ }
71
+ const name = (typeof this[action] === 'function' ? action : 'noopEffect');
72
+ this.actions.get(action)?.next({ name, payload });
73
+ }
74
+ // eslint-disable-next-line @typescript-eslint/member-ordering
75
+ static noopEffect(payload) {
76
+ return of(payload);
77
+ }
78
+ // eslint-disable-next-line @typescript-eslint/member-ordering
79
+ static getOperator(strategyFn) {
80
+ if (strategyFn === 'mergeMap') {
81
+ return mergeMap;
82
+ }
83
+ else if (strategyFn === 'concatMap') {
84
+ return concatMap;
85
+ }
86
+ else {
87
+ return switchMap;
88
+ }
89
+ }
90
+ swallowError(key, error, payload) {
91
+ console.log(`Error handling action "${key}"`, error);
92
+ this._loading$.next({
93
+ payload,
94
+ error: error,
95
+ status: false,
96
+ code: key,
97
+ });
98
+ return EMPTY;
99
+ }
100
+ }
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdG9yZS9zcmMvbGliL3N0b3JlL3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkUsT0FBTyxFQUFFLFdBQVcsRUFBVyxNQUFNLGtCQUFrQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUcsT0FBTyxFQUEwQixVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQTBDdEUsTUFBTSxPQUFnQixLQUFLO0lBd0J6QixZQUFvQixZQUFtQjtRQUFuQixpQkFBWSxHQUFaLFlBQVksQ0FBTztRQXRCdEIsWUFBTyxHQUEwRCxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBT3BGLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBbUIsQ0FBQztRQU1oQyxZQUFPLEdBQTJCLElBQUksZUFBZTtRQUN0RSxvRUFBb0U7UUFDcEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUM5QyxDQUFDO1FBUUEsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV2RCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBRXJDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFdEQsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBRXpCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFFckMsYUFBYTtZQUNiLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUVoRSxhQUFhO1lBQ2IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUN4QixjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUM1QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUMsT0FBTyxFQUFDLENBQUMsRUFBRSxFQUFFO2dCQUNsQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztvQkFDbEIsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLE1BQU0sRUFBRSxJQUFJO29CQUNaLElBQUksRUFBRSxHQUFjO2lCQUNyQixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsRUFDRixRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLEVBQUUsRUFBRTtnQkFDN0IsYUFBYTtnQkFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FDaEMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQ2YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7d0JBQ2xCLE9BQU87d0JBQ1AsUUFBUTt3QkFDUixNQUFNLEVBQUUsS0FBSzt3QkFDYiw2REFBNkQ7d0JBQzdELCtEQUErRDt3QkFDL0QsSUFBSSxFQUFFLEdBQWM7cUJBQ3JCLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUM7Z0JBQ0YsZUFBZTtnQkFDZixHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtvQkFDZixxQ0FBcUM7b0JBQ3JDLGNBQWM7b0JBQ2QsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFJLElBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFFL0UsYUFBYTtvQkFDYixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM5RCxDQUFDLENBQUM7Z0JBQ0Ysb0ZBQW9GO2dCQUNwRiwrRUFBK0U7Z0JBQy9FLFVBQVUsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQzlELENBQUM7WUFDSixDQUFDLENBQUMsQ0FFSCxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBdkVELElBQVcsUUFBUTtRQUNqQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQU9ELElBQVcsTUFBTTtRQUNmLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBOERELE1BQU0sQ0FBSSxVQUEyQjtRQUNuQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUNyQixHQUFHLENBQUMsVUFBVSxDQUFDLENBQ2hCLENBQUM7SUFDSixDQUFDO0lBRUQsYUFBYSxDQUFvQixNQUFTO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQ3ZCLE1BQU0sQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsRUFDbkMsR0FBRyxDQUFDLENBQUMsRUFBQyxNQUFNLEVBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQzFCLENBQUM7SUFDSixDQUFDO0lBRUQsUUFBUSxDQUNOLE1BQVMsRUFDVCxHQUFHLE9BQXVDO1FBRzFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFnQixDQUFDLEVBQUU7WUFDdkMsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUN6RDtRQUVELE1BQU0sSUFBSSxHQUFXLENBQUMsT0FBUSxJQUFxQixDQUFDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQVcsQ0FBQztRQUc5RyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFnQixDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELDhEQUE4RDtJQUN0RCxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQVk7UUFDcEMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckIsQ0FBQztJQUVELDhEQUE4RDtJQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLFVBQTBCO1FBQ25ELElBQUksVUFBVSxLQUFLLFVBQVUsRUFBRTtZQUM3QixPQUFPLFFBQVEsQ0FBQztTQUNqQjthQUFNLElBQUksVUFBVSxLQUFLLFdBQVcsRUFBRTtZQUNyQyxPQUFPLFNBQVMsQ0FBQztTQUNsQjthQUFNO1lBQ0wsT0FBTyxTQUFTLENBQUM7U0FDbEI7SUFDSCxDQUFDO0lBRU8sWUFBWSxDQUFDLEdBQVcsRUFBRSxLQUFZLEVBQUUsT0FBWTtRQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixHQUFHLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztZQUNsQixPQUFPO1lBQ1AsS0FBSyxFQUFFLEtBQUs7WUFDWixNQUFNLEVBQUUsS0FBSztZQUNiLElBQUksRUFBRSxHQUFjO1NBQ3JCLENBQUMsQ0FBQztRQUVILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUVGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBFTVBUWSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGdldFJlZHVjZXJzLCBSZWR1Y2VyIH0gZnJvbSAnLi4vcmVkdWNlL3JlZHVjZSc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBjb25jYXRNYXAsIGZpbHRlciwgbWFwLCBtZXJnZU1hcCwgc3dpdGNoTWFwLCB0YXAsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRWZmZWN0LCBFZmZlY3RTdHJhdGVneSwgZ2V0RWZmZWN0cyB9IGZyb20gJy4uL2VmZmVjdC9lZmZlY3QnO1xuaW1wb3J0IHsgQnJhbmQsIFByaW1pdGl2ZSB9IGZyb20gJ3V0aWxpdHktdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBnZXRQYXlsb2FkRnJvbUFjdGlvblR5cGU8QSwgQyBleHRlbmRzIGtleW9mIEE+ID1cbiAgQVtDXSBleHRlbmRzIEZ1bmN0aW9uID8gQVtDXSBleHRlbmRzICgpID0+IGFueVxuICAgID8gbmV2ZXJbXSA6IEFbQ10gZXh0ZW5kcyAoLi4uYXJnczogaW5mZXIgVCkgPT4gYW55XG4gICAgICA/IFQgOiBuZXZlcltdIDogQVtDXVtdO1xuXG5leHBvcnQgdHlwZSBQdXJlUmVkdWNlcjxUIGV4dGVuZHMgUHJpbWl0aXZlPiA9IEJyYW5kPFQsICdyZWR1Y2VyJz47XG5cbmV4cG9ydCB0eXBlIG1ha2VFZmZlY3RzPEFjdGlvbnM+ID0ge1xuICAvLyBFZmZlY3RzXG4gIFtrIGluIGtleW9mIEFjdGlvbnNdOiBBY3Rpb25zW2tdIGV4dGVuZHMgUHVyZVJlZHVjZXI8UHJpbWl0aXZlPlxuICAgID8gbmV2ZXJcbiAgICA6IEFjdGlvbnNba11cbn1cblxuZXhwb3J0IHR5cGUgbWFrZVN0b3JlPFN0YXRlLCBBY3Rpb25zPiA9XG4gIHtcbiAgICBbayBpbiBrZXlvZiBtYWtlRWZmZWN0czxBY3Rpb25zPl06IG1ha2VFZmZlY3RzPEFjdGlvbnM+W2tdXG4gIH1cbiAgLy8gJlxuICAvLyBBY3Rpb25zXG4gICZcbiAge1xuICAgIC8vIFJlZHVjZXJzXG4gICAgW2sgaW4ga2V5b2YgQWN0aW9ucyBhcyBgb24ke0NhcGl0YWxpemU8c3RyaW5nICYgaz59YF06IEFjdGlvbnNba10gZXh0ZW5kcyAoLi4uYXJnczogYW55KSA9PiBPYnNlcnZhYmxlPGluZmVyIE8+XG4gICAgPyAoc3RhdGU6IFN0YXRlLCBwYXlsb2FkOiBPKSA9PiBTdGF0ZVxuICAgIDogQWN0aW9uc1trXSBleHRlbmRzIFB1cmVSZWR1Y2VyPGluZmVyIE8+XG4gICAgICA/IChzdGF0ZT86IFN0YXRlLCBwYXlsb2FkPzogTykgPT4gU3RhdGVcbiAgICAgIDogKHN0YXRlPzogU3RhdGUpID0+IFN0YXRlXG5cbiAgfTtcblxuZXhwb3J0IGludGVyZmFjZSBMb2FkaW5nU3RhdGU8QT4ge1xuICBjb2RlOiBrZXlvZiBBO1xuICBwYXlsb2FkPzogYW55O1xuICByZXNwb25zZT86IGFueTtcbiAgZXJyb3I/OiBhbnk7XG4gIHN0YXR1czogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0b3JlPFN0YXRlLCBBPiB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhY3Rpb25zOiBNYXA8c3RyaW5nLCBTdWJqZWN0PHsgbmFtZTogc3RyaW5nLCBwYXlsb2FkPzogYW55IH0+PiA9IG5ldyBNYXAoKTtcblxuICByZWFkb25seSBlZmZlY3RzOiBFZmZlY3RbXTtcblxuICByZWFkb25seSByZWR1Y2VyczogUmVkdWNlcltdO1xuXG5cbiAgcHJpdmF0ZSBfbG9hZGluZyQgPSBuZXcgU3ViamVjdDxMb2FkaW5nU3RhdGU8QT4+KCk7XG5cbiAgcHVibGljIGdldCBsb2FkaW5nJCgpOiBPYnNlcnZhYmxlPExvYWRpbmdTdGF0ZTxBPj4ge1xuICAgIHJldHVybiB0aGlzLl9sb2FkaW5nJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RvcmUkOiBCZWhhdmlvclN1YmplY3Q8U3RhdGU+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTdGF0ZT4oXG4gICAgLy8gd2UgbmVlZCB0aGlzIGluIG9yZGVyIHRvIGRlY291cGxlIGluaXRpYWwgc3RhdGUgYmV0d2VlbiBpbnN0YW5jZXNcbiAgICBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuaW5pdGlhbFN0YXRlKSlcbiAgKTtcblxuICBwdWJsaWMgZ2V0IHN0YXRlJCgpOiBPYnNlcnZhYmxlPFN0YXRlPiB7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JlJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaW5pdGlhbFN0YXRlOiBTdGF0ZSkge1xuXG4gICAgdGhpcy5lZmZlY3RzID0gZ2V0RWZmZWN0cyh0aGlzKTtcbiAgICB0aGlzLnJlZHVjZXJzID0gZ2V0UmVkdWNlcnModGhpcyk7XG5cbiAgICBjb25zdCBhY3Rpb25zID0gW10uY29uY2F0KHRoaXMuZWZmZWN0cywgdGhpcy5yZWR1Y2Vycyk7XG5cbiAgICBjb25zdCBhY3Rpb25zU2V0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBhY3Rpb25zLmZvckVhY2goKHthY3Rpb259KSA9PiBhY3Rpb25zU2V0LmFkZChhY3Rpb24pKTtcblxuICAgIGFjdGlvbnNTZXQuZm9yRWFjaCgoa2V5KSA9PiB7XG5cbiAgICAgIHRoaXMuYWN0aW9ucy5zZXQoa2V5LCBuZXcgU3ViamVjdCgpKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgY29uc3Qgb3BlcmF0b3IgPSBTdG9yZS5nZXRPcGVyYXRvcih0aGlzLmVmZmVjdHNba2V5XT8uc3RyYXRlZ3kpO1xuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICB0aGlzLmFjdGlvbnMuZ2V0KGtleSkucGlwZShcbiAgICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5fc3RvcmUkKSxcbiAgICAgICAgdGFwKChbe3BheWxvYWR9XSkgPT4ge1xuICAgICAgICAgIHRoaXMuX2xvYWRpbmckLm5leHQoe1xuICAgICAgICAgICAgcGF5bG9hZDogcGF5bG9hZCxcbiAgICAgICAgICAgIHN0YXR1czogdHJ1ZSxcbiAgICAgICAgICAgIGNvZGU6IGtleSBhcyBrZXlvZiBBLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgb3BlcmF0b3IoKFt7bmFtZSwgcGF5bG9hZH1dKSA9PiB7XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIHJldHVybiB0aGlzW25hbWVdKC4uLnBheWxvYWQpLnBpcGUoXG4gICAgICAgICAgICB0YXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuX2xvYWRpbmckLm5leHQoe1xuICAgICAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAvLyBoZXJlIHRoZSBhY3Rpb24gaXMgZG9uZS4gVGhlIGFjdGlvbiBpcyB0aGUgb25seSBhc3luYyBjYWxsXG4gICAgICAgICAgICAgICAgLy8gd2UgY2FuIGFzc3VtZSB0aGUgbG9hZGluZyBpcyBkb25lIGFzIHRoZSBlZmZlY3QgaXMgbm90IGFzeW5jXG4gICAgICAgICAgICAgICAgY29kZToga2V5IGFzIGtleW9mIEEsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAvLyB0aGUgYWJvdmUgaXNcbiAgICAgICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgLy8gYnkgY29udmVudGlvbiByZWR1Y2VyIG5hbWUgbXVzdCBiZVxuICAgICAgICAgICAgICAvLyBvbiArIEFjdGlvblxuICAgICAgICAgICAgICBjb25zdCByZWR1Y2VyTmFtZSA9IGBvbiR7KG5hbWVbMF0pLnRvVXBwZXJDYXNlKCl9JHsobmFtZSBhcyBzdHJpbmcpLnNsaWNlKDEpfWA7XG5cbiAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICByZXR1cm4gdGhpc1tyZWR1Y2VyTmFtZV0odGhpcy5fc3RvcmUkLmdldFZhbHVlKCksIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgLy8gZXJyb3IgbmVlZCB0byBiZSBzd2FsbG93ZWQgaGVyZSB0b28gb3RoZXJ3aXNlIHRoZSBvYnNlcnZhYmxlIGNoYWluIHdpbGwgYmUgYnJva2VuXG4gICAgICAgICAgICAvLyBtZWFuaW5nIHRoYXQgb25jZSBhbiBhY3Rpb24gZ29lcyBpbnRvIGFuIGVycm9yIGl0IGNhbm5vdCBiZSBkaXNwYXRjaGVkIGFnYWluXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5zd2FsbG93RXJyb3Ioa2V5LCBlcnJvciwgcGF5bG9hZCkpLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICApLnN1YnNjcmliZSh0aGlzLl9zdG9yZSQpO1xuICAgIH0pO1xuICB9XG5cbiAgc2VsZWN0PFI+KHByb2plY3Rpb246IChzOiBTdGF0ZSkgPT4gUikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlJC5waXBlKFxuICAgICAgbWFwKHByb2plY3Rpb24pXG4gICAgKTtcbiAgfVxuXG4gIGdldExvYWRpbmdGb3I8QyBleHRlbmRzIGtleW9mIEE+KGFjdGlvbjogQyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLmxvYWRpbmckLnBpcGUoXG4gICAgICBmaWx0ZXIoKHtjb2RlfSkgPT4gY29kZSA9PT0gYWN0aW9uKSxcbiAgICAgIG1hcCgoe3N0YXR1c30pID0+IHN0YXR1cyksXG4gICAgKTtcbiAgfVxuXG4gIGRpc3BhdGNoPEMgZXh0ZW5kcyBrZXlvZiBBPihcbiAgICBhY3Rpb246IEMsXG4gICAgLi4ucGF5bG9hZDogZ2V0UGF5bG9hZEZyb21BY3Rpb25UeXBlPEEsIEM+XG4gICkge1xuXG4gICAgaWYgKCF0aGlzLmFjdGlvbnMuaGFzKGFjdGlvbiBhcyBzdHJpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIGFjdGlvbiAke1N0cmluZyhhY3Rpb24pfWApO1xuICAgIH1cblxuICAgIGNvbnN0IG5hbWU6IHN0cmluZyA9ICh0eXBlb2YgKHRoaXMgYXMgdW5rbm93biBhcyBBKVthY3Rpb25dID09PSAnZnVuY3Rpb24nID8gYWN0aW9uIDogJ25vb3BFZmZlY3QnKSBhcyBzdHJpbmc7XG5cblxuICAgIHRoaXMuYWN0aW9ucy5nZXQoYWN0aW9uIGFzIHN0cmluZyk/Lm5leHQoe25hbWUsIHBheWxvYWR9KTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbWVtYmVyLW9yZGVyaW5nXG4gIHByaXZhdGUgc3RhdGljIG5vb3BFZmZlY3QocGF5bG9hZDogYW55KSB7XG4gICAgcmV0dXJuIG9mKHBheWxvYWQpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9tZW1iZXItb3JkZXJpbmdcbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0T3BlcmF0b3Ioc3RyYXRlZ3lGbjogRWZmZWN0U3RyYXRlZ3kpIHtcbiAgICBpZiAoc3RyYXRlZ3lGbiA9PT0gJ21lcmdlTWFwJykge1xuICAgICAgcmV0dXJuIG1lcmdlTWFwO1xuICAgIH0gZWxzZSBpZiAoc3RyYXRlZ3lGbiA9PT0gJ2NvbmNhdE1hcCcpIHtcbiAgICAgIHJldHVybiBjb25jYXRNYXA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzd2l0Y2hNYXA7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzd2FsbG93RXJyb3Ioa2V5OiBzdHJpbmcsIGVycm9yOiBFcnJvciwgcGF5bG9hZDogYW55KSB7XG4gICAgY29uc29sZS5sb2coYEVycm9yIGhhbmRsaW5nIGFjdGlvbiBcIiR7a2V5fVwiYCwgZXJyb3IpO1xuXG4gICAgdGhpcy5fbG9hZGluZyQubmV4dCh7XG4gICAgICBwYXlsb2FkLFxuICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgc3RhdHVzOiBmYWxzZSxcbiAgICAgIGNvZGU6IGtleSBhcyBrZXlvZiBBLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIEVNUFRZO1xuICB9XG5cbn1cbiJdfQ==
@@ -0,0 +1,19 @@
1
+ const builtInMethods = Object.keys(Object.getOwnPropertyDescriptors(Object.getPrototypeOf({})));
2
+ export function scanInstance(instance, cb) {
3
+ let proto = Object.getPrototypeOf(instance);
4
+ while (proto) {
5
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
6
+ Object.keys(descriptors)
7
+ .filter((k) => {
8
+ return !builtInMethods.includes(k);
9
+ })
10
+ .forEach((key) => cb(proto, key));
11
+ try {
12
+ proto = Object.getPrototypeOf(proto);
13
+ }
14
+ catch (e) {
15
+ proto = null;
16
+ }
17
+ }
18
+ }
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nhbi1pbnN0YW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlL3NyYy9saWIvdXRpbGl0aWVzL3NjYW4taW5zdGFuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFaEcsTUFBTSxVQUFVLFlBQVksQ0FBbUIsUUFBVyxFQUFFLEVBQTBDO0lBRXBHLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFNUMsT0FBTyxLQUFLLEVBQUU7UUFFWixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFNUQsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7YUFDckIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDWixPQUFPLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUM7YUFDRCxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUVwQyxJQUFJO1lBQ0YsS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDdEM7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLEtBQUssR0FBRyxJQUFJLENBQUM7U0FDZDtLQUNGO0FBRUgsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsYXNzIH0gZnJvbSAndXRpbGl0eS10eXBlcyc7XG5cbmNvbnN0IGJ1aWx0SW5NZXRob2RzID0gT2JqZWN0LmtleXMoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoT2JqZWN0LmdldFByb3RvdHlwZU9mKHt9KSkpO1xuXG5leHBvcnQgZnVuY3Rpb24gc2Nhbkluc3RhbmNlPFQgZXh0ZW5kcyBvYmplY3Q+KGluc3RhbmNlOiBULCBjYjogKHByb3RvOiBDbGFzczxUPiwga2V5OiBzdHJpbmcpID0+IHZvaWQpIHtcblxuICBsZXQgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpO1xuXG4gIHdoaWxlIChwcm90bykge1xuXG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhwcm90byk7XG5cbiAgICBPYmplY3Qua2V5cyhkZXNjcmlwdG9ycylcbiAgICAgIC5maWx0ZXIoKGspID0+IHtcbiAgICAgICAgcmV0dXJuICFidWlsdEluTWV0aG9kcy5pbmNsdWRlcyhrKTtcbiAgICAgIH0pXG4gICAgICAuZm9yRWFjaCgoa2V5KSA9PiBjYihwcm90bywga2V5KSk7XG5cbiAgICB0cnkge1xuICAgICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHByb3RvID0gbnVsbDtcbiAgICB9XG4gIH1cblxufVxuIl19
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm9waGktc3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9zdG9yZS9zcmMvbWljcm9waGktc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Public API Surface of store
3
+ */
4
+ export * from './lib/store/store';
5
+ export * from './lib/effect/effect';
6
+ export * from './lib/reduce/reduce';
7
+ export * from './lib/list/list';
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3N0b3JlL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2Ygc3RvcmVcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9zdG9yZS9zdG9yZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9lZmZlY3QvZWZmZWN0JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3JlZHVjZS9yZWR1Y2UnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvbGlzdC9saXN0JztcbiJdfQ==
@@ -0,0 +1,305 @@
1
+ import { Subject, BehaviorSubject, of, EMPTY } from 'rxjs';
2
+ import 'reflect-metadata';
3
+ import { withLatestFrom, tap, map, catchError, filter, mergeMap, concatMap, switchMap } from 'rxjs/operators';
4
+
5
+ const builtInMethods = Object.keys(Object.getOwnPropertyDescriptors(Object.getPrototypeOf({})));
6
+ function scanInstance(instance, cb) {
7
+ let proto = Object.getPrototypeOf(instance);
8
+ while (proto) {
9
+ const descriptors = Object.getOwnPropertyDescriptors(proto);
10
+ Object.keys(descriptors)
11
+ .filter((k) => {
12
+ return !builtInMethods.includes(k);
13
+ })
14
+ .forEach((key) => cb(proto, key));
15
+ try {
16
+ proto = Object.getPrototypeOf(proto);
17
+ }
18
+ catch (e) {
19
+ proto = null;
20
+ }
21
+ }
22
+ }
23
+
24
+ const ReduceSymbol = Symbol('@Reduce');
25
+ function Reduce() {
26
+ return (target, propertyKey) => {
27
+ // by convention a reducer have name such as onFindAll
28
+ // where findAll is the associated action
29
+ // with the following we extract the action's name
30
+ const action = propertyKey.slice(2, 3).toLowerCase() + propertyKey.slice(3);
31
+ return Reflect.defineMetadata(ReduceSymbol, action, target, propertyKey);
32
+ };
33
+ }
34
+ function getReduceMetadata(klass, key) {
35
+ return Reflect.getMetadata(ReduceSymbol, klass, key);
36
+ }
37
+ function getReducers(instance) {
38
+ const reducers = [];
39
+ scanInstance(instance, (proto, key) => {
40
+ const metadata = getReduceMetadata(proto, key);
41
+ if (metadata) {
42
+ reducers.push({ action: metadata });
43
+ }
44
+ });
45
+ return reducers;
46
+ }
47
+
48
+ const EffectSymbol = Symbol.for('@Effect');
49
+ /**
50
+ * Tags a method as an effect <br>
51
+ *
52
+ * Strategy is one of the following rxjs pipe-able operators:
53
+ * - `mergeMap`
54
+ * - `concatMap`
55
+ * - `switchMap`
56
+ *
57
+ * As an example consider the following:
58
+ * suppose there's an effect that takes 10 ms to return and then a reducer is called.<br>
59
+ * Suppose we dispatch its event, the following diagram demonstrate what happens<br>
60
+ * <code>
61
+ * `D -> E -> (10) -> R`<br>
62
+ * </code>
63
+ * Event is dispatched `D`, event is executed `E`, takes 10ms and finally reducer is called with result from `E`
64
+ *
65
+ * Now let's suppose we dispatch again the same while `E` is still pending (executing) and suppose we call it with a different argument.
66
+ *
67
+ *
68
+ * `D(a) -> E -> D(b)`
69
+ *
70
+ *
71
+ * what happens next depends on the strategy used.<br>
72
+ *
73
+ *
74
+ * If `switchMap` is used (default)
75
+ *
76
+ * `D(a) -> E(a) -> D(b) -> E(b) -> R(b)`
77
+ *
78
+ * the second dispatch cancels the first and so only `R(b)` is executed
79
+ *
80
+ *
81
+ * If `mergeMap` is used
82
+ *
83
+ * `D(a) -> E(a) -> D(b) -> E(b) -> R(a) -> R(b)
84
+ *
85
+ * effects are executed in parallel and the first to come is the first served
86
+ *
87
+ * i.e.: lets say E(a) takes longer to respond then
88
+ *
89
+ * `D(a) -> D(b) -> E(b) -> R(b) -> E(a) -> -> R(a)`
90
+ *
91
+ *
92
+ * If `concatMap` is used then the order of calls is respected.
93
+ *
94
+ * in the case above we'll have whatever the timings are on the effects
95
+ *
96
+ * `D(a) -> D(b) -> E(a) -> R(a) -> E(b) -> -> R(b)`
97
+ *
98
+ * @param strategy
99
+ * @constructor
100
+ */
101
+ function Effect(strategy = 'switchMap') {
102
+ // return Reflect.metadata(EffectSymbol, strategy);
103
+ return (target, propertyKey) => {
104
+ // return Reflect.metadata(EffectSymbol, strategy)(target, propertyKey);
105
+ return Reflect.defineMetadata(EffectSymbol, strategy, target, propertyKey);
106
+ };
107
+ }
108
+ function getEffectMetadata(klass, key) {
109
+ return Reflect.getMetadata(EffectSymbol, klass, key);
110
+ }
111
+ function getEffects(instance) {
112
+ const effects = [];
113
+ scanInstance(instance, (proto, key) => {
114
+ const strategy = getEffectMetadata(proto, key);
115
+ if (strategy) {
116
+ effects.push({ action: key, strategy, });
117
+ }
118
+ });
119
+ return effects;
120
+ }
121
+
122
+ class Store {
123
+ constructor(initialState) {
124
+ this.initialState = initialState;
125
+ this.actions = new Map();
126
+ this._loading$ = new Subject();
127
+ this._store$ = new BehaviorSubject(
128
+ // we need this in order to decouple initial state between instances
129
+ JSON.parse(JSON.stringify(this.initialState)));
130
+ this.effects = getEffects(this);
131
+ this.reducers = getReducers(this);
132
+ const actions = [].concat(this.effects, this.reducers);
133
+ const actionsSet = new Set();
134
+ actions.forEach(({ action }) => actionsSet.add(action));
135
+ actionsSet.forEach((key) => {
136
+ var _a;
137
+ this.actions.set(key, new Subject());
138
+ // @ts-ignore
139
+ const operator = Store.getOperator((_a = this.effects[key]) === null || _a === void 0 ? void 0 : _a.strategy);
140
+ // @ts-ignore
141
+ this.actions.get(key).pipe(withLatestFrom(this._store$), tap(([{ payload }]) => {
142
+ this._loading$.next({
143
+ payload: payload,
144
+ status: true,
145
+ code: key,
146
+ });
147
+ }), operator(([{ name, payload }]) => {
148
+ // @ts-ignore
149
+ return this[name](...payload).pipe(tap((response) => {
150
+ this._loading$.next({
151
+ payload,
152
+ response,
153
+ status: false,
154
+ // here the action is done. The action is the only async call
155
+ // we can assume the loading is done as the effect is not async
156
+ code: key,
157
+ });
158
+ }),
159
+ // the above is
160
+ map((response) => {
161
+ // by convention reducer name must be
162
+ // on + Action
163
+ const reducerName = `on${(name[0]).toUpperCase()}${name.slice(1)}`;
164
+ // @ts-ignore
165
+ return this[reducerName](this._store$.getValue(), response);
166
+ }),
167
+ // error need to be swallowed here too otherwise the observable chain will be broken
168
+ // meaning that once an action goes into an error it cannot be dispatched again
169
+ catchError((error) => this.swallowError(key, error, payload)));
170
+ })).subscribe(this._store$);
171
+ });
172
+ }
173
+ get loading$() {
174
+ return this._loading$.asObservable();
175
+ }
176
+ get state$() {
177
+ return this._store$.asObservable();
178
+ }
179
+ select(projection) {
180
+ return this.state$.pipe(map(projection));
181
+ }
182
+ getLoadingFor(action) {
183
+ return this.loading$.pipe(filter(({ code }) => code === action), map(({ status }) => status));
184
+ }
185
+ dispatch(action, ...payload) {
186
+ var _a;
187
+ if (!this.actions.has(action)) {
188
+ throw new Error(`Cannot find action ${String(action)}`);
189
+ }
190
+ const name = (typeof this[action] === 'function' ? action : 'noopEffect');
191
+ (_a = this.actions.get(action)) === null || _a === void 0 ? void 0 : _a.next({ name, payload });
192
+ }
193
+ // eslint-disable-next-line @typescript-eslint/member-ordering
194
+ static noopEffect(payload) {
195
+ return of(payload);
196
+ }
197
+ // eslint-disable-next-line @typescript-eslint/member-ordering
198
+ static getOperator(strategyFn) {
199
+ if (strategyFn === 'mergeMap') {
200
+ return mergeMap;
201
+ }
202
+ else if (strategyFn === 'concatMap') {
203
+ return concatMap;
204
+ }
205
+ else {
206
+ return switchMap;
207
+ }
208
+ }
209
+ swallowError(key, error, payload) {
210
+ console.log(`Error handling action "${key}"`, error);
211
+ this._loading$.next({
212
+ payload,
213
+ error: error,
214
+ status: false,
215
+ code: key,
216
+ });
217
+ return EMPTY;
218
+ }
219
+ }
220
+
221
+ class List {
222
+ constructor(IDField, entities = []) {
223
+ this.IDField = IDField;
224
+ this.entities = new Map();
225
+ /**
226
+ * maps entities position from the original array to their ids
227
+ */
228
+ this.ids = [];
229
+ this.ids = entities.map((e) => this.getId(e));
230
+ entities
231
+ .forEach((item, idx) => {
232
+ const id = item[IDField];
233
+ this.entities.set(id, item);
234
+ });
235
+ }
236
+ get size() {
237
+ if (this.ids.length !== this.entities.size) {
238
+ throw new Error(`Size Mismatch ${this.ids.length} !== ${this.entities.size}`);
239
+ }
240
+ return this.entities.size;
241
+ }
242
+ get(id) {
243
+ return this.entities.get(id);
244
+ }
245
+ getId(entity) {
246
+ return entity[this.IDField];
247
+ }
248
+ *[Symbol.iterator]() {
249
+ // tslint:disable-next-line:forin
250
+ for (const idx in this.ids) {
251
+ const id = this.ids[idx];
252
+ yield this.entities.get(id);
253
+ }
254
+ }
255
+ upsert(...entities) {
256
+ entities.forEach((e) => {
257
+ const id = this.getId(e);
258
+ if (!this.entities.has(id)) {
259
+ this.ids.push(id);
260
+ }
261
+ this.entities.set(id, e);
262
+ });
263
+ }
264
+ prepend(...entities) {
265
+ entities.reverse().forEach((e) => {
266
+ const id = this.getId(e);
267
+ if (this.entities.has(id)) {
268
+ this.delete(e);
269
+ }
270
+ this.ids.unshift(id);
271
+ this.entities.set(id, e);
272
+ });
273
+ }
274
+ delete(...entities) {
275
+ entities.forEach((e) => {
276
+ const id = this.getId(e);
277
+ const indexOfId = this.ids.findIndex((_id) => _id === id);
278
+ if (indexOfId >= 0) {
279
+ this.ids.splice(indexOfId, 1);
280
+ this.entities.delete(id);
281
+ }
282
+ });
283
+ }
284
+ append(...entities) {
285
+ entities.forEach((e) => {
286
+ const id = this.getId(e);
287
+ if (this.entities.has(id)) {
288
+ this.delete(e);
289
+ }
290
+ this.ids.push(id);
291
+ this.entities.set(id, e);
292
+ });
293
+ }
294
+ }
295
+
296
+ /*
297
+ * Public API Surface of store
298
+ */
299
+
300
+ /**
301
+ * Generated bundle index. Do not edit.
302
+ */
303
+
304
+ export { Effect, EffectSymbol, List, Reduce, ReduceSymbol, Store, getEffectMetadata, getEffects, getReduceMetadata, getReducers };
305
+ //# sourceMappingURL=microphi-store.mjs.map