• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

satanTime / ngrx-entity-relationship / 475a6fe6-862e-42f9-b95e-23a40dfab79b

26 Jan 2024 01:24AM UTC coverage: 100.0%. Remained the same
475a6fe6-862e-42f9-b95e-23a40dfab79b

Pull #2048

circleci

web-flow
chore(deps): update dependency husky to v9
Pull Request #2048: chore(deps): update dependency husky to v9

443 of 443 branches covered (100.0%)

Branch coverage included in aggregate %.

680 of 680 relevant lines covered (100.0%)

33.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/libs/ngrx-entity-relationship/src/lib/childEntity.ts
1
import {
2
    CACHE,
3
    CACHE_CHECKS_SET,
4
    FEATURE_SELECTOR,
5
    HANDLER_RELATED_ENTITY,
6
    ID_FILTER_PROPS,
7
    ID_SELECTOR,
8
    ID_TYPES,
9
    isSelectorMeta,
10
    UNKNOWN,
11
    VALUES_FILTER_PROPS,
12
} from './types';
13
import {argsToArray, mergeCache, normalizeSelector, objectValues, verifyCache} from './utils';
14

15
export function childEntity<
16
    STORE,
17
    PARENT_ENTITY,
18
    RELATED_ENTITY,
19
    RELATED_KEY_IDS extends ID_FILTER_PROPS<RELATED_ENTITY, ID_TYPES> = ID_FILTER_PROPS<RELATED_ENTITY, ID_TYPES>,
20
    RELATED_KEY_VALUES extends VALUES_FILTER_PROPS<PARENT_ENTITY, RELATED_ENTITY> = VALUES_FILTER_PROPS<
21
        PARENT_ENTITY,
22
        RELATED_ENTITY
23
    >,
24
>(
25
    featureSelector: FEATURE_SELECTOR<STORE, RELATED_ENTITY>,
26
    keyId: RELATED_KEY_IDS,
27
    keyValue: RELATED_KEY_VALUES,
28
    metaOrRelationship?: SELECTOR_META | HANDLER_RELATED_ENTITY<STORE, RELATED_ENTITY>,
29
    ...relationships: Array<HANDLER_RELATED_ENTITY<STORE, RELATED_ENTITY>>
30
): HANDLER_RELATED_ENTITY<STORE, PARENT_ENTITY>;
31

32
export function childEntity<
33
    STORE,
34
    PARENT_ENTITY,
35
    RELATED_ENTITY,
36
    RELATED_KEY_IDS extends ID_FILTER_PROPS<RELATED_ENTITY, ID_TYPES>,
37
    RELATED_KEY_VALUES extends VALUES_FILTER_PROPS<PARENT_ENTITY, RELATED_ENTITY>,
