@thi.ng/oquery 2.2.41 → 2.2.43
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/CHANGELOG.md +8 -1
- package/README.md +2 -2
- package/api.d.ts +17 -8
- package/match.d.ts +42 -29
- package/package.json +11 -11
- package/query.js +126 -126
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
3
|
+
- **Last updated**: 2024-06-29T09:28:36Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,13 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
### [2.2.42](https://github.com/thi-ng/umbrella/tree/@thi.ng/oquery@2.2.42) (2024-06-21)
|
|
13
|
+
|
|
14
|
+
#### ♻️ Refactoring
|
|
15
|
+
|
|
16
|
+
- enforce uniform naming convention of internal functions ([56992b2](https://github.com/thi-ng/umbrella/commit/56992b2))
|
|
17
|
+
- minor internal restructuring ([3aa9e8b](https://github.com/thi-ng/umbrella/commit/3aa9e8b))
|
|
18
|
+
|
|
12
19
|
### [2.2.26](https://github.com/thi-ng/umbrella/tree/@thi.ng/oquery@2.2.26) (2024-02-22)
|
|
13
20
|
|
|
14
21
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://mastodon.thi.ng/@toxi)
|
|
8
8
|
|
|
9
9
|
> [!NOTE]
|
|
10
|
-
> This is one of
|
|
10
|
+
> This is one of 189 standalone projects, maintained as part
|
|
11
11
|
> of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
|
|
12
12
|
> and anti-framework.
|
|
13
13
|
>
|
|
@@ -89,7 +89,7 @@ For Node.js REPL:
|
|
|
89
89
|
const oq = await import("@thi.ng/oquery");
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
92
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.69 KB
|
|
93
93
|
|
|
94
94
|
## Dependencies
|
|
95
95
|
|
package/api.d.ts
CHANGED
|
@@ -72,15 +72,19 @@ export interface QueryOpts {
|
|
|
72
72
|
* successfully matched property values will be included for each result.
|
|
73
73
|
*
|
|
74
74
|
* @example
|
|
75
|
-
* ```ts
|
|
75
|
+
* ```ts tangle:../export/def-query.ts
|
|
76
76
|
* import { defQuery } from "@thi.ng/oquery";
|
|
77
77
|
*
|
|
78
78
|
* const DB = { a: { id: 1, name: "alice" }, b: { name: "bob" } };
|
|
79
79
|
*
|
|
80
|
-
*
|
|
80
|
+
* console.log(
|
|
81
|
+
* defQuery({ partial: false })(DB, null, "id", 1)
|
|
82
|
+
* );
|
|
81
83
|
* // { a: { id: 1, name: "alice" } }
|
|
82
84
|
*
|
|
83
|
-
*
|
|
85
|
+
* console.log(
|
|
86
|
+
* defQuery({ partial: true })(DB, null, "id", 1)
|
|
87
|
+
* );
|
|
84
88
|
* // { a: { id: 1 } }
|
|
85
89
|
* ```
|
|
86
90
|
*
|
|
@@ -97,15 +101,20 @@ export interface QueryOpts {
|
|
|
97
101
|
* ALWAYS matched in a componentwise manner.
|
|
98
102
|
*
|
|
99
103
|
* @example
|
|
100
|
-
* ```ts
|
|
104
|
+
* ```ts tangle:../export/def-query-2.ts
|
|
101
105
|
* import { defQuery } from "@thi.ng/oquery";
|
|
102
106
|
*
|
|
103
107
|
* const DB = { a: { knows: ["b","c"] }, b: { knows: ["a","c"] }};
|
|
104
|
-
* defQuery({ cwise: true })(DB, null, "knows", "b")
|
|
105
|
-
* // { a: { knows: ["b","c"] } }
|
|
106
108
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
+
* console.log(
|
|
110
|
+
* defQuery({ cwise: true })(DB, null, "knows", "b")
|
|
111
|
+
* );
|
|
112
|
+
* // { a: { knows: ["b", "c"] } }
|
|
113
|
+
*
|
|
114
|
+
* console.log(
|
|
115
|
+
* defQuery({ cwise: false })(DB, null, "knows", (x) => x.includes("b"))
|
|
116
|
+
* );
|
|
117
|
+
* // { a: { knows: ["b", "c"] } }
|
|
109
118
|
* ```
|
|
110
119
|
*
|
|
111
120
|
* @defaultValue true
|
package/match.d.ts
CHANGED
|
@@ -23,30 +23,10 @@ export interface MatchMultipleOpts<T> {
|
|
|
23
23
|
* which contains any of these exclusions is automatically rejected, even if
|
|
24
24
|
* other strings could be matched.
|
|
25
25
|
*
|
|
26
|
-
* See {@link matchMultiple} for more details
|
|
27
|
-
*
|
|
28
|
-
* @param key
|
|
29
|
-
* @param matches
|
|
30
|
-
* @param opts
|
|
31
|
-
* @returns
|
|
32
|
-
*/
|
|
33
|
-
export declare const matchStrings: <T extends QueryObj = QueryObj>(key: QueryTerm["q"][0], matches: string[], opts?: Partial<MatchMultipleOpts<string>>) => QueryTerm<T>;
|
|
34
|
-
/**
|
|
35
|
-
* Returns a {@link QueryTerm} for use with {@link query} to perform set-like
|
|
36
|
-
* intersection or union queries with optional negation/exclusions. Matches set
|
|
37
|
-
* of given values against an item's chosen field of values and by default only
|
|
38
|
-
* succeeds if all provided `includes` can be matched (aka intersection query)
|
|
39
|
-
* and there're no values from `excludes` present.
|
|
40
|
-
*
|
|
41
|
-
* @remarks
|
|
42
|
-
* If the `union` option is true, only one of the provided values needs to
|
|
43
|
-
* match. Exclusions _always_ take precedence.
|
|
44
|
-
*
|
|
45
|
-
* Note: See {@link matchStrings} for a syntax sugar of this function, aimed at
|
|
46
|
-
* matching `string[]` options.
|
|
26
|
+
* See {@link matchMultiple} for more details.
|
|
47
27
|
*
|
|
48
28
|
* @example
|
|
49
|
-
* ```ts
|
|
29
|
+
* ```ts tangle:../export/match-strings.ts
|
|
50
30
|
* import { query, matchStrings } from "@thi.ng/oquery";
|
|
51
31
|
*
|
|
52
32
|
* const DB = [
|
|
@@ -56,22 +36,48 @@ export declare const matchStrings: <T extends QueryObj = QueryObj>(key: QueryTer
|
|
|
56
36
|
* ];
|
|
57
37
|
*
|
|
58
38
|
* // tag intersection
|
|
59
|
-
*
|
|
39
|
+
* console.log(
|
|
40
|
+
* query(DB, [matchStrings("tags", ["a", "b"])])
|
|
41
|
+
* );
|
|
60
42
|
* // [ { id: 1, tags: ["a", "b"] } ]
|
|
61
43
|
*
|
|
62
44
|
* // tag union
|
|
63
|
-
*
|
|
45
|
+
* console.log(
|
|
46
|
+
* query(DB, [matchStrings("tags", ["a", "b"])])
|
|
47
|
+
* );
|
|
64
48
|
* // here returns full DB...
|
|
65
49
|
* // since each item either has `a` and/or `b` tags
|
|
66
50
|
*
|
|
67
51
|
* // tag exclusion (require `a`, disallow `b`)
|
|
68
|
-
*
|
|
52
|
+
* console.log(
|
|
53
|
+
* query(DB, [matchStrings("tags", ["a", "!b"])])
|
|
54
|
+
* );
|
|
69
55
|
* // [ { id: 3, tags: ["c", "a"] } ]
|
|
70
56
|
* ```
|
|
71
57
|
*
|
|
72
58
|
* @param key
|
|
73
59
|
* @param matches
|
|
74
60
|
* @param opts
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
export declare const matchStrings: <T extends QueryObj = QueryObj>(key: QueryTerm["q"][0], matches: string[], opts?: Partial<MatchMultipleOpts<string>>) => QueryTerm<T>;
|
|
64
|
+
/**
|
|
65
|
+
* Returns a {@link QueryTerm} for use with {@link query} to perform set-like
|
|
66
|
+
* intersection or union queries with optional negation/exclusions. Matches set
|
|
67
|
+
* of given values against an item's chosen field of values and by default only
|
|
68
|
+
* succeeds if all provided `includes` can be matched (aka intersection query)
|
|
69
|
+
* and there're no values from `excludes` present.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* If the `union` option is true, only one of the provided values needs to
|
|
73
|
+
* match. Exclusions _always_ take precedence.
|
|
74
|
+
*
|
|
75
|
+
* Note: See {@link matchStrings} for a syntax sugar & examples of this
|
|
76
|
+
* function, aimed at matching `string[]` options.
|
|
77
|
+
*
|
|
78
|
+
* @param key
|
|
79
|
+
* @param matches
|
|
80
|
+
* @param opts
|
|
75
81
|
*/
|
|
76
82
|
export declare const matchMultiple: <T extends QueryObj = QueryObj, V = any>(key: QueryTerm["q"][0], includes: V[], excludes: V[], opts?: Partial<MatchMultipleOpts<V>>) => QueryTerm<T>;
|
|
77
83
|
/**
|
|
@@ -89,7 +95,7 @@ export declare const matchMultiple: <T extends QueryObj = QueryObj, V = any>(key
|
|
|
89
95
|
* between operator and value are ignored.
|
|
90
96
|
*
|
|
91
97
|
* @example
|
|
92
|
-
* ```ts
|
|
98
|
+
* ```ts tangle:../export/match-pattern.ts
|
|
93
99
|
* import { query, matchPattern } from "@thi.ng/oquery";
|
|
94
100
|
*
|
|
95
101
|
* const DB = [
|
|
@@ -98,12 +104,19 @@ export declare const matchMultiple: <T extends QueryObj = QueryObj, V = any>(key
|
|
|
98
104
|
* { id: "c", score: 15 },
|
|
99
105
|
* ];
|
|
100
106
|
*
|
|
101
|
-
*
|
|
107
|
+
* console.log(
|
|
108
|
+
* query(DB, [matchPattern("id", /[a-z]{4,}/)])
|
|
109
|
+
* );
|
|
102
110
|
* // [{ id: "bbbb", score: 60 }]
|
|
103
|
-
*
|
|
111
|
+
*
|
|
112
|
+
* console.log(
|
|
113
|
+
* query(DB, [matchPattern("id", ">= c")])
|
|
114
|
+
* );
|
|
104
115
|
* // [{ id: "c", score: 15 }]
|
|
105
116
|
*
|
|
106
|
-
*
|
|
117
|
+
* console.log(
|
|
118
|
+
* query(DB, [matchPattern("score", "<50")])
|
|
119
|
+
* );
|
|
107
120
|
* // [{ id: "a", score: 32 }, { id: "c", score: 15 }]
|
|
108
121
|
* ```
|
|
109
122
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/oquery",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.43",
|
|
4
4
|
"description": "Datalog-inspired, optimized pattern/predicate query engine for JS objects & arrays of objects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/thi-ng/umbrella.git"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://
|
|
13
|
+
"homepage": "https://thi.ng/oquery",
|
|
14
14
|
"funding": [
|
|
15
15
|
{
|
|
16
16
|
"type": "github",
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@thi.ng/api": "^8.11.
|
|
40
|
-
"@thi.ng/checks": "^3.6.
|
|
41
|
-
"@thi.ng/compare": "^2.3.
|
|
42
|
-
"@thi.ng/defmulti": "^3.0.
|
|
43
|
-
"@thi.ng/equiv": "^2.1.
|
|
39
|
+
"@thi.ng/api": "^8.11.4",
|
|
40
|
+
"@thi.ng/checks": "^3.6.6",
|
|
41
|
+
"@thi.ng/compare": "^2.3.7",
|
|
42
|
+
"@thi.ng/defmulti": "^3.0.41",
|
|
43
|
+
"@thi.ng/equiv": "^2.1.60"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@microsoft/api-extractor": "^7.
|
|
47
|
-
"esbuild": "^0.21.
|
|
46
|
+
"@microsoft/api-extractor": "^7.47.0",
|
|
47
|
+
"esbuild": "^0.21.5",
|
|
48
48
|
"typedoc": "^0.25.13",
|
|
49
|
-
"typescript": "^5.
|
|
49
|
+
"typescript": "^5.5.2"
|
|
50
50
|
},
|
|
51
51
|
"keywords": [
|
|
52
52
|
"array",
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
],
|
|
97
97
|
"year": 2020
|
|
98
98
|
},
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "7b950c112fba0b2e7c450765b15624c3382f1354\n"
|
|
100
100
|
}
|
package/query.js
CHANGED
|
@@ -6,268 +6,268 @@ import { compareByKey } from "@thi.ng/compare/keys";
|
|
|
6
6
|
import { reverse } from "@thi.ng/compare/reverse";
|
|
7
7
|
import { defmulti } from "@thi.ng/defmulti/defmulti";
|
|
8
8
|
import { equiv } from "@thi.ng/equiv";
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const a =
|
|
9
|
+
const __classify = (x) => x != null ? isFunction(x) ? "f" : "l" : "n";
|
|
10
|
+
const __ensureArray = (src) => isArray(src) ? src : [...src];
|
|
11
|
+
const __ensureSet = (src) => isArray(src) ? new Set(src) : src;
|
|
12
|
+
const __intersect = (src) => {
|
|
13
|
+
const a = __ensureArray(src);
|
|
14
14
|
const num = a.length;
|
|
15
15
|
return (b) => {
|
|
16
|
-
const $b =
|
|
16
|
+
const $b = __ensureSet(b);
|
|
17
17
|
for (let i = num; i-- > 0; ) {
|
|
18
18
|
if (!$b.has(a[i])) return false;
|
|
19
19
|
}
|
|
20
20
|
return true;
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
23
|
+
const __coerce = (x, isec = false) => isArray(x) ? isec ? __intersect(x) : (y) => x.includes(y) : isSet(x) ? isec ? __intersect(x) : (y) => x.has(y) : x;
|
|
24
|
+
const __coerceStr = (x) => isArray(x) ? __coerce(x.map((y) => String(y))) : isSet(x) ? __coerce(new Set([...x].map((y) => String(y)))) : x == null || isFunction(x) ? x : String(x);
|
|
25
|
+
const __addTriple = (acc, s, p, o) => {
|
|
26
26
|
const sval = acc[s];
|
|
27
27
|
sval ? sval[p] = o : acc[s] = { [p]: o };
|
|
28
28
|
};
|
|
29
|
-
const
|
|
29
|
+
const __match = (o, val, opts) => {
|
|
30
30
|
if (val != null) {
|
|
31
31
|
const pred = isFunction(o) ? o : ($) => opts.equiv(o, $);
|
|
32
32
|
return opts.cwise && isArray(val) ? val.some(pred) : pred(val);
|
|
33
33
|
}
|
|
34
34
|
return false;
|
|
35
35
|
};
|
|
36
|
-
const
|
|
36
|
+
const __collect = (acc, s, p, o, val, opts) => {
|
|
37
37
|
if (val != null) {
|
|
38
38
|
const pred = isFunction(o) ? o : ($) => opts.equiv(o, $);
|
|
39
39
|
if (opts.cwise && isArray(val)) {
|
|
40
40
|
val = val.filter(pred);
|
|
41
|
-
val.length &&
|
|
41
|
+
val.length && __addTriple(acc, s, p, val);
|
|
42
42
|
} else if (pred(val)) {
|
|
43
|
-
|
|
43
|
+
__addTriple(acc, s, p, val);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
const
|
|
48
|
-
const
|
|
47
|
+
const __collectFull = (res, s, val) => res[s] = val;
|
|
48
|
+
const __collectSP = (res, sval, s, p, o, opts) => {
|
|
49
49
|
if (opts.partial) {
|
|
50
50
|
for (let $p in sval) {
|
|
51
|
-
p($p) &&
|
|
51
|
+
p($p) && __collect(res, s, $p, o, sval[$p], opts);
|
|
52
52
|
}
|
|
53
53
|
} else {
|
|
54
54
|
for (let $p in sval) {
|
|
55
|
-
if (p($p) &&
|
|
56
|
-
|
|
55
|
+
if (p($p) && __match(o, sval[$p], opts)) {
|
|
56
|
+
__collectFull(res, s, sval);
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
const
|
|
62
|
+
const __collectSO = (res, sval, s, o, opts) => {
|
|
63
63
|
if (opts.partial) {
|
|
64
64
|
for (let p in sval) {
|
|
65
|
-
|
|
65
|
+
__collect(res, s, p, o, sval[p], opts);
|
|
66
66
|
}
|
|
67
67
|
} else {
|
|
68
68
|
for (let p in sval) {
|
|
69
|
-
if (
|
|
70
|
-
|
|
69
|
+
if (__match(o, sval[p], opts)) {
|
|
70
|
+
__collectFull(res, s, sval);
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
-
const
|
|
76
|
+
const __queryLL = (res, db, s, p, o, opts) => {
|
|
77
77
|
const sval = db[s];
|
|
78
78
|
const val = sval?.[p];
|
|
79
79
|
if (opts.partial) {
|
|
80
|
-
|
|
80
|
+
__collect(res, s, p, o, val, opts);
|
|
81
81
|
} else {
|
|
82
|
-
|
|
82
|
+
__match(o, val, opts) && __collectFull(res, s, sval);
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
-
const
|
|
85
|
+
const __queryLF = (res, db, s, p, o, opts) => {
|
|
86
86
|
const sval = db[s];
|
|
87
|
-
sval != null &&
|
|
87
|
+
sval != null && __collectSP(res, sval, s, p, o, opts);
|
|
88
88
|
};
|
|
89
|
-
const
|
|
89
|
+
const __queryLN = (res, db, s, _, o, opts) => {
|
|
90
90
|
const sval = db[s];
|
|
91
|
-
sval != null &&
|
|
91
|
+
sval != null && __collectSO(res, sval, s, o, opts);
|
|
92
92
|
};
|
|
93
|
-
const
|
|
93
|
+
const __queryFL = (res, db, s, p, o, opts) => {
|
|
94
94
|
if (opts.partial) {
|
|
95
95
|
for (let $s in db) {
|
|
96
|
-
s($s) &&
|
|
96
|
+
s($s) && __collect(res, $s, p, o, db[$s]?.[p], opts);
|
|
97
97
|
}
|
|
98
98
|
} else {
|
|
99
99
|
for (let $s in db) {
|
|
100
100
|
const sval = db[$s];
|
|
101
|
-
s($s) &&
|
|
101
|
+
s($s) && __match(o, sval?.[p], opts) && __collectFull(res, $s, sval);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
|
-
const
|
|
105
|
+
const __queryFF = (res, db, s, p, o, opts) => {
|
|
106
106
|
for (let $s in db) {
|
|
107
|
-
s($s) &&
|
|
107
|
+
s($s) && __collectSP(res, db[$s], $s, p, o, opts);
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
|
-
const
|
|
110
|
+
const __queryFFNPartial = (res, db, s, p) => {
|
|
111
111
|
for (let $s in db) {
|
|
112
|
-
s($s)
|
|
112
|
+
if (s($s)) {
|
|
113
|
+
const sval = db[$s];
|
|
114
|
+
for (let $p in sval) {
|
|
115
|
+
p($p) && __addTriple(res, $s, $p, sval[$p]);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const __queryFFN = (res, db, s, p) => {
|
|
121
|
+
for (let $s in db) {
|
|
122
|
+
if (s($s)) {
|
|
123
|
+
const sval = db[$s];
|
|
124
|
+
for (let $p in sval) {
|
|
125
|
+
if (p($p)) {
|
|
126
|
+
__collectFull(res, $s, sval);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const __queryFN = (res, db, s, _, o, opts) => {
|
|
134
|
+
for (let $s in db) {
|
|
135
|
+
s($s) && __collectSO(res, db[$s], $s, o, opts);
|
|
113
136
|
}
|
|
114
137
|
};
|
|
115
|
-
const
|
|
138
|
+
const __queryNL = (res, db, _, p, o, opts) => {
|
|
116
139
|
if (opts.partial) {
|
|
117
140
|
for (let s in db) {
|
|
118
|
-
|
|
141
|
+
__collect(res, s, p, o, db[s][p], opts);
|
|
119
142
|
}
|
|
120
143
|
} else {
|
|
121
144
|
for (let s in db) {
|
|
122
145
|
const sval = db[s];
|
|
123
|
-
|
|
146
|
+
__match(o, sval[p], opts) && __collectFull(res, s, sval);
|
|
124
147
|
}
|
|
125
148
|
}
|
|
126
149
|
};
|
|
127
|
-
const
|
|
150
|
+
const __queryNF = (res, db, _, p, o, opts) => {
|
|
151
|
+
for (let s in db) {
|
|
152
|
+
__collectSP(res, db[s], s, p, o, opts);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const __queryNN = (res, db, _, __, o, opts) => {
|
|
128
156
|
for (let s in db) {
|
|
129
|
-
|
|
157
|
+
__collectSO(res, db[s], s, o, opts);
|
|
130
158
|
}
|
|
131
159
|
};
|
|
132
|
-
const
|
|
160
|
+
const __queryNLNPartial = (res, db, _, p) => {
|
|
133
161
|
for (let s in db) {
|
|
134
|
-
|
|
162
|
+
const val = db[s][p];
|
|
163
|
+
val != null && __addTriple(res, s, p, val);
|
|
135
164
|
}
|
|
136
165
|
};
|
|
137
|
-
const
|
|
166
|
+
const __queryNLN = (res, db, _, p) => {
|
|
167
|
+
for (let s in db) {
|
|
168
|
+
const sval = db[s];
|
|
169
|
+
const val = sval[p];
|
|
170
|
+
val != null && __collectFull(res, s, sval);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const __querySP = (res, sval, s, p, _, opts) => {
|
|
138
174
|
if (opts.partial) {
|
|
139
175
|
for (let q in sval) {
|
|
140
176
|
if (p(q)) {
|
|
141
177
|
const val = sval[q];
|
|
142
|
-
val != null &&
|
|
178
|
+
val != null && __addTriple(res, s, q, val);
|
|
143
179
|
}
|
|
144
180
|
}
|
|
145
181
|
} else {
|
|
146
182
|
for (let q in sval) {
|
|
147
183
|
if (p(q)) {
|
|
148
|
-
|
|
184
|
+
__collectFull(res, s, sval);
|
|
149
185
|
return;
|
|
150
186
|
}
|
|
151
187
|
}
|
|
152
188
|
}
|
|
153
189
|
};
|
|
154
|
-
const
|
|
190
|
+
const __queryO = (res, db, s, p, _, opts) => {
|
|
155
191
|
const sval = db[s];
|
|
156
192
|
const val = sval?.[p];
|
|
157
|
-
val != null && (opts.partial ?
|
|
193
|
+
val != null && (opts.partial ? __addTriple(res, s, p, val) : __collectFull(res, s, sval));
|
|
158
194
|
};
|
|
159
195
|
const IMPLS = {
|
|
160
|
-
lll:
|
|
161
|
-
llf:
|
|
162
|
-
lln:
|
|
163
|
-
lfl:
|
|
164
|
-
lff:
|
|
196
|
+
lll: __queryLL,
|
|
197
|
+
llf: __queryLL,
|
|
198
|
+
lln: __queryO,
|
|
199
|
+
lfl: __queryLF,
|
|
200
|
+
lff: __queryLF,
|
|
165
201
|
lfn: (res, db, s, p, _, opts) => {
|
|
166
202
|
const sval = db[s];
|
|
167
|
-
sval != null &&
|
|
203
|
+
sval != null && __querySP(res, sval, s, p, null, opts);
|
|
168
204
|
},
|
|
169
|
-
lnl:
|
|
170
|
-
lnf:
|
|
205
|
+
lnl: __queryLN,
|
|
206
|
+
lnf: __queryLN,
|
|
171
207
|
lnn: (res, db, s) => {
|
|
172
208
|
const sval = db[s];
|
|
173
|
-
sval != null &&
|
|
209
|
+
sval != null && __collectFull(res, s, sval);
|
|
174
210
|
},
|
|
175
|
-
fll:
|
|
176
|
-
flf:
|
|
211
|
+
fll: __queryFL,
|
|
212
|
+
flf: __queryFL,
|
|
177
213
|
fln: (res, db, s, p, _, opts) => {
|
|
178
214
|
for (let $s in db) {
|
|
179
|
-
s($s) &&
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
ffl: queryFF,
|
|
183
|
-
fff: queryFF,
|
|
184
|
-
ffn: (res, db, s, p, _, opts) => {
|
|
185
|
-
if (opts.partial) {
|
|
186
|
-
for (let $s in db) {
|
|
187
|
-
if (s($s)) {
|
|
188
|
-
const sval = db[$s];
|
|
189
|
-
for (let $p in sval) {
|
|
190
|
-
p($p) && addTriple(res, $s, $p, sval[$p]);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
} else {
|
|
195
|
-
for (let $s in db) {
|
|
196
|
-
if (s($s)) {
|
|
197
|
-
const sval = db[$s];
|
|
198
|
-
for (let $p in sval) {
|
|
199
|
-
if (p($p)) {
|
|
200
|
-
collectFull(res, $s, sval);
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
215
|
+
s($s) && __queryO(res, db, $s, p, null, opts);
|
|
206
216
|
}
|
|
207
217
|
},
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
ffl: __queryFF,
|
|
219
|
+
fff: __queryFF,
|
|
220
|
+
ffn: (res, db, s, p, o, opts) => (opts.partial ? __queryFFNPartial : __queryFFN)(res, db, s, p, o, opts),
|
|
221
|
+
fnl: __queryFN,
|
|
222
|
+
fnf: __queryFN,
|
|
210
223
|
fnn: (res, db, s) => {
|
|
211
224
|
for (let $s in db) {
|
|
212
225
|
if (s($s)) {
|
|
213
226
|
const sval = db[$s];
|
|
214
|
-
sval != null &&
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
nll: queryNL,
|
|
219
|
-
nlf: queryNL,
|
|
220
|
-
nln: (res, db, _, p, __, opts) => {
|
|
221
|
-
if (opts.partial) {
|
|
222
|
-
for (let s in db) {
|
|
223
|
-
const val = db[s][p];
|
|
224
|
-
val != null && addTriple(res, s, p, val);
|
|
225
|
-
}
|
|
226
|
-
} else {
|
|
227
|
-
for (let s in db) {
|
|
228
|
-
const sval = db[s];
|
|
229
|
-
const val = sval[p];
|
|
230
|
-
val != null && collectFull(res, s, sval);
|
|
227
|
+
sval != null && __collectFull(res, $s, sval);
|
|
231
228
|
}
|
|
232
229
|
}
|
|
233
230
|
},
|
|
234
|
-
|
|
235
|
-
|
|
231
|
+
nll: __queryNL,
|
|
232
|
+
nlf: __queryNL,
|
|
233
|
+
nln: (res, db, s, p, o, opts) => (opts.partial ? __queryNLNPartial : __queryNLN)(res, db, s, p, o, opts),
|
|
234
|
+
nfl: __queryNF,
|
|
235
|
+
nff: __queryNF,
|
|
236
236
|
nfn: (res, db, _, p, __, opts) => {
|
|
237
237
|
for (let s in db) {
|
|
238
|
-
|
|
238
|
+
__querySP(res, db[s], s, p, null, opts);
|
|
239
239
|
}
|
|
240
240
|
},
|
|
241
|
-
nnl:
|
|
242
|
-
nnf:
|
|
241
|
+
nnl: __queryNN,
|
|
242
|
+
nnf: __queryNN,
|
|
243
243
|
nnn: (res, db) => Object.assign(res, db)
|
|
244
244
|
};
|
|
245
|
-
const
|
|
246
|
-
const
|
|
245
|
+
const __impl = defmulti((_, __, s, p, o) => __classify(s) + __classify(p) + __classify(o), {}, IMPLS);
|
|
246
|
+
const __objQuery = (src, opts, args) => {
|
|
247
247
|
const isIsec = opts.cwise && opts.intersect;
|
|
248
248
|
isIsec && (opts.cwise = false);
|
|
249
249
|
let [s, p, o, out] = args;
|
|
250
250
|
out = out || {};
|
|
251
|
-
|
|
251
|
+
__impl(
|
|
252
252
|
out,
|
|
253
253
|
src,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
__coerceStr(s),
|
|
255
|
+
__coerceStr(p),
|
|
256
|
+
__coerce(o, isIsec),
|
|
257
257
|
opts
|
|
258
258
|
);
|
|
259
259
|
return out;
|
|
260
260
|
};
|
|
261
|
-
const
|
|
261
|
+
const __arrayQuery = (src, opts, p, o, collect) => {
|
|
262
262
|
const isIsec = opts.cwise && opts.intersect;
|
|
263
263
|
isIsec && (opts.cwise = false);
|
|
264
|
-
const $p =
|
|
265
|
-
const $o =
|
|
266
|
-
const
|
|
264
|
+
const $p = __coerceStr(p);
|
|
265
|
+
const $o = __coerce(o, isIsec);
|
|
266
|
+
const impl = IMPLS["n" + __classify($p) + __classify($o)];
|
|
267
267
|
for (let i = 0, n = src.length; i < n; i++) {
|
|
268
268
|
const res = {};
|
|
269
|
-
|
|
270
|
-
res._ &&
|
|
269
|
+
impl(res, { _: src[i] }, "_", $p, $o, opts);
|
|
270
|
+
res._ && collect(res._, i);
|
|
271
271
|
}
|
|
272
272
|
};
|
|
273
273
|
const DEFAULT_OPTS = {
|
|
@@ -281,10 +281,10 @@ const defQuery = (opts) => {
|
|
|
281
281
|
return (src, ...args) => {
|
|
282
282
|
if (isArray(src)) {
|
|
283
283
|
const out = args[2] || [];
|
|
284
|
-
|
|
284
|
+
__arrayQuery(src, $opts, args[0], args[1], (x) => out.push(x));
|
|
285
285
|
return out;
|
|
286
286
|
} else {
|
|
287
|
-
return
|
|
287
|
+
return __objQuery(src, $opts, args);
|
|
288
288
|
}
|
|
289
289
|
};
|
|
290
290
|
};
|
|
@@ -293,10 +293,10 @@ const defKeyQuery = (opts) => {
|
|
|
293
293
|
return (src, ...args) => {
|
|
294
294
|
if (isArray(src)) {
|
|
295
295
|
const out = args[2] || /* @__PURE__ */ new Set();
|
|
296
|
-
|
|
296
|
+
__arrayQuery(src, $opts, args[0], args[1], (_, i) => out.add(i));
|
|
297
297
|
return out;
|
|
298
298
|
} else {
|
|
299
|
-
const res =
|
|
299
|
+
const res = __objQuery(src, $opts, args.slice(0, 3));
|
|
300
300
|
const out = args[3];
|
|
301
301
|
if (!out) return new Set(Object.keys(res));
|
|
302
302
|
for (let k in res) out.add(k);
|