@routier/core 0.5.0 → 0.7.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/README.md +1 -1
- package/dist/assertions/index.cjs +19 -8
- package/dist/assertions/index.cjs.map +1 -1
- package/dist/assertions/index.d.ts +5 -1
- package/dist/assertions/index.js +21 -9
- package/dist/assertions/index.js.map +1 -1
- package/dist/collections/MemoryDataCollection.d.ts +10 -0
- package/dist/collections/index.cjs +29 -4
- package/dist/collections/index.cjs.map +1 -1
- package/dist/collections/index.js +29 -4
- package/dist/collections/index.js.map +1 -1
- package/dist/expressions/callSource.d.ts +41 -0
- package/dist/expressions/evaluate.d.ts +3 -0
- package/dist/expressions/fold.d.ts +7 -0
- package/dist/expressions/index.cjs +1754 -233
- package/dist/expressions/index.cjs.map +1 -1
- package/dist/expressions/index.d.ts +2 -0
- package/dist/expressions/index.js +1765 -234
- package/dist/expressions/index.js.map +1 -1
- package/dist/expressions/types.d.ts +45 -26
- package/dist/expressions/utils.d.ts +19 -1
- package/dist/index.cjs +2429 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2769 -682
- package/dist/index.js.map +1 -1
- package/dist/performance/index.cjs +6 -4
- package/dist/performance/index.cjs.map +1 -1
- package/dist/performance/index.js +6 -4
- package/dist/performance/index.js.map +1 -1
- package/dist/pipeline/index.cjs +6 -4
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.js +6 -4
- package/dist/pipeline/index.js.map +1 -1
- package/dist/plugins/index.cjs +2323 -316
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +2328 -311
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/query/QueryOptionsCollection.d.ts +38 -10
- package/dist/plugins/query/describeFilter.d.ts +83 -0
- package/dist/plugins/query/explain.d.ts +71 -9
- package/dist/plugins/query/index.d.ts +1 -0
- package/dist/plugins/query/join.d.ts +4 -1
- package/dist/plugins/query/types.d.ts +36 -4
- package/dist/plugins/resultShape.d.ts +35 -0
- package/dist/schema/PropertyInfo.d.ts +0 -1
- package/dist/schema/index.cjs +7 -14
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.js +7 -14
- package/dist/schema/index.js.map +1 -1
- package/dist/transfer/ChunkEncoder.d.ts +60 -0
- package/dist/transfer/decoder.d.ts +29 -0
- package/dist/transfer/fillers.d.ts +36 -0
- package/dist/transfer/index.cjs +873 -0
- package/dist/transfer/index.cjs.map +1 -0
- package/dist/transfer/index.d.ts +47 -0
- package/dist/transfer/index.js +872 -0
- package/dist/transfer/index.js.map +1 -0
- package/dist/transfer/plan.d.ts +94 -0
- package/dist/transfer/types.d.ts +138 -0
- package/dist/utilities/index.cjs +242 -49
- package/dist/utilities/index.cjs.map +1 -1
- package/dist/utilities/index.js +242 -49
- package/dist/utilities/index.js.map +1 -1
- package/package.json +9 -1
|
@@ -9,18 +9,11 @@ export declare class QueryOptionsCollection<T> {
|
|
|
9
9
|
private nextExecutionReason;
|
|
10
10
|
private nextIndex;
|
|
11
11
|
private enumeratedItems;
|
|
12
|
+
private dirty;
|
|
13
|
+
/** The collection a `splitAt`/`split` half came from. A capability report belongs to it. */
|
|
14
|
+
private origin;
|
|
12
15
|
/** Cuts over to memory execution, keeping the first cause. See `MemoryExecutionReason`. */
|
|
13
16
|
private cutOverToMemory;
|
|
14
|
-
/**
|
|
15
|
-
* True when `split()` or `splitAt()` produced this collection.
|
|
16
|
-
*
|
|
17
|
-
* Those rebuild each half by re-adding its options, which re-derives execution targets
|
|
18
|
-
* without the options that caused them — a post-join filter alone in the memory half
|
|
19
|
-
* derives back to `"database"`. Anything reading `target` as a report of where work runs
|
|
20
|
-
* has to reject a derived collection; see `explainQuery`.
|
|
21
|
-
*/
|
|
22
|
-
private derived;
|
|
23
|
-
get isDerived(): boolean;
|
|
24
17
|
get items(): Map<keyof QueryOptionValueMap<unknown>, QueryCollectionItem<any, any>[]>;
|
|
25
18
|
get isEmpty(): boolean;
|
|
26
19
|
static EMPTY<R>(): QueryOptionsCollection<R>;
|
|
@@ -47,6 +40,41 @@ export declare class QueryOptionsCollection<T> {
|
|
|
47
40
|
* runs it over the first execution's scalar result.
|
|
48
41
|
*/
|
|
49
42
|
snapshot(): () => void;
|
|
43
|
+
/** Takes an item as it stands — same object, same index, same target and reason. */
|
|
44
|
+
private adopt;
|
|
45
|
+
/**
|
|
46
|
+
* A plugin reporting that its engine cannot express one option.
|
|
47
|
+
*
|
|
48
|
+
* Core marks the rest of the database phase `not-reached`, because the database has to stop
|
|
49
|
+
* there — a window applied in front of a filter that was not applied returns the wrong rows.
|
|
50
|
+
* Passing the cascade through core is what makes it impossible for a plugin to mark a
|
|
51
|
+
* non-contiguous cut.
|
|
52
|
+
*
|
|
53
|
+
* A report names a culprit and never un-names one, so reports commute.
|
|
54
|
+
*
|
|
55
|
+
* The option is not moved to the memory arm. It stays where it was planned, which is what keeps
|
|
56
|
+
* a redirect distinguishable from something core sent to memory in the first place.
|
|
57
|
+
*/
|
|
58
|
+
reportMissingCapability(item: QueryCollectionItem<any, any>): void;
|
|
59
|
+
/**
|
|
60
|
+
* A plugin reporting that its engine would answer one option differently from JavaScript.
|
|
61
|
+
*
|
|
62
|
+
* Same cascade as `reportMissingCapability`, and a separate reason because the caller can act on
|
|
63
|
+
* one and not the other. See `DatabaseExecutionReason`.
|
|
64
|
+
*/
|
|
65
|
+
reportEngineDivergence(item: QueryCollectionItem<any, any>): void;
|
|
66
|
+
private report;
|
|
67
|
+
/**
|
|
68
|
+
* Forgets what any previous dispatch reported.
|
|
69
|
+
*
|
|
70
|
+
* Capability is answered per dispatch, so a report is only an answer for the execution that
|
|
71
|
+
* produced it. The items are shared with any snapshot, so a report mutated in place otherwise
|
|
72
|
+
* survives a restore and a second terminal on the same queryable replays options the plugin
|
|
73
|
+
* did run — a `skip` applied twice, over rows already windowed.
|
|
74
|
+
*/
|
|
75
|
+
forgetReports(): void;
|
|
76
|
+
/** The options the database did not run, in the order they were written. */
|
|
77
|
+
notExecuted(): QueryCollectionItem<any, any>[];
|
|
50
78
|
split(): {
|
|
51
79
|
memory: QueryOptionsCollection<T>;
|
|
52
80
|
database: QueryOptionsCollection<T>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Expression } from "../../expressions";
|
|
2
|
+
/**
|
|
3
|
+
* Saying what a backend was asked to do, with the values pulled out.
|
|
4
|
+
*
|
|
5
|
+
* `explain` already carries `{ text, parameters }` per executed query, and the SQL plugins fill
|
|
6
|
+
* both in — a statement with `?` and the values bound to it. Every other backend reported a
|
|
7
|
+
* placeholder: Dexie said `filter(<predicate>)`, which names nothing, and a key-value store said
|
|
8
|
+
* only that it scanned. The predicate was the one thing a reader wanted and the one thing missing.
|
|
9
|
+
*
|
|
10
|
+
* Two renderings live here, and neither knows about a specific engine:
|
|
11
|
+
*
|
|
12
|
+
* - `describeFilterAsJs` — the predicate as JavaScript, for a backend with no query language of
|
|
13
|
+
* its own. It reads like what the caller wrote, which is what they are looking for.
|
|
14
|
+
* - `parameteriseDocument` — for a backend whose query IS a document. Values become `?` and are
|
|
15
|
+
* collected in order, so a Mango selector and an MQL filter both come out in their own shape
|
|
16
|
+
* with the values listed beside them.
|
|
17
|
+
*
|
|
18
|
+
* Pulling values out is not decoration. It is what makes two runs of one query comparable, and
|
|
19
|
+
* what keeps a value out of the text when that text is logged.
|
|
20
|
+
*/
|
|
21
|
+
export type ParameterisedQuery = {
|
|
22
|
+
/** The query in its own language, with each value replaced by `?`. */
|
|
23
|
+
text: string;
|
|
24
|
+
/** The values, in the order their placeholders appear. */
|
|
25
|
+
parameters: unknown[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* The predicate as JavaScript, with every value replaced by `?`.
|
|
29
|
+
*
|
|
30
|
+
* Rendered from the parsed tree rather than from the function's source. The tree is what the
|
|
31
|
+
* backend was actually given, so this cannot drift from what ran; and a value reaching the tree
|
|
32
|
+
* as a literal is indistinguishable from one arriving through a params object, which is what
|
|
33
|
+
* makes both come out as `?` the way SQL treats them.
|
|
34
|
+
*/
|
|
35
|
+
export declare const describeFilterAsJs: (expression: Expression) => ParameterisedQuery;
|
|
36
|
+
/**
|
|
37
|
+
* Marks a value inside a query document so it is replaced by `?` rather than printed.
|
|
38
|
+
*
|
|
39
|
+
* A document language carries its values inline, so there is nothing in the shape itself to say
|
|
40
|
+
* which parts are operators and which are data. A dialect wraps the data as it builds the
|
|
41
|
+
* document, and `parameteriseDocument` reads the wrapper.
|
|
42
|
+
*/
|
|
43
|
+
declare const PARAMETER: unique symbol;
|
|
44
|
+
export type ParameterHolder = {
|
|
45
|
+
readonly [PARAMETER]: unknown;
|
|
46
|
+
};
|
|
47
|
+
export declare const parameter: (value: unknown) => ParameterHolder;
|
|
48
|
+
/**
|
|
49
|
+
* Renders a query DOCUMENT with its values replaced by `?`.
|
|
50
|
+
*
|
|
51
|
+
* Language-agnostic on purpose: an MQL filter and a Mango selector are both plain objects, and so
|
|
52
|
+
* is whatever a future document store wants reported. The dialect decides the shape; this only
|
|
53
|
+
* decides how it is written down.
|
|
54
|
+
*
|
|
55
|
+
* A value not wrapped by `parameter` is structural — an operator name, a field path, a nesting
|
|
56
|
+
* level — and is printed as it is. That is the whole distinction, and it has to be made where the
|
|
57
|
+
* document is built, because by the time it is an object the two are the same kind of thing.
|
|
58
|
+
*/
|
|
59
|
+
export declare const parameteriseDocument: (document: unknown) => ParameterisedQuery;
|
|
60
|
+
/**
|
|
61
|
+
* Every filter on a query, as one description.
|
|
62
|
+
*
|
|
63
|
+
* Filters accumulate — `.where(a).where(b)` is `a && b` — so they are reported as one predicate
|
|
64
|
+
* rather than several, which is how the caller thinks of them and how a SQL plugin renders them
|
|
65
|
+
* into one `WHERE`. Parameters run left to right across the whole thing, matching the text.
|
|
66
|
+
*
|
|
67
|
+
* A filter that could not be parsed falls back to its source. Mixing the two is deliberate: one
|
|
68
|
+
* unparsable filter does not make the others unreadable, and seeing which one it was is the
|
|
69
|
+
* point.
|
|
70
|
+
*/
|
|
71
|
+
export declare const describeFilters: (filters: readonly {
|
|
72
|
+
expression: Expression;
|
|
73
|
+
filter?: unknown;
|
|
74
|
+
}[]) => ParameterisedQuery;
|
|
75
|
+
/**
|
|
76
|
+
* A predicate core could not parse, shown as the caller wrote it.
|
|
77
|
+
*
|
|
78
|
+
* This is the case where the source matters most: an unparsable filter is why the query did not
|
|
79
|
+
* push down, and the reason codes say that it happened without showing what it was. There are no
|
|
80
|
+
* parameters — nothing was extracted, because nothing was understood.
|
|
81
|
+
*/
|
|
82
|
+
export declare const describeUnparsableFilter: (filter: unknown, reason?: string) => ParameterisedQuery;
|
|
83
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DatabaseExecutionReason, MemoryExecutionReason, QueryOptionName } from "./types";
|
|
2
2
|
import { QueryOptionsCollection } from "./QueryOptionsCollection";
|
|
3
3
|
/**
|
|
4
4
|
* One sentence per reason code, written for someone meeting pushdown for the first time.
|
|
@@ -24,25 +24,68 @@ export type ExplainedOption = {
|
|
|
24
24
|
detail?: Record<string, unknown>;
|
|
25
25
|
};
|
|
26
26
|
export declare const EXECUTED_QUERIES_UNSUPPORTED = "This plugin did not report what it executed. It may not support explain.";
|
|
27
|
+
/**
|
|
28
|
+
* Why an option planned for the database did not run there. `executed` has no sentence: it needs no
|
|
29
|
+
* explaining, and a step made of executed options is a database step like any other.
|
|
30
|
+
*/
|
|
31
|
+
export declare const DATABASE_EXECUTION_EXPLANATIONS: Record<Exclude<DatabaseExecutionReason, "executed">, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Where a step ran.
|
|
34
|
+
*
|
|
35
|
+
* A database step names WHICH database, because a cross-plugin join reads from more than one — and a
|
|
36
|
+
* name alone does not say whether the second was PostgreSQL or PouchDB, which is the difference
|
|
37
|
+
* between a statement a reader recognises and one they cannot place.
|
|
38
|
+
*/
|
|
39
|
+
export type ExecutedIn = {
|
|
40
|
+
kind: "database";
|
|
41
|
+
database: string;
|
|
42
|
+
plugin: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "memory";
|
|
45
|
+
};
|
|
46
|
+
/** Why a step is not in the database. `executed` never appears: those steps ARE in the database. */
|
|
47
|
+
export type StepReason = MemoryExecutionReason | Exclude<DatabaseExecutionReason, "executed">;
|
|
48
|
+
/**
|
|
49
|
+
* One run of options in one place.
|
|
50
|
+
*
|
|
51
|
+
* A union, so a memory step cannot carry statements it could not have run and a database step cannot
|
|
52
|
+
* carry a reason for not being in the database.
|
|
53
|
+
*/
|
|
27
54
|
export type ExecutionStep = {
|
|
28
55
|
step: number;
|
|
29
56
|
of: number;
|
|
30
|
-
executedIn:
|
|
31
|
-
|
|
57
|
+
executedIn: Extract<ExecutedIn, {
|
|
58
|
+
kind: "database";
|
|
59
|
+
}>;
|
|
32
60
|
options: ExplainedOption[];
|
|
33
|
-
/**
|
|
34
|
-
executedQueries
|
|
35
|
-
/** Set
|
|
61
|
+
/** What the plugin reported running. Empty when it reported nothing. */
|
|
62
|
+
executedQueries: ExecutedQuery[];
|
|
63
|
+
/** Set instead, when this plugin does not report what it executed. */
|
|
36
64
|
executedQueriesUnsupported?: string;
|
|
37
|
-
|
|
38
|
-
|
|
65
|
+
} | {
|
|
66
|
+
step: number;
|
|
67
|
+
of: number;
|
|
68
|
+
executedIn: Extract<ExecutedIn, {
|
|
69
|
+
kind: "memory";
|
|
70
|
+
}>;
|
|
71
|
+
options: ExplainedOption[];
|
|
72
|
+
reason?: StepReason;
|
|
39
73
|
explanation?: string;
|
|
40
74
|
};
|
|
75
|
+
export type DatabaseStep = Extract<ExecutionStep, {
|
|
76
|
+
executedQueries: ExecutedQuery[];
|
|
77
|
+
}>;
|
|
78
|
+
export type MemoryStep = Exclude<ExecutionStep, DatabaseStep>;
|
|
79
|
+
/**
|
|
80
|
+
* TypeScript does not narrow a union from a discriminant nested inside a property, so the two kinds
|
|
81
|
+
* of step need a guard rather than an inline check.
|
|
82
|
+
*/
|
|
83
|
+
export declare const isDatabaseStep: (step: ExecutionStep) => step is DatabaseStep;
|
|
41
84
|
export type QueryExplanationSummary = {
|
|
42
85
|
database: number;
|
|
43
86
|
memory: number;
|
|
44
87
|
/** Deduped, in first-seen order. Empty when the whole query pushed down. */
|
|
45
|
-
reasons:
|
|
88
|
+
reasons: StepReason[];
|
|
46
89
|
explanation: string;
|
|
47
90
|
};
|
|
48
91
|
export type QueryExplanation = {
|
|
@@ -80,3 +123,22 @@ export declare const explainQuery: (options: QueryOptionsCollection<any>, contex
|
|
|
80
123
|
* original — nothing mutates them, and copying deeper would only look safer than it is.
|
|
81
124
|
*/
|
|
82
125
|
export declare const withExecutedQueries: (explanation: QueryExplanation, executedQueries: ExecutedQuery[]) => QueryExplanation;
|
|
126
|
+
/**
|
|
127
|
+
* Adds the step for a cross-plugin join's inner side.
|
|
128
|
+
*
|
|
129
|
+
* Appended by the executor rather than derived from the options, because the inner side's options
|
|
130
|
+
* live on the join, in its own collection, and were never part of this query's chain. It goes before
|
|
131
|
+
* the memory steps that consume it — the join cannot run until both sides are read.
|
|
132
|
+
*/
|
|
133
|
+
/**
|
|
134
|
+
* Every statement the query ran, across every database it touched, in execution order.
|
|
135
|
+
*
|
|
136
|
+
* A step is a place, so the statements live on the steps — this is for a caller that wants them all
|
|
137
|
+
* without caring which plugin ran which.
|
|
138
|
+
*/
|
|
139
|
+
export declare const executedQueriesOf: (explanation: QueryExplanation) => ExecutedQuery[];
|
|
140
|
+
export declare const withInnerSide: (explanation: QueryExplanation, innerSide: {
|
|
141
|
+
database: string;
|
|
142
|
+
plugin: string;
|
|
143
|
+
executedQueries: ExecutedQuery[];
|
|
144
|
+
}) => QueryExplanation;
|
|
@@ -5,6 +5,7 @@ import type { DbPluginQueryEvent } from "../types";
|
|
|
5
5
|
import type { ITranslatedValue } from "../translators/types";
|
|
6
6
|
import { QueryOptionsCollection } from "./QueryOptionsCollection";
|
|
7
7
|
import { QueryOptionValueMap } from "./types";
|
|
8
|
+
import { ExecutedQuery } from "./explain";
|
|
8
9
|
export type JoinKind = "inner" | "left";
|
|
9
10
|
/**
|
|
10
11
|
* One side's join key, as a property path plus the resolved property.
|
|
@@ -165,7 +166,9 @@ export declare const loadJoinInnerSide: <TRoot extends {}, TShape>(event: DbPlug
|
|
|
165
166
|
* before anything else — so it is optional, and its absence costs a wider inner read rather
|
|
166
167
|
* than a wrong one.
|
|
167
168
|
*/
|
|
168
|
-
outerKeys?: ReadonlySet<unknown> | null
|
|
169
|
+
outerKeys?: ReadonlySet<unknown> | null,
|
|
170
|
+
/** Where the inner read reports what it executed. Defaults to the outer read's own list. */
|
|
171
|
+
innerExecutedQueries?: ExecutedQuery[]) => void;
|
|
169
172
|
/**
|
|
170
173
|
* Interprets a join by running TWO ordinary queries through the plugin's own read path.
|
|
171
174
|
*
|
|
@@ -27,13 +27,45 @@ export type QueryOptionName = keyof QueryOptionValueMap<unknown>;
|
|
|
27
27
|
* never returns to `"database"`, so the code recorded is the FIRST cause and it stays on every
|
|
28
28
|
* option after it. Reporting a later one would name a symptom of this one.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
/** Why core planned an option for memory, decided when the option is added. */
|
|
31
|
+
export type MemoryExecutionReason = "not-parsable" | "unmapped-property" | "renamed-property" | "map-rename" | "after-nearest" | "after-join" | "cross-plugin-join" | "predicate-error" | "after-window";
|
|
32
|
+
/**
|
|
33
|
+
* What became of an option planned for the database.
|
|
34
|
+
*
|
|
35
|
+
* `missing-capability` and `engine-divergence` are the only values a plugin writes, and the only
|
|
36
|
+
* ones core cannot derive: an engine's capabilities are not knowable from here. SQLite's `REGEXP`
|
|
37
|
+
* exists if the host registered the function and not otherwise, so two instances in one process can
|
|
38
|
+
* differ.
|
|
39
|
+
*
|
|
40
|
+
* They are separate because a developer can act on one and not the other: no way to say it at all,
|
|
41
|
+
* versus an engine that would answer, and answer differently from JavaScript.
|
|
42
|
+
*
|
|
43
|
+
* `not-reached` is the rest of the database phase after either. The database stops there rather than
|
|
44
|
+
* carrying on: a window applied in front of a filter that was not applied returns the wrong rows.
|
|
45
|
+
* Core writes it, so a plugin cannot mark a cascade it does not own.
|
|
46
|
+
*/
|
|
47
|
+
export type DatabaseExecutionReason = "executed" | "missing-capability" | "engine-divergence" | "not-reached";
|
|
48
|
+
/**
|
|
49
|
+
* One option, and where it runs.
|
|
50
|
+
*
|
|
51
|
+
* `target` narrows what `reason` can say, so an option cannot carry a reason that does not belong to
|
|
52
|
+
* the half it was planned for. An option is never moved between arms — the database arm records what
|
|
53
|
+
* became of it, which is what makes a redirect readable:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* option.target === "database" && option.reason === "missing-capability"
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
31
59
|
export type QueryOption<T, K extends QueryOptionName> = {
|
|
32
60
|
name: QueryOptionName;
|
|
33
61
|
value: QueryOptionValueMap<T>[K];
|
|
34
|
-
target:
|
|
35
|
-
|
|
36
|
-
|
|
62
|
+
target: "database";
|
|
63
|
+
reason: DatabaseExecutionReason;
|
|
64
|
+
} | {
|
|
65
|
+
name: QueryOptionName;
|
|
66
|
+
value: QueryOptionValueMap<T>[K];
|
|
67
|
+
target: "memory";
|
|
68
|
+
reason: MemoryExecutionReason;
|
|
37
69
|
};
|
|
38
70
|
export type QueryOptionValueMap<T extends {}> = {
|
|
39
71
|
skip: number;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PropertyInfo } from '../schema/PropertyInfo';
|
|
2
|
+
import type { QueryField } from './query/types';
|
|
3
|
+
/**
|
|
4
|
+
* What a statement or command RETURNS, described before it runs.
|
|
5
|
+
*
|
|
6
|
+
* A plugin's builder knows this and nothing else knows it: the shape of a result comes from the
|
|
7
|
+
* projection, the join aliases, or the `RETURNING` list, none of which survive into the SQL as
|
|
8
|
+
* anything a reader could recover. So the builder states it, once, beside the statement it built.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately says nothing about what anyone does with the result. It is a description, not an
|
|
11
|
+
* instruction — the same description serves a driver that transfers rows across a worker
|
|
12
|
+
* boundary, one that hands them straight back, and one that only wants to know the column order.
|
|
13
|
+
* A consumer that needs more turns this into whatever it needs: `buildTransferPlan` in
|
|
14
|
+
* `@routier/core/transfer` is one such consumer, and it is not privileged.
|
|
15
|
+
*/
|
|
16
|
+
export type ResultColumn = {
|
|
17
|
+
/** Exact name the engine will return, including any projection or join alias. */
|
|
18
|
+
readonly name: string;
|
|
19
|
+
/**
|
|
20
|
+
* The schema property behind the column, or `null`.
|
|
21
|
+
*
|
|
22
|
+
* `null` for an expression — a computed value, an aggregate, anything with no declared type
|
|
23
|
+
* to reason from. A consumer that wants to treat the value specially needs the property; one
|
|
24
|
+
* that only wants names does not.
|
|
25
|
+
*/
|
|
26
|
+
readonly property: PropertyInfo<any> | null;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The columns a `map` projection selects.
|
|
30
|
+
*
|
|
31
|
+
* Named by `sourceName`, which is what the statement actually emits; the rename to
|
|
32
|
+
* `destinationName` happens in the translator, after the rows come back. A field with no
|
|
33
|
+
* `property` is an expression.
|
|
34
|
+
*/
|
|
35
|
+
export declare const mappedResultColumns: (fields: readonly QueryField[]) => ResultColumn[];
|
package/dist/schema/index.cjs
CHANGED
|
@@ -618,12 +618,14 @@ const isLogLevel = (value)=>typeof value === 'string' && LOG_LEVELS.includes(val
|
|
|
618
618
|
const debug = process.env.DEBUG;
|
|
619
619
|
if (debug === 'routier' || debug === '*') return 'debug';
|
|
620
620
|
const env = "production"?.toLowerCase();
|
|
621
|
-
// `test` is deliberately absent. It used to be here, which meant no test suite anywhere
|
|
622
|
-
// could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test
|
|
623
|
-
// needs the output.
|
|
624
621
|
if (env === 'dev' || env === 'development') return 'debug';
|
|
625
622
|
}
|
|
626
|
-
|
|
623
|
+
// Warnings are on unless something turns them off.
|
|
624
|
+
//
|
|
625
|
+
// Routier warns when a query returns correct rows a slower way than it could, or when a filter
|
|
626
|
+
// compares types that can never match. Both are the caller's to act on, and a default of
|
|
627
|
+
// `silent` meant the only people who ever saw them were the ones who already knew to look.
|
|
628
|
+
return 'warn';
|
|
627
629
|
};
|
|
628
630
|
let level = resolveLevel();
|
|
629
631
|
let rank = RANK[level];
|
|
@@ -1779,12 +1781,6 @@ class SchemaComputed extends SchemaBase {
|
|
|
1779
1781
|
;// CONCATENATED MODULE: ./src/schema/PropertyInfo.ts
|
|
1780
1782
|
|
|
1781
1783
|
|
|
1782
|
-
const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
1783
|
-
types/* .SchemaTypes.Boolean */.L.Boolean,
|
|
1784
|
-
types/* .SchemaTypes.Date */.L.Date,
|
|
1785
|
-
types/* .SchemaTypes.Number */.L.Number,
|
|
1786
|
-
types/* .SchemaTypes.String */.L.String
|
|
1787
|
-
]);
|
|
1788
1784
|
/**
|
|
1789
1785
|
* Represents metadata and utilities for a property in a schema, including its type, name, parent, children, and serialization details.
|
|
1790
1786
|
*/ class PropertyInfo {
|
|
@@ -1904,9 +1900,6 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
|
1904
1900
|
get isRenamed() {
|
|
1905
1901
|
return !!this.from;
|
|
1906
1902
|
}
|
|
1907
|
-
get supportsDeserialization() {
|
|
1908
|
-
return this.valueDeserializer != null || SUPPORTED_DESERIALIZATION_TYPES.has(this.type);
|
|
1909
|
-
}
|
|
1910
1903
|
_getPropertyChain() {
|
|
1911
1904
|
if (this._propertyChainCache) {
|
|
1912
1905
|
return this._propertyChainCache;
|
|
@@ -2159,7 +2152,7 @@ const SUPPORTED_DESERIALIZATION_TYPES = new Set([
|
|
|
2159
2152
|
if (this.type === types/* .SchemaTypes.Boolean */.L.Boolean) {
|
|
2160
2153
|
return Boolean(value);
|
|
2161
2154
|
}
|
|
2162
|
-
|
|
2155
|
+
return value;
|
|
2163
2156
|
}
|
|
2164
2157
|
}
|
|
2165
2158
|
|