38
>(
39
    featureSelector: FEATURE_SELECTOR<STORE, RELATED_ENTITY>,
40
    keyId: RELATED_KEY_IDS,
41
    keyValue: RELATED_KEY_VALUES,
42
): HANDLER_RELATED_ENTITY<STORE, PARENT_ENTITY> {
43
    let relationships: Array<HANDLER_RELATED_ENTITY<STORE, RELATED_ENTITY>> = argsToArray(arguments);
35✔
44
    relationships = relationships.slice(3);
35✔
45

46
    let meta: SELECTOR_META = {};
35✔
47
    if (isSelectorMeta(relationships[0])) {
35✔
48
        meta = relationships[0];
18✔
49
        relationships = relationships.slice(1);
18✔
50
    }
51

52
    const {collection: collectionSelector, id: idSelector} = normalizeSelector(featureSelector);
35✔
53

54
    const callback = (
35✔
55
        cacheLevel: string,
56
        state: STORE,
57
        cache: CACHE<STORE>,
58
        source: PARENT_ENTITY,
59
        idParentSelector: ID_SELECTOR<PARENT_ENTITY>,
60
    ) => {
61
        const featureState = collectionSelector(state);
18✔
62
        const parentId = idParentSelector(source);
18✔
63

64
        let cacheDataLevel = cache.get(cacheLevel);
18✔
65
        if (!cacheDataLevel) {
18✔
66
            cacheDataLevel = new Map();
14✔
67
            cache.set(cacheLevel, cacheDataLevel);
14✔
68
        }
69

70
        // maybe we don't need to scan the entities.
71
        let [idChecks, id]: [CACHE_CHECKS_SET<STORE>, ID_TYPES | undefined] = cacheDataLevel.get(`!${parentId}`) || [
18✔
72
            new Map(),
73
            undefined,
74
        ];
75
        if (!verifyCache(state, idChecks)) {
18✔
76
            id = undefined;
15✔
77
            for (const entity of objectValues(featureState.entities)) {
15✔
78
                if (
14✔
79
                    !entity ||
28✔
80
                    entity[keyId] !== (parentId as any as RELATED_ENTITY[RELATED_KEY_IDS]) // todo fix any A8
81
                ) {
82
                    continue;
1✔
83
                }
84
                id = idSelector(entity);
13✔
85
                break;
13✔
86
            }
87
            idChecks = new Map();
15✔
88
            const idChecksEntities = new Map();
15✔
89
            idChecks.set(collectionSelector, idChecksEntities);
15✔
90
            idChecksEntities.set(null, featureState.entities);
15✔
91
            cacheDataLevel.set(`!${parentId}`, [idChecks, id]);
15✔
92
        }
93
        if (!id) {
18✔
94
            return `!${parentId}`;
2✔
95
        }
96

97
        const cacheHash = `#${id}`;
16✔
98
        let [checks, value]: [CACHE_CHECKS_SET<STORE>, UNKNOWN] = cacheDataLevel.get(cacheHash) || [
16✔
99
            new Map(),
100
            undefined,
101
        ];
102
        if (verifyCache(state, checks)) {
16✔
103
            source[keyValue] = value;
3✔
104
            return cacheHash;
3✔
105
        }
106

107
        // building a new value.
108
        value = undefined;
13✔
109
        checks = new Map();
13✔
110
        const checksEntities = new Map();
13✔
111
        checks.set(collectionSelector, checksEntities);
13✔
112
        checksEntities.set(null, featureState.entities);
13✔
113
        checksEntities.set(id, featureState.entities[id]);
13✔
114

115
        // we have to clone it because we are going to update it with relationships.
116
        value = {...featureState.entities[id]} as RELATED_ENTITY;
13✔
117

118
        let cacheRelLevelIndex = 0;
13✔
119
        for (const relationship of relationships) {
13✔
120
            const cacheRelLevel = `${cacheLevel}:${cacheRelLevelIndex}`;
6✔
121
            const cacheRelHash = relationship(cacheRelLevel, state, cache, value, idSelector);
6✔
122
            cacheRelLevelIndex += 1;
6✔
123
            if (cacheRelHash) {
6✔
124
                mergeCache(cache.get(cacheRelLevel)?.get(cacheRelHash)?.[0], checks);
4✔
125
            }
126
        }
127
        cacheDataLevel.set(cacheHash, [checks, value]);
13✔
128
        source[keyValue] = value as PARENT_ENTITY[RELATED_KEY_VALUES];
13✔
129
        return cacheHash;
13✔
130
    };
131
    callback.ngrxEntityRelationship = 'childEntity';
35✔
132
    callback.collectionSelector = collectionSelector;
35✔
133
    callback.meta = meta;
35✔
134
    callback.idSelector = idSelector;
35✔
135
    callback.relationships = relationships;
35✔
136
    callback.keyId = keyId;
35✔
137
    callback.keyValue = keyValue;
35✔
138
    callback.release = () => {
35✔
139
        for (const relationship of relationships) {
1✔
140
            relationship.release();
2✔
141
        }
142
    };
143

144
    return callback;
35✔
145
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc