1 | 'use strict';
|
2 | function isLikeSelector(selector) {
|
3 | return selector !== null &&
|
4 | typeof selector === 'object' &&
|
5 | Reflect.getPrototypeOf(selector) === Object.prototype &&
|
6 | Reflect.ownKeys(selector).length > 0;
|
7 | }
|
8 |
|
9 | exports.isLikeSelector = isLikeSelector;
|
10 |
|
11 | const CIRCULAR_SELECTOR = new Error('Encountered a circular selector');
|
12 | exports.CIRCULAR_SELECTOR = CIRCULAR_SELECTOR;
|
13 |
|
14 | function selectComparable(lhs, selector, circular = new Set()) {
|
15 | if (circular.has(selector)) {
|
16 | throw CIRCULAR_SELECTOR;
|
17 | }
|
18 |
|
19 | circular.add(selector);
|
20 |
|
21 | if (lhs === null || typeof lhs !== 'object') {
|
22 | return lhs;
|
23 | }
|
24 |
|
25 | const comparable = {};
|
26 | for (const [key, rhs] of Object.entries(selector)) {
|
27 | if (isLikeSelector(rhs)) {
|
28 | comparable[key] = selectComparable(Reflect.get(lhs, key), rhs, circular);
|
29 | } else {
|
30 | comparable[key] = Reflect.get(lhs, key);
|
31 | }
|
32 | }
|
33 |
|
34 | return comparable;
|
35 | }
|
36 |
|
37 | exports.selectComparable = selectComparable;
|