@jarenjs/json 0.9.2 → 0.34.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.
- package/ARCHITECTURE.md +86 -13
- package/README.md +248 -23
- package/dist/types/canonical.d.ts +37 -0
- package/dist/types/cow.d.ts +28 -0
- package/dist/types/errors.d.ts +45 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/jslt/errors.d.ts +15 -8
- package/dist/types/jslt/index.d.ts +22 -0
- package/dist/types/jslt/packs/finance.d.ts +119 -0
- package/dist/types/jslt/packs/index.d.ts +310 -0
- package/dist/types/jslt/packs/math.d.ts +159 -0
- package/dist/types/jslt/packs/stats.d.ts +48 -0
- package/dist/types/jslt/registry.d.ts +65 -0
- package/dist/types/jtlt/errors.d.ts +3 -6
- package/dist/types/option-variants.d.ts +29 -0
- package/dist/types/patch.d.ts +214 -0
- package/dist/types/path.d.ts +139 -9
- package/dist/types/pointer.d.ts +100 -9
- package/dist/types/query/compile.d.ts +12 -0
- package/dist/types/query/errors.d.ts +72 -8
- package/dist/types/query/index.d.ts +317 -25
- package/dist/types/query/normalize.d.ts +24 -0
- package/dist/types/query/operators.d.ts +241 -1
- package/dist/types/query/runtime.d.ts +5 -8
- package/dist/types/query/types.d.ts +34 -0
- package/dist/types/segments.d.ts +31 -0
- package/dist/types/write.d.ts +204 -0
- package/dist/types/xquery/parse.d.ts +2 -3
- package/docs/JSLT-FORMAT.md +74 -3
- package/docs/JSLT-PRELUDE.md +1 -1
- package/docs/QUERY-FORMAT.md +695 -33
- package/package.json +18 -4
- package/schemas/geojson.draft-07.schema.json +323 -0
- package/schemas/geojson.jaren.schema.json +863 -0
- package/schemas/geojson.schema.json +172 -0
- package/schemas/jaren-jslt.authoring.schema.json +142 -0
- package/schemas/jaren-jslt.draft-07.schema.json +152 -11
- package/schemas/jaren-jslt.llm-profile.schema.json +782 -0
- package/schemas/jaren-jslt.schema.json +152 -11
- package/schemas/jaren-query.draft-07.schema.json +152 -11
- package/schemas/jaren-query.llm-profile.schema.json +619 -0
- package/schemas/jaren-query.schema.json +82 -15
- package/src/basic.js +1 -1
- package/src/canonical.js +170 -0
- package/src/cow.js +106 -0
- package/src/errors.js +68 -0
- package/src/index.js +3 -0
- package/src/jslt/dispatch.js +178 -28
- package/src/jslt/errors.js +19 -14
- package/src/jslt/index.js +37 -29
- package/src/jslt/packs/finance.js +49 -0
- package/src/jslt/packs/index.js +18 -0
- package/src/jslt/packs/math.js +46 -0
- package/src/jslt/packs/stats.js +65 -0
- package/src/jslt/registry.js +200 -0
- package/src/jslt/stylesheet.js +14 -23
- package/src/jtlt/desugar.js +2 -3
- package/src/jtlt/errors.js +6 -12
- package/src/jtlt/index.js +12 -29
- package/src/jtlt/template.js +9 -18
- package/src/option-variants.js +54 -0
- package/src/patch.js +1052 -0
- package/src/path.js +319 -52
- package/src/pointer.js +225 -44
- package/src/query/compile.js +790 -75
- package/src/query/errors.js +72 -12
- package/src/query/index.js +274 -42
- package/src/query/normalize.js +489 -78
- package/src/query/operators.js +620 -23
- package/src/query/runtime.js +5 -19
- package/src/query/types.js +213 -0
- package/src/segments.js +409 -64
- package/src/write.js +660 -0
- package/src/xquery/parse.js +37 -53
|
@@ -1,18 +1,82 @@
|
|
|
1
|
+
import { CodedError } from '@jarenjs/core/errors';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime code table (the `CSV_CODES` shape): one entry per code
|
|
4
|
+
* the engine can raise, proven in sync with QUERY-FORMAT.md §10's
|
|
5
|
+
* normative tables by a test — the table cannot silently drift from
|
|
6
|
+
* the spec.
|
|
7
|
+
*/
|
|
8
|
+
export declare const QUERY_CODES: Readonly<{
|
|
9
|
+
JQ0001: "object mixes $-prefixed and plain keys";
|
|
10
|
+
JQ0002: "unknown operator or $-key outside the vocabulary";
|
|
11
|
+
JQ0003: "known phrase with bad arity, value shape, or key combination";
|
|
12
|
+
JQ0004: "string starting $ is not a valid path or escape";
|
|
13
|
+
JQ0005: "variable reference neither bound nor a declared external";
|
|
14
|
+
JQ0006: "version envelope with unknown or non-string $query";
|
|
15
|
+
JQ0007: "duplicate variable binding within one phrase";
|
|
16
|
+
JQ0008: "schema operator in a query compiled without a type-test compiler";
|
|
17
|
+
JQ0009: "schema literal rejected by the type-test compiler";
|
|
18
|
+
JQ0010: "$call/$collation naming no registered function/collation";
|
|
19
|
+
JQ0011: "expression nesting deeper than limits.depth";
|
|
20
|
+
JQ2001: "runtime type error";
|
|
21
|
+
JQ2002: "$idiv/$mod by zero";
|
|
22
|
+
JQ2003: "EBV of a multi-item sequence";
|
|
23
|
+
JQ2004: "$map key expression not a single string";
|
|
24
|
+
JQ2005: "incomparable $orderby/$sort keys";
|
|
25
|
+
JQ2006: "reference to an unbound external parameter";
|
|
26
|
+
JQ2007: "resource guard: an operator result exceeding an implementation limit";
|
|
27
|
+
JQ2008: "schema assertion failure";
|
|
28
|
+
JQ2009: "an execution limit exceeded";
|
|
29
|
+
JQ2010: "a registered $call function threw";
|
|
30
|
+
JQ2011: "the input document is undefined";
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Shared constructor body for the two query error classes: `cause`
|
|
34
|
+
* retains what host code threw, BY VALUE — set via an own property
|
|
35
|
+
* even for `undefined`, so presence is testable (the base's `hasOwn`
|
|
36
|
+
* options form, passed through unchanged).
|
|
37
|
+
*/
|
|
38
|
+
declare class JsonQueryError extends CodedError {
|
|
39
|
+
/**
|
|
40
|
+
* @param {string} name - The public class name for `error.name`
|
|
41
|
+
* @param {string} code
|
|
42
|
+
* @param {string} reason
|
|
43
|
+
* @param {string} docPath
|
|
44
|
+
* @param {{ cause?: unknown }} [options]
|
|
45
|
+
*/
|
|
46
|
+
constructor(name: string, code: string, reason: string, docPath: string, options?: {
|
|
47
|
+
cause?: unknown;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
1
50
|
/**
|
|
2
51
|
* Error thrown when a query document is rejected at compile time
|
|
3
52
|
* (`JQ0xxx` codes, QUERY-FORMAT.md section 10.2).
|
|
4
53
|
*/
|
|
5
|
-
export declare class JsonQueryCompileError extends
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
54
|
+
export declare class JsonQueryCompileError extends JsonQueryError {
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} code
|
|
57
|
+
* @param {string} reason
|
|
58
|
+
* @param {string} docPath
|
|
59
|
+
* @param {{ cause?: unknown }} [options] - `cause` retains what a
|
|
60
|
+
* host hook (e.g. `compileTypeTest`) threw
|
|
61
|
+
*/
|
|
62
|
+
constructor(code: string, reason: string, docPath: string, options?: {
|
|
63
|
+
cause?: unknown;
|
|
64
|
+
});
|
|
9
65
|
}
|
|
10
66
|
/**
|
|
11
67
|
* Error thrown when evaluating a compiled query fails
|
|
12
68
|
* (`JQ2xxx` codes, QUERY-FORMAT.md section 10.3).
|
|
13
69
|
*/
|
|
14
|
-
export declare class JsonQueryRuntimeError extends
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
70
|
+
export declare class JsonQueryRuntimeError extends JsonQueryError {
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} code
|
|
73
|
+
* @param {string} reason
|
|
74
|
+
* @param {string} docPath
|
|
75
|
+
* @param {{ cause?: unknown }} [options] - `cause` retains what host
|
|
76
|
+
* code threw
|
|
77
|
+
*/
|
|
78
|
+
constructor(code: string, reason: string, docPath: string, options?: {
|
|
79
|
+
cause?: unknown;
|
|
80
|
+
});
|
|
18
81
|
}
|
|
82
|
+
export {};
|
|
@@ -1,10 +1,274 @@
|
|
|
1
|
-
|
|
1
|
+
import { NODE_KINDS } from './normalize.js';
|
|
2
|
+
export { JsonQueryCompileError, JsonQueryRuntimeError, QUERY_CODES } from './errors.js';
|
|
3
|
+
export { NODE_KINDS };
|
|
4
|
+
export { annotateTypes, TYPE_TAGS } from './types.js';
|
|
5
|
+
export type JsonQueryLimits = {
|
|
6
|
+
/**
|
|
7
|
+
* - Caps every FLWOR phrase
|
|
8
|
+
* materialization and tightens `$range`'s resource guard; exceeding
|
|
9
|
+
* it is `JQ2009` (`$range` keeps its historical `JQ2007`).
|
|
10
|
+
*/
|
|
11
|
+
sequenceItems?: number;
|
|
12
|
+
/**
|
|
13
|
+
* - Caps the final result at the
|
|
14
|
+
* query boundary (`JQ2009`); checked after evaluation, and
|
|
15
|
+
* deliberately bypassed by `first`/`exists`/`ebv`.
|
|
16
|
+
*/
|
|
17
|
+
resultItems?: number;
|
|
18
|
+
/**
|
|
19
|
+
* - Caps expression-node evaluations
|
|
20
|
+
* (`JQ2009`). This is the one limit that bounds *work* rather than
|
|
21
|
+
* output, so it is also the one that costs: setting it compiles a
|
|
22
|
+
* counter check into every node, roughly halving throughput. A step
|
|
23
|
+
* is one node evaluation, not one primitive operation - a single
|
|
24
|
+
* node that loops internally (`$range` materialization, a general
|
|
25
|
+
* comparison's cross product) counts once.
|
|
26
|
+
*/
|
|
27
|
+
steps?: number;
|
|
28
|
+
/**
|
|
29
|
+
* - Caps expression nesting, enforced at
|
|
30
|
+
* compile time (`JQ0011`). The language has no recursion, so the
|
|
31
|
+
* compiled closure tree's evaluation depth IS the document's static
|
|
32
|
+
* nesting: checking it once is exact and costs nothing to evaluate.
|
|
33
|
+
*/
|
|
34
|
+
depth?: number;
|
|
35
|
+
};
|
|
36
|
+
export type JsonQueryOptions = {
|
|
37
|
+
/**
|
|
38
|
+
* Hook compiling a JSON Schema literal into a boolean item
|
|
39
|
+
* predicate, called once per schema literal at query compile time
|
|
40
|
+
* (QUERY-FORMAT.md section 8.11). `@jarenjs/validate/query` exports
|
|
41
|
+
* `createTypeTestCompiler()` producing one; any conforming
|
|
42
|
+
* implementation works - this package never imports the validator.
|
|
43
|
+
* Without a hook, the schema operators `$valid`/`$assert`/`$as` are
|
|
44
|
+
* compile error JQ0008.
|
|
45
|
+
*/
|
|
46
|
+
compileTypeTest?: (schemaJson: any, docPath: string) => ((value: any) => boolean);
|
|
47
|
+
/**
|
|
48
|
+
* - Package-internal operator
|
|
49
|
+
* extension point, the operator analogue of `compileTypeTest` (used
|
|
50
|
+
* by the JSLT layer; not a public contract). A plain object of
|
|
51
|
+
* `name -> entry` following the operator registry contract; see
|
|
52
|
+
* normalizeQuery in normalize.js for the full shape. The published
|
|
53
|
+
* format vocabulary is unchanged: without extensions, documents
|
|
54
|
+
* using such operators fail JQ0002.
|
|
55
|
+
*/
|
|
56
|
+
extensions?: object;
|
|
57
|
+
/**
|
|
58
|
+
* Registry of named trusted pure host functions for `$call`
|
|
59
|
+
* (QUERY-FORMAT.md section 8.12); an unregistered or empty name is
|
|
60
|
+
* rejected at compile time (JQ0010 / TypeError).
|
|
61
|
+
*/
|
|
62
|
+
functions?: Record<string, (...args: any[]) => any>;
|
|
63
|
+
/**
|
|
64
|
+
* Registry of named pure compare functions for `$orderby`'s
|
|
65
|
+
* `$collation` member (QUERY-FORMAT.md section 6.6).
|
|
66
|
+
*/
|
|
67
|
+
collations?: Record<string, (a: string, b: string) => number>;
|
|
68
|
+
/**
|
|
69
|
+
* Registry of custom JSONPath function extensions (RFC 9535 section
|
|
70
|
+
* 2.4), available inside the filters of every path string the
|
|
71
|
+
* document contains. Deliberately separate from `functions`: that
|
|
72
|
+
* registry extends the query vocabulary through `$call`, this one
|
|
73
|
+
* extends the RFC 9535 grammar the path strings are written in.
|
|
74
|
+
*/
|
|
75
|
+
pathFunctions?: Record<string, import('../path.js').JSONPathFunction>;
|
|
76
|
+
/**
|
|
77
|
+
* - Enforced execution limits.
|
|
78
|
+
*/
|
|
79
|
+
limits?: JsonQueryLimits;
|
|
80
|
+
/**
|
|
81
|
+
* - Closed-world compilation:
|
|
82
|
+
* the variable names (no `$` sigil) the document may leave free.
|
|
83
|
+
* Every other free variable is compile error `JQ0005` at its own
|
|
84
|
+
* reference site, so a query cannot silently acquire a parameter the
|
|
85
|
+
* host never meant to expose. `[]` declares none. Omitted, the open
|
|
86
|
+
* world of QUERY-FORMAT.md section 9 applies: use is the declaration.
|
|
87
|
+
*/
|
|
88
|
+
externals?: readonly string[];
|
|
89
|
+
/**
|
|
90
|
+
* - On `compileJsonQuery`: additionally
|
|
91
|
+
* expose the normalized-form record (QUERY-FORMAT.md Appendix C.1) at
|
|
92
|
+
* `query.analysis`, from the same normalization. Compilation itself
|
|
93
|
+
* stays strict — schema hooks remain required.
|
|
94
|
+
*/
|
|
95
|
+
analysis?: boolean;
|
|
96
|
+
};
|
|
97
|
+
export type JsonQueryAnalysis = {
|
|
98
|
+
/**
|
|
99
|
+
* - see the compatibility policy (C.7)
|
|
100
|
+
*/
|
|
101
|
+
astVersion: number;
|
|
102
|
+
/**
|
|
103
|
+
* - the frozen node tree (C.3)
|
|
104
|
+
*/
|
|
105
|
+
root: object;
|
|
106
|
+
externals: readonly {
|
|
107
|
+
name: string;
|
|
108
|
+
slot: number;
|
|
109
|
+
}[];
|
|
110
|
+
frameSize: number;
|
|
111
|
+
dependencies: Readonly<JsonQueryDependencies>;
|
|
112
|
+
limits: object | null;
|
|
113
|
+
};
|
|
114
|
+
export type JsonQueryDependencies = {
|
|
115
|
+
externals: readonly string[];
|
|
116
|
+
operators: readonly string[];
|
|
117
|
+
functions: readonly string[];
|
|
118
|
+
collations: readonly string[];
|
|
119
|
+
};
|
|
120
|
+
export type JsonQueryExplanation = {
|
|
121
|
+
externals: string[];
|
|
122
|
+
operators: string[];
|
|
123
|
+
functions: string[];
|
|
124
|
+
collations: string[];
|
|
125
|
+
limits: {
|
|
126
|
+
sequenceItems: number | null;
|
|
127
|
+
resultItems: number | null;
|
|
128
|
+
steps: number | null;
|
|
129
|
+
depth: number | null;
|
|
130
|
+
} | null;
|
|
131
|
+
};
|
|
132
|
+
export type CompiledJsonQuery = ((data: any, externals?: Record<string, any>) => any) & {
|
|
133
|
+
first: (data: any, externals?: Record<string, any>) => any;
|
|
134
|
+
exists: (data: any, externals?: Record<string, any>) => boolean;
|
|
135
|
+
ebv: (data: any, externals?: Record<string, any>) => boolean;
|
|
136
|
+
externals: readonly string[];
|
|
137
|
+
doc: any;
|
|
138
|
+
dependencies: Readonly<JsonQueryDependencies>;
|
|
139
|
+
explain: () => JsonQueryExplanation;
|
|
140
|
+
analysis?: Readonly<JsonQueryAnalysis>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* The enforced query limits (QUERY-FORMAT.md section 8.12). These are
|
|
144
|
+
* deterministic result/phrase-OUTPUT caps, not general resource
|
|
145
|
+
* budgets: they bound what a phrase or the query hands onward, never
|
|
146
|
+
* the memory, work, fan-out or recursion spent producing it (a group
|
|
147
|
+
* or order barrier may accumulate arbitrarily many items behind a
|
|
148
|
+
* small final result). Untrusted queries need worker isolation, not
|
|
149
|
+
* these limits.
|
|
150
|
+
* @typedef {Object} JsonQueryLimits
|
|
151
|
+
* @property {number} [sequenceItems] - Caps every FLWOR phrase
|
|
152
|
+
* materialization and tightens `$range`'s resource guard; exceeding
|
|
153
|
+
* it is `JQ2009` (`$range` keeps its historical `JQ2007`).
|
|
154
|
+
* @property {number} [resultItems] - Caps the final result at the
|
|
155
|
+
* query boundary (`JQ2009`); checked after evaluation, and
|
|
156
|
+
* deliberately bypassed by `first`/`exists`/`ebv`.
|
|
157
|
+
* @property {number} [steps] - Caps expression-node evaluations
|
|
158
|
+
* (`JQ2009`). This is the one limit that bounds *work* rather than
|
|
159
|
+
* output, so it is also the one that costs: setting it compiles a
|
|
160
|
+
* counter check into every node, roughly halving throughput. A step
|
|
161
|
+
* is one node evaluation, not one primitive operation - a single
|
|
162
|
+
* node that loops internally (`$range` materialization, a general
|
|
163
|
+
* comparison's cross product) counts once.
|
|
164
|
+
* @property {number} [depth] - Caps expression nesting, enforced at
|
|
165
|
+
* compile time (`JQ0011`). The language has no recursion, so the
|
|
166
|
+
* compiled closure tree's evaluation depth IS the document's static
|
|
167
|
+
* nesting: checking it once is exact and costs nothing to evaluate.
|
|
168
|
+
*/
|
|
169
|
+
/**
|
|
170
|
+
* Compile options for {@link compileJsonQuery}.
|
|
171
|
+
* @typedef {Object} JsonQueryOptions
|
|
172
|
+
* @property {(schemaJson: any, docPath: string) => ((value: any) => boolean)} [compileTypeTest]
|
|
173
|
+
* Hook compiling a JSON Schema literal into a boolean item
|
|
174
|
+
* predicate, called once per schema literal at query compile time
|
|
175
|
+
* (QUERY-FORMAT.md section 8.11). `@jarenjs/validate/query` exports
|
|
176
|
+
* `createTypeTestCompiler()` producing one; any conforming
|
|
177
|
+
* implementation works - this package never imports the validator.
|
|
178
|
+
* Without a hook, the schema operators `$valid`/`$assert`/`$as` are
|
|
179
|
+
* compile error JQ0008.
|
|
180
|
+
* @property {object} [extensions] - Package-internal operator
|
|
181
|
+
* extension point, the operator analogue of `compileTypeTest` (used
|
|
182
|
+
* by the JSLT layer; not a public contract). A plain object of
|
|
183
|
+
* `name -> entry` following the operator registry contract; see
|
|
184
|
+
* normalizeQuery in normalize.js for the full shape. The published
|
|
185
|
+
* format vocabulary is unchanged: without extensions, documents
|
|
186
|
+
* using such operators fail JQ0002.
|
|
187
|
+
* @property {Record<string, (...args: any[]) => any>} [functions]
|
|
188
|
+
* Registry of named trusted pure host functions for `$call`
|
|
189
|
+
* (QUERY-FORMAT.md section 8.12); an unregistered or empty name is
|
|
190
|
+
* rejected at compile time (JQ0010 / TypeError).
|
|
191
|
+
* @property {Record<string, (a: string, b: string) => number>} [collations]
|
|
192
|
+
* Registry of named pure compare functions for `$orderby`'s
|
|
193
|
+
* `$collation` member (QUERY-FORMAT.md section 6.6).
|
|
194
|
+
* @property {Record<string, import('../path.js').JSONPathFunction>} [pathFunctions]
|
|
195
|
+
* Registry of custom JSONPath function extensions (RFC 9535 section
|
|
196
|
+
* 2.4), available inside the filters of every path string the
|
|
197
|
+
* document contains. Deliberately separate from `functions`: that
|
|
198
|
+
* registry extends the query vocabulary through `$call`, this one
|
|
199
|
+
* extends the RFC 9535 grammar the path strings are written in.
|
|
200
|
+
* @property {JsonQueryLimits} [limits] - Enforced execution limits.
|
|
201
|
+
* @property {readonly string[]} [externals] - Closed-world compilation:
|
|
202
|
+
* the variable names (no `$` sigil) the document may leave free.
|
|
203
|
+
* Every other free variable is compile error `JQ0005` at its own
|
|
204
|
+
* reference site, so a query cannot silently acquire a parameter the
|
|
205
|
+
* host never meant to expose. `[]` declares none. Omitted, the open
|
|
206
|
+
* world of QUERY-FORMAT.md section 9 applies: use is the declaration.
|
|
207
|
+
* @property {boolean} [analysis] - On `compileJsonQuery`: additionally
|
|
208
|
+
* expose the normalized-form record (QUERY-FORMAT.md Appendix C.1) at
|
|
209
|
+
* `query.analysis`, from the same normalization. Compilation itself
|
|
210
|
+
* stays strict — schema hooks remain required.
|
|
211
|
+
*/
|
|
212
|
+
/**
|
|
213
|
+
* The published normalized-form record (QUERY-FORMAT.md Appendix C.1):
|
|
214
|
+
* what `analyzeQuery` returns and `compileJsonQuery`'s `analysis`
|
|
215
|
+
* option exposes.
|
|
216
|
+
* @typedef {Object} JsonQueryAnalysis
|
|
217
|
+
* @property {number} astVersion - see the compatibility policy (C.7)
|
|
218
|
+
* @property {object} root - the frozen node tree (C.3)
|
|
219
|
+
* @property {readonly { name: string, slot: number }[]} externals
|
|
220
|
+
* @property {number} frameSize
|
|
221
|
+
* @property {Readonly<JsonQueryDependencies>} dependencies
|
|
222
|
+
* @property {object | null} limits
|
|
223
|
+
*/
|
|
224
|
+
/**
|
|
225
|
+
* The frozen dependency record of a compiled query (saved-rule
|
|
226
|
+
* vetting): the external names it binds, the operators it uses, and
|
|
227
|
+
* the registered functions/collations it resolved.
|
|
228
|
+
* @typedef {Object} JsonQueryDependencies
|
|
229
|
+
* @property {readonly string[]} externals
|
|
230
|
+
* @property {readonly string[]} operators
|
|
231
|
+
* @property {readonly string[]} functions
|
|
232
|
+
* @property {readonly string[]} collations
|
|
233
|
+
*/
|
|
234
|
+
/**
|
|
235
|
+
* A plain-JSON explanation of a compiled query: its dependencies plus
|
|
236
|
+
* the enforced limits. A fresh value each `explain()` call.
|
|
237
|
+
* @typedef {Object} JsonQueryExplanation
|
|
238
|
+
* @property {string[]} externals
|
|
239
|
+
* @property {string[]} operators
|
|
240
|
+
* @property {string[]} functions
|
|
241
|
+
* @property {string[]} collations
|
|
242
|
+
* @property {{ sequenceItems: number | null, resultItems: number | null, steps: number | null, depth: number | null } | null} limits
|
|
243
|
+
*/
|
|
244
|
+
/**
|
|
245
|
+
* The compiled query returned by {@link compileJsonQuery}: the query
|
|
246
|
+
* function itself, carrying its helper methods and metadata.
|
|
247
|
+
* @typedef {((data: any, externals?: Record<string, any>) => any) & {
|
|
248
|
+
* first: (data: any, externals?: Record<string, any>) => any,
|
|
249
|
+
* exists: (data: any, externals?: Record<string, any>) => boolean,
|
|
250
|
+
* ebv: (data: any, externals?: Record<string, any>) => boolean,
|
|
251
|
+
* externals: readonly string[],
|
|
252
|
+
* doc: any,
|
|
253
|
+
* dependencies: Readonly<JsonQueryDependencies>,
|
|
254
|
+
* explain: () => JsonQueryExplanation,
|
|
255
|
+
* analysis?: Readonly<JsonQueryAnalysis>,
|
|
256
|
+
* }} CompiledJsonQuery
|
|
257
|
+
*/
|
|
2
258
|
/**
|
|
3
259
|
* Compile a Jaren JSON Query document into a reusable query function.
|
|
4
260
|
*
|
|
5
261
|
* The returned function applies the query to a JSON value and returns the
|
|
6
262
|
* result as plain JSON: `undefined` for the empty sequence, the item
|
|
7
263
|
* itself for a singleton result, an array of items for a longer sequence.
|
|
264
|
+
*
|
|
265
|
+
* The `data` argument MUST be a JSON value (section 2.1). The engine does
|
|
266
|
+
* not deep-validate it - that would cost a full walk per call - so a
|
|
267
|
+
* non-JSON value inside the document simply flows through as an opaque
|
|
268
|
+
* item. The single exception is `undefined`, rejected with `JQ2011`
|
|
269
|
+
* because this API already spends `undefined` on the empty sequence.
|
|
270
|
+
* An external bound to `undefined` reads as unbound (`JQ2006` on use).
|
|
271
|
+
*
|
|
8
272
|
* It also carries helper methods and metadata:
|
|
9
273
|
*
|
|
10
274
|
* - `query(data, externals?)` - the query result as described above
|
|
@@ -22,26 +286,15 @@ export { JsonQueryCompileError, JsonQueryRuntimeError } from './errors.js';
|
|
|
22
286
|
* external raises `JQ2006`.
|
|
23
287
|
* - `query.doc` - a deeply frozen copy of the query document (the
|
|
24
288
|
* caller's object is never frozen)
|
|
289
|
+
* - `query.dependencies` - what the query depends on (frozen JSON):
|
|
290
|
+
* external names, operators, registered functions and collations
|
|
291
|
+
* - `query.explain()` - a fresh plain-JSON explanation: the
|
|
292
|
+
* dependencies plus the enforced limits
|
|
25
293
|
*
|
|
26
294
|
* @param {any} doc - the query document (any JSON value; a bare RFC 9535
|
|
27
295
|
* JSONPath string is the degenerate query)
|
|
28
|
-
* @param {
|
|
29
|
-
* @
|
|
30
|
-
* [options.compileTypeTest] - hook compiling a JSON Schema literal into
|
|
31
|
-
* a boolean item predicate, called once per schema literal at query
|
|
32
|
-
* compile time (QUERY-FORMAT.md section 8.11). `@jarenjs/validate/query`
|
|
33
|
-
* exports `createTypeTestCompiler()` producing one; any conforming
|
|
34
|
-
* implementation works - this package never imports the validator.
|
|
35
|
-
* Without a hook, the schema operators `$valid`/`$assert`/`$as` are
|
|
36
|
-
* compile error JQ0008.
|
|
37
|
-
* @param {object} [options.extensions] - package-internal operator
|
|
38
|
-
* extension point, the operator analogue of `compileTypeTest` (used by
|
|
39
|
-
* the JSLT layer; not a public contract). A plain object of
|
|
40
|
-
* `name -> entry` following the operator registry contract; see
|
|
41
|
-
* normalizeQuery in normalize.js for the full shape. The published
|
|
42
|
-
* format vocabulary is unchanged: without extensions, documents using
|
|
43
|
-
* such operators fail JQ0002.
|
|
44
|
-
* @returns {function} the compiled query function
|
|
296
|
+
* @param {JsonQueryOptions} [options] - compile options
|
|
297
|
+
* @returns {CompiledJsonQuery} the compiled query function
|
|
45
298
|
* @throws {JsonQueryCompileError} when the document violates the format
|
|
46
299
|
* @example
|
|
47
300
|
* const q = compileJsonQuery({
|
|
@@ -51,15 +304,54 @@ export { JsonQueryCompileError, JsonQueryRuntimeError } from './errors.js';
|
|
|
51
304
|
* q.externals; // ['max']
|
|
52
305
|
* q(data, { max: 10 }); // { title: 'Sayings of the Century', cheap: true }
|
|
53
306
|
*/
|
|
54
|
-
export declare function compileJsonQuery(doc: any, options?:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
307
|
+
export declare function compileJsonQuery(doc: any, options?: JsonQueryOptions): CompiledJsonQuery;
|
|
308
|
+
/**
|
|
309
|
+
* The version of the published normalized form (QUERY-FORMAT.md
|
|
310
|
+
* Appendix C.7): bumped when a node kind is added or removed, a
|
|
311
|
+
* published field is removed or retyped, or an appendix invariant
|
|
312
|
+
* changes. Adding an optional field is NOT a bump.
|
|
313
|
+
*/
|
|
314
|
+
export declare const AST_VERSION = 1;
|
|
315
|
+
/**
|
|
316
|
+
* Analyse a query document WITHOUT compiling it: the engine's own
|
|
317
|
+
* normalized reading of the document — the frozen node tree, the
|
|
318
|
+
* externals in first-appearance order, the frame size and the
|
|
319
|
+
* dependency sets — published as the versioned contract of
|
|
320
|
+
* QUERY-FORMAT.md Appendix C. Another package walks this instead of
|
|
321
|
+
* re-implementing the grammar, and an unknown `kind` in its dispatch is
|
|
322
|
+
* a loud failure instead of a silent divergence.
|
|
323
|
+
*
|
|
324
|
+
* Analysis applies every JQ0xxx rejection compilation would, with one
|
|
325
|
+
* difference (Appendix C.1): schema literals do not require
|
|
326
|
+
* `options.compileTypeTest` — without the hook they normalize to `raw`
|
|
327
|
+
* nodes whose `test` is `null`, so a document can be analysed by a
|
|
328
|
+
* consumer that could not execute it. With the hook supplied, analysis
|
|
329
|
+
* compiles the predicates exactly as compilation would.
|
|
330
|
+
* @param {any} doc - the query document (any JSON value)
|
|
331
|
+
* @param {JsonQueryOptions} [options] - the same options as
|
|
332
|
+
* `compileJsonQuery`
|
|
333
|
+
* @returns {{ astVersion: number, root: object, externals: readonly
|
|
334
|
+
* { name: string, slot: number }[], frameSize: number,
|
|
335
|
+
* dependencies: Readonly<JsonQueryDependencies>, limits: object | null }}
|
|
336
|
+
* @throws {JsonQueryCompileError} on any JQ0xxx condition (except
|
|
337
|
+
* JQ0008, which analysis does not raise)
|
|
338
|
+
*/
|
|
339
|
+
export declare function analyzeQuery(doc: any, options?: JsonQueryOptions): {
|
|
340
|
+
astVersion: number;
|
|
341
|
+
root: object;
|
|
342
|
+
externals: readonly {
|
|
343
|
+
name: string;
|
|
344
|
+
slot: number;
|
|
345
|
+
}[];
|
|
346
|
+
frameSize: number;
|
|
347
|
+
dependencies: Readonly<JsonQueryDependencies>;
|
|
348
|
+
limits: object | null;
|
|
349
|
+
};
|
|
58
350
|
/**
|
|
59
351
|
* Apply a Jaren JSON Query document to a JSON value in one call.
|
|
60
|
-
* Compiled queries are cached: object documents by identity (
|
|
61
|
-
* string documents (the degenerate JSONPath case) by value (
|
|
62
|
-
* entries
|
|
352
|
+
* Compiled queries are cached: object documents by identity (weak),
|
|
353
|
+
* string documents (the degenerate JSONPath case) by value (bounded
|
|
354
|
+
* LRU, 512 entries — the shared `@jarenjs/core/cache` primitive).
|
|
63
355
|
* @param {any} doc - the query document
|
|
64
356
|
* @param {any} data - the JSON value to query
|
|
65
357
|
* @param {object} [externals] - external parameter bindings (`{ name: value }`)
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The twelve node kinds of the normalized form, sorted — the published
|
|
3
|
+
* AST contract (QUERY-FORMAT.md Appendix C). An exhaustiveness gate
|
|
4
|
+
* asserts a corpus exercising every construct produces exactly this
|
|
5
|
+
* set, so a new kind cannot ship undocumented.
|
|
6
|
+
*/
|
|
7
|
+
export declare const NODE_KINDS: readonly string[];
|
|
1
8
|
/** Statically empty (the node always evaluates to the empty sequence). */
|
|
2
9
|
export declare const CARD_ZERO = 0;
|
|
3
10
|
/** Always exactly one item; compile.js skips all sequence checks. */
|
|
@@ -22,6 +29,15 @@ export declare function joinCard(a: number, b: number): number;
|
|
|
22
29
|
* @returns {number}
|
|
23
30
|
*/
|
|
24
31
|
export declare function sumCard(a: number, b: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Project a safe diagnostic string from whatever a host hook threw:
|
|
34
|
+
* no `.message` read on a raw value, no user coercion, no
|
|
35
|
+
* proxy-observable reflection — the compiler must never fail while
|
|
36
|
+
* describing a host failure.
|
|
37
|
+
* @param {unknown} e
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
export declare function hostFailureText(e: unknown): string;
|
|
25
41
|
/**
|
|
26
42
|
* Deep-copy a JSON value and freeze every object/array in the copy.
|
|
27
43
|
* Used for `$const` values and the compiled query's `.doc` property, so
|
|
@@ -30,6 +46,14 @@ export declare function sumCard(a: number, b: number): number;
|
|
|
30
46
|
* @returns {any} an independent, deeply frozen copy
|
|
31
47
|
*/
|
|
32
48
|
export declare function deepFreezeCopy(value: any): any;
|
|
49
|
+
/**
|
|
50
|
+
* Collect the frame slots an expression subtree reads (variable
|
|
51
|
+
* references and path roots) into `out`. Over-approximation is safe.
|
|
52
|
+
* @param {object} node - a frozen AST node
|
|
53
|
+
* @param {Set<number>} out - accumulator of slot indexes
|
|
54
|
+
*/
|
|
55
|
+
export declare function collectReadSlots(node: object, out: Set<number>): void;
|
|
56
|
+
export declare function isReservedQueryName(name: any): boolean;
|
|
33
57
|
/**
|
|
34
58
|
* Normalize a query document into the internal AST.
|
|
35
59
|
* @param {any} doc - the query document (any JSON value)
|