@hypequery/datasets 0.23.1 → 0.25.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 +14 -0
- package/dist/aggregations.d.ts +3 -0
- package/dist/aggregations.d.ts.map +1 -1
- package/dist/aggregations.js +6 -0
- package/dist/cache/definition-identity.d.ts +9 -6
- package/dist/cache/definition-identity.d.ts.map +1 -1
- package/dist/cache/definition-identity.js +14 -8
- package/dist/cache/protocol-cache-keys.d.ts.map +1 -1
- package/dist/cache/protocol-cache-keys.js +29 -6
- package/dist/cache/query-signature.d.ts.map +1 -1
- package/dist/cache/query-signature.js +12 -1
- package/dist/catalog.d.ts +7 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +5 -2
- package/dist/client-contract/query-schema.d.ts +19 -0
- package/dist/client-contract/query-schema.d.ts.map +1 -0
- package/dist/client-contract/query-schema.js +85 -0
- package/dist/constants.d.ts +5 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -6
- package/dist/contract.d.ts +5 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +6 -3
- package/dist/dataset-compilation.d.ts +2 -0
- package/dist/dataset-compilation.d.ts.map +1 -1
- package/dist/dataset-sql-dialect.d.ts +119 -0
- package/dist/dataset-sql-dialect.d.ts.map +1 -1
- package/dist/dataset.d.ts +4 -2
- package/dist/dataset.d.ts.map +1 -1
- package/dist/dataset.js +23 -31
- package/dist/in-memory-backend.d.ts.map +1 -1
- package/dist/in-memory-backend.js +2 -0
- package/dist/index.d.ts +49 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -6
- package/dist/internal.d.ts +5 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +5 -1
- package/dist/measure.d.ts +9 -1
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +9 -1
- package/dist/metric-query-engine.d.ts +0 -1
- package/dist/metric-query-engine.d.ts.map +1 -1
- package/dist/metric-query-engine.js +11 -3
- package/dist/protocol-adapter.d.ts.map +1 -1
- package/dist/protocol-adapter.js +2 -3
- package/dist/protocol-deployment-adapter.d.ts.map +1 -1
- package/dist/protocol-deployment-adapter.js +7 -1
- package/dist/protocol-rehydrate.d.ts.map +1 -1
- package/dist/protocol-rehydrate.js +1 -0
- package/dist/protocol-schema-adapter.d.ts +7 -7
- package/dist/protocol-schema-adapter.d.ts.map +1 -1
- package/dist/protocol-schema-adapter.js +12 -245
- package/dist/query-builder-protocol.d.ts +34 -1
- package/dist/query-builder-protocol.d.ts.map +1 -1
- package/dist/query-planner.d.ts +14 -5
- package/dist/query-planner.d.ts.map +1 -1
- package/dist/query-planner.js +53 -34
- package/dist/relationship-check.d.ts.map +1 -1
- package/dist/relationship-check.js +8 -8
- package/dist/schemas.d.ts +17 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +16 -0
- package/dist/semantic-planner.d.ts.map +1 -1
- package/dist/semantic-planner.js +49 -13
- package/dist/semantic-query-schema.d.ts +8 -1
- package/dist/semantic-query-schema.d.ts.map +1 -1
- package/dist/semantic-query-schema.js +18 -12
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +4 -3
- package/dist/types.d.ts +105 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/aggregate-state-functions.d.ts +24 -0
- package/dist/utils/aggregate-state-functions.d.ts.map +1 -0
- package/dist/utils/aggregate-state-functions.js +60 -0
- package/dist/utils/approximate-measures.d.ts +3 -1
- package/dist/utils/approximate-measures.d.ts.map +1 -1
- package/dist/utils/approximate-measures.js +8 -2
- package/dist/utils/base-measure-definition.d.ts +16 -0
- package/dist/utils/base-measure-definition.d.ts.map +1 -1
- package/dist/utils/base-measure-definition.js +31 -0
- package/dist/utils/build-dataset-query-builder.d.ts +1 -1
- package/dist/utils/build-dataset-query-builder.d.ts.map +1 -1
- package/dist/utils/build-dataset-query-builder.js +26 -21
- package/dist/utils/by-name.d.ts +8 -0
- package/dist/utils/by-name.d.ts.map +1 -0
- package/dist/utils/by-name.js +44 -0
- package/dist/utils/calendar-shift-sql.d.ts +5 -4
- package/dist/utils/calendar-shift-sql.d.ts.map +1 -1
- package/dist/utils/calendar-shift-sql.js +8 -8
- package/dist/utils/clickhouse-dataset-sql-dialect.d.ts +2 -2
- package/dist/utils/clickhouse-dataset-sql-dialect.d.ts.map +1 -1
- package/dist/utils/clickhouse-dataset-sql-dialect.js +143 -1
- package/dist/utils/compile-dataset-query.d.ts +1 -1
- package/dist/utils/compile-dataset-query.d.ts.map +1 -1
- package/dist/utils/compile-dataset-query.js +22 -8
- package/dist/utils/composite-time-measure-sql.d.ts +3 -5
- package/dist/utils/composite-time-measure-sql.d.ts.map +1 -1
- package/dist/utils/composite-time-measure-sql.js +15 -16
- package/dist/utils/count-aggregations.d.ts +4 -0
- package/dist/utils/count-aggregations.d.ts.map +1 -0
- package/dist/utils/count-aggregations.js +6 -0
- package/dist/utils/dataset-definition-validation.d.ts +1 -1
- package/dist/utils/dataset-definition-validation.d.ts.map +1 -1
- package/dist/utils/dataset-definition-validation.js +55 -26
- package/dist/utils/dataset-derived-query.d.ts +2 -4
- package/dist/utils/dataset-derived-query.d.ts.map +1 -1
- package/dist/utils/dataset-derived-query.js +11 -14
- package/dist/utils/dataset-having.d.ts +5 -7
- package/dist/utils/dataset-having.d.ts.map +1 -1
- package/dist/utils/dataset-having.js +9 -12
- package/dist/utils/dataset-normalization.d.ts.map +1 -1
- package/dist/utils/dataset-normalization.js +1 -0
- package/dist/utils/dataset-query-validation.d.ts +1 -1
- package/dist/utils/dataset-query-validation.d.ts.map +1 -1
- package/dist/utils/dataset-query-validation.js +19 -2
- package/dist/utils/dataset-source.d.ts +42 -0
- package/dist/utils/dataset-source.d.ts.map +1 -0
- package/dist/utils/dataset-source.js +59 -0
- package/dist/utils/dataset-sql-dialect.d.ts +13 -2
- package/dist/utils/dataset-sql-dialect.d.ts.map +1 -1
- package/dist/utils/dataset-sql-dialect.js +74 -1
- package/dist/utils/dataset-time-keys.d.ts +32 -0
- package/dist/utils/dataset-time-keys.d.ts.map +1 -0
- package/dist/utils/dataset-time-keys.js +55 -0
- package/dist/utils/dataset-validation.d.ts.map +1 -1
- package/dist/utils/dataset-validation.js +7 -0
- package/dist/utils/deployable-formulas.d.ts +33 -0
- package/dist/utils/deployable-formulas.d.ts.map +1 -0
- package/dist/utils/deployable-formulas.js +102 -0
- package/dist/utils/derived-cte-validation.d.ts +5 -0
- package/dist/utils/derived-cte-validation.d.ts.map +1 -1
- package/dist/utils/derived-cte-validation.js +77 -8
- package/dist/utils/derived-measure-sql.d.ts +10 -2
- package/dist/utils/derived-measure-sql.d.ts.map +1 -1
- package/dist/utils/derived-measure-sql.js +23 -43
- package/dist/utils/enforced-constraints.d.ts +14 -0
- package/dist/utils/enforced-constraints.d.ts.map +1 -0
- package/dist/utils/enforced-constraints.js +57 -0
- package/dist/utils/filter-field-type.d.ts +14 -0
- package/dist/utils/filter-field-type.d.ts.map +1 -0
- package/dist/utils/filter-field-type.js +21 -0
- package/dist/utils/filtered-aggregation-sql.d.ts +2 -1
- package/dist/utils/filtered-aggregation-sql.d.ts.map +1 -1
- package/dist/utils/filtered-aggregation-sql.js +18 -35
- package/dist/utils/groupable.d.ts +7 -0
- package/dist/utils/groupable.d.ts.map +1 -0
- package/dist/utils/groupable.js +8 -0
- package/dist/utils/metric-derived-query.d.ts +2 -4
- package/dist/utils/metric-derived-query.d.ts.map +1 -1
- package/dist/utils/metric-derived-query.js +58 -51
- package/dist/utils/metric-query-builder.d.ts +1 -1
- package/dist/utils/metric-query-builder.d.ts.map +1 -1
- package/dist/utils/metric-query-builder.js +22 -20
- package/dist/utils/metric-query-validation.d.ts.map +1 -1
- package/dist/utils/metric-query-validation.js +14 -1
- package/dist/utils/portable-aggregations.d.ts +1 -0
- package/dist/utils/portable-aggregations.d.ts.map +1 -1
- package/dist/utils/portable-aggregations.js +5 -0
- package/dist/utils/protocol-schema-conversion.d.ts +12 -0
- package/dist/utils/protocol-schema-conversion.d.ts.map +1 -0
- package/dist/utils/protocol-schema-conversion.js +61 -0
- package/dist/utils/query-field-references.d.ts +10 -0
- package/dist/utils/query-field-references.d.ts.map +1 -0
- package/dist/utils/query-field-references.js +38 -0
- package/dist/utils/query-timezone.d.ts +41 -3
- package/dist/utils/query-timezone.d.ts.map +1 -1
- package/dist/utils/query-timezone.js +76 -9
- package/dist/utils/raw-sql-dialect-check.d.ts +12 -0
- package/dist/utils/raw-sql-dialect-check.d.ts.map +1 -0
- package/dist/utils/raw-sql-dialect-check.js +37 -0
- package/dist/utils/relationship-builder-plan.d.ts +37 -18
- package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
- package/dist/utils/relationship-builder-plan.js +43 -28
- package/dist/utils/relationship-measure-sql.d.ts +14 -4
- package/dist/utils/relationship-measure-sql.d.ts.map +1 -1
- package/dist/utils/relationship-measure-sql.js +36 -10
- package/dist/utils/relationship-measures.d.ts.map +1 -1
- package/dist/utils/relationship-measures.js +3 -0
- package/dist/utils/relationship-validation.d.ts.map +1 -1
- package/dist/utils/relationship-validation.js +2 -0
- package/dist/utils/row-scope.d.ts +23 -0
- package/dist/utils/row-scope.d.ts.map +1 -0
- package/dist/utils/row-scope.js +26 -0
- package/dist/utils/scoped-dataset-source.d.ts +23 -0
- package/dist/utils/scoped-dataset-source.d.ts.map +1 -0
- package/dist/utils/scoped-dataset-source.js +34 -0
- package/dist/utils/semantic-tool.d.ts +2 -2
- package/dist/utils/semantic-tool.d.ts.map +1 -1
- package/dist/utils/semantic-tool.js +1 -1
- package/dist/utils/shift-measure-sql.d.ts +5 -4
- package/dist/utils/shift-measure-sql.d.ts.map +1 -1
- package/dist/utils/shift-measure-sql.js +25 -26
- package/dist/utils/shift-wall-time-sql.d.ts +2 -1
- package/dist/utils/shift-wall-time-sql.d.ts.map +1 -1
- package/dist/utils/shift-wall-time-sql.js +7 -7
- package/dist/utils/snapshot-execution-context.d.ts.map +1 -1
- package/dist/utils/snapshot-execution-context.js +3 -0
- package/dist/utils/statement-parameters.d.ts +58 -0
- package/dist/utils/statement-parameters.d.ts.map +1 -0
- package/dist/utils/statement-parameters.js +101 -0
- package/dist/utils/time-axis-calendar-guard.d.ts +2 -1
- package/dist/utils/time-axis-calendar-guard.d.ts.map +1 -1
- package/dist/utils/time-axis-calendar-guard.js +5 -7
- package/dist/utils/time-measure-axis-sql.d.ts +3 -2
- package/dist/utils/time-measure-axis-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-axis-sql.js +20 -22
- package/dist/utils/time-measure-context-sql.d.ts +3 -2
- package/dist/utils/time-measure-context-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-context-sql.js +11 -11
- package/dist/utils/time-measure-dataset-sql.d.ts +7 -5
- package/dist/utils/time-measure-dataset-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-dataset-sql.js +17 -12
- package/dist/utils/time-measure-leaf-sql.d.ts +3 -2
- package/dist/utils/time-measure-leaf-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-leaf-sql.js +19 -18
- package/dist/utils/time-measure-result-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-result-sql.js +10 -11
- package/dist/utils/time-measure-source-sql.d.ts +5 -2
- package/dist/utils/time-measure-source-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-source-sql.js +33 -23
- package/dist/utils/time-measure-values-sql.d.ts +4 -3
- package/dist/utils/time-measure-values-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-values-sql.js +26 -29
- package/dist/utils/timestamp-instants.d.ts +17 -0
- package/dist/utils/timestamp-instants.d.ts.map +1 -0
- package/dist/utils/timestamp-instants.js +34 -0
- package/dist/utils/timestamp-text.d.ts +12 -0
- package/dist/utils/timestamp-text.d.ts.map +1 -0
- package/dist/utils/timestamp-text.js +18 -0
- package/dist/utils/zod-json-schema.d.ts +8 -0
- package/dist/utils/zod-json-schema.d.ts.map +1 -0
- package/dist/utils/zod-json-schema.js +18 -0
- package/dist/utils/zod-schema-version.d.ts +19 -0
- package/dist/utils/zod-schema-version.d.ts.map +1 -0
- package/dist/utils/zod-schema-version.js +6 -0
- package/dist/utils/zod-v3-protocol-schema.d.ts +10 -0
- package/dist/utils/zod-v3-protocol-schema.d.ts.map +1 -0
- package/dist/utils/zod-v3-protocol-schema.js +164 -0
- package/dist/utils/zod-v4-protocol-schema.d.ts +12 -0
- package/dist/utils/zod-v4-protocol-schema.d.ts.map +1 -0
- package/dist/utils/zod-v4-protocol-schema.js +171 -0
- package/dist/validation.d.ts +7 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +42 -8
- package/package.json +21 -12
- package/dist/api.type-test.d.ts +0 -2
- package/dist/api.type-test.d.ts.map +0 -1
- package/dist/api.type-test.js +0 -251
- package/dist/utils/time-arithmetic-sql.d.ts +0 -4
- package/dist/utils/time-arithmetic-sql.d.ts.map +0 -1
- package/dist/utils/time-arithmetic-sql.js +0 -9
- package/dist/utils/window-aggregation-sql.d.ts +0 -5
- package/dist/utils/window-aggregation-sql.d.ts.map +0 -1
- package/dist/utils/window-aggregation-sql.js +0 -17
package/README.md
CHANGED
|
@@ -72,6 +72,9 @@ The same definition can become:
|
|
|
72
72
|
- an OpenAI, AI SDK, or MCP tool schema;
|
|
73
73
|
- a stable semantic contract for CI and deployment.
|
|
74
74
|
|
|
75
|
+
Schema builders and agent tools are imported from `@hypequery/datasets/schemas`.
|
|
76
|
+
(Their root-entry re-exports are deprecated and removed in 1.0.)
|
|
77
|
+
|
|
75
78
|
`buildCanonicalSemanticQuerySchemas()` compiles the same catalog into strict
|
|
76
79
|
dataset and metric Zod validators, JSON Schemas, and a deterministic manifest
|
|
77
80
|
hash. It accepts either live local Dataset definitions or an already-normalized
|
|
@@ -111,3 +114,14 @@ for module boundaries and verification requirements, and the
|
|
|
111
114
|
## License
|
|
112
115
|
|
|
113
116
|
Apache-2.0.
|
|
117
|
+
|
|
118
|
+
## Public client descriptor schemas
|
|
119
|
+
|
|
120
|
+
`buildClientContractQuerySchemas(contract)` validates an RFC 0018 signed client
|
|
121
|
+
contract and returns per-endpoint HTTP schemas plus the canonical dataset/metric
|
|
122
|
+
MCP schemas, JSON schemas and manifest hash. It accepts public descriptors without
|
|
123
|
+
constructing Dataset instances or loading project code. Filter values have their
|
|
124
|
+
advertised scalar/range/list types. Runtime validation additionally checks selected
|
|
125
|
+
fields, uniqueness, timezone membership and combined predicate limits; preserve it
|
|
126
|
+
when using the structural JSON schemas. Empty MCP target sets remain uncallable.
|
|
127
|
+
Existing catalog-based schema APIs keep their defaults.
|
package/dist/aggregations.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
import type { AggregationSpec } from './types.js';
|
|
18
|
+
import { type AggregateStateFunction } from './utils/aggregate-state-functions.js';
|
|
18
19
|
export declare function sum(field: string): AggregationSpec;
|
|
19
20
|
export declare function count(field: string): AggregationSpec;
|
|
20
21
|
export declare function countDistinct(field: string): AggregationSpec;
|
|
@@ -23,6 +24,8 @@ export declare function approxCountDistinct(field: string): AggregationSpec;
|
|
|
23
24
|
export declare function avg(field: string): AggregationSpec;
|
|
24
25
|
export declare function min(field: string): AggregationSpec;
|
|
25
26
|
export declare function max(field: string): AggregationSpec;
|
|
27
|
+
/** Finalize the aggregate states stored in `field` with `stateFunction`'s `-Merge` combinator. */
|
|
28
|
+
export declare function merge(stateFunction: AggregateStateFunction, field: string): AggregationSpec;
|
|
26
29
|
/** Approximate percentile of a numeric field at `level` in [0, 1]. */
|
|
27
30
|
export declare function percentile(field: string, level: number): AggregationSpec;
|
|
28
31
|
/** Median — sugar for `percentile(field, 0.5)`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAgC,KAAK,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAUjH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAE5D;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElE;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,kGAAkG;AAClG,wBAAgB,KAAK,CAAC,aAAa,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAG3F;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAGxE;AAED,mDAAmD;AACnD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,iCAAiC;AACjC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEvD"}
|
package/dist/aggregations.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
import { validatePercentileLevel } from './measure.js';
|
|
18
|
+
import { assertAggregateStateFunction } from './utils/aggregate-state-functions.js';
|
|
18
19
|
function createAggregation(aggregation, field) {
|
|
19
20
|
return {
|
|
20
21
|
__type: 'aggregation_spec',
|
|
@@ -44,6 +45,11 @@ export function min(field) {
|
|
|
44
45
|
export function max(field) {
|
|
45
46
|
return createAggregation('max', field);
|
|
46
47
|
}
|
|
48
|
+
/** Finalize the aggregate states stored in `field` with `stateFunction`'s `-Merge` combinator. */
|
|
49
|
+
export function merge(stateFunction, field) {
|
|
50
|
+
assertAggregateStateFunction(stateFunction, `merge(…, "${field}")`);
|
|
51
|
+
return { ...createAggregation('merge', field), stateFunction };
|
|
52
|
+
}
|
|
47
53
|
/** Approximate percentile of a numeric field at `level` in [0, 1]. */
|
|
48
54
|
export function percentile(field, level) {
|
|
49
55
|
validatePercentileLevel(level);
|
|
@@ -2,7 +2,8 @@ import type { AnyDatasetInstance } from '../types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* The local definition identity RFC 0009 leaves implementation-defined: a
|
|
4
4
|
* digest of every definition that could affect the rows of a query over
|
|
5
|
-
* `root`, plus the metric spec, cache scope, and
|
|
5
|
+
* `root`, plus the metric spec, cache scope, timezone, and alternate time axis
|
|
6
|
+
* when present.
|
|
6
7
|
*
|
|
7
8
|
* Throws when a definition holds a function it cannot describe safely; the
|
|
8
9
|
* caller then runs the query uncached.
|
|
@@ -15,12 +16,14 @@ export declare function localDefinitionIdentity(root: AnyDatasetInstance, extra?
|
|
|
15
16
|
metric?: unknown;
|
|
16
17
|
scope?: string;
|
|
17
18
|
timezone?: string;
|
|
19
|
+
timeKey?: string;
|
|
18
20
|
}): string;
|
|
19
21
|
/**
|
|
20
|
-
* Folds a cache scope
|
|
21
|
-
* identity.
|
|
22
|
-
* source, the timezone moves bucket boundaries
|
|
23
|
-
*
|
|
22
|
+
* Folds a cache scope, a non-default timezone and an alternate time axis into
|
|
23
|
+
* a deployed definition identity. Each changes the rows one release returns
|
|
24
|
+
* (`scope` picks the data source, the timezone moves bucket boundaries, the
|
|
25
|
+
* axis picks the column they bucket), so they must separate keys even when
|
|
26
|
+
* the definitions are identical.
|
|
24
27
|
*/
|
|
25
|
-
export declare function scopedDefinitionIdentity(identity: string, scope: string | undefined, timezone?: string): string;
|
|
28
|
+
export declare function scopedDefinitionIdentity(identity: string, scope: string | undefined, timezone?: string, timeKey?: string): string;
|
|
26
29
|
//# sourceMappingURL=definition-identity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-identity.d.ts","sourceRoot":"","sources":["../../src/cache/definition-identity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAC;AA8InE
|
|
1
|
+
{"version":3,"file":"definition-identity.d.ts","sourceRoot":"","sources":["../../src/cache/definition-identity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAC;AA8InE;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,kBAAkB,EACxB,KAAK,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACpF,MAAM,CAaR;AAMD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAMR"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { sha256 } from '@noble/hashes/sha2';
|
|
2
|
-
import { bytesToHex } from '@noble/hashes/utils';
|
|
1
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
2
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
3
3
|
import { stableStringify } from '../utils/canonical-json.js';
|
|
4
4
|
const LOCAL_DEFINITION_DOMAIN = 'hypequery.ts.local-definitions.v2\0';
|
|
5
5
|
/**
|
|
@@ -124,7 +124,8 @@ class DefinitionDescriber {
|
|
|
124
124
|
/**
|
|
125
125
|
* The local definition identity RFC 0009 leaves implementation-defined: a
|
|
126
126
|
* digest of every definition that could affect the rows of a query over
|
|
127
|
-
* `root`, plus the metric spec, cache scope, and
|
|
127
|
+
* `root`, plus the metric spec, cache scope, timezone, and alternate time axis
|
|
128
|
+
* when present.
|
|
128
129
|
*
|
|
129
130
|
* Throws when a definition holds a function it cannot describe safely; the
|
|
130
131
|
* caller then runs the query uncached.
|
|
@@ -142,6 +143,8 @@ export function localDefinitionIdentity(root, extra = {}) {
|
|
|
142
143
|
metric,
|
|
143
144
|
scope: extra.scope ?? null,
|
|
144
145
|
timezone: extra.timezone ?? null,
|
|
146
|
+
// Present only for an alternate axis, so default queries keep their keys.
|
|
147
|
+
...(extra.timeKey !== undefined ? { timeKey: extra.timeKey } : {}),
|
|
145
148
|
});
|
|
146
149
|
return bytesToHex(sha256(new TextEncoder().encode(LOCAL_DEFINITION_DOMAIN + description)));
|
|
147
150
|
}
|
|
@@ -149,16 +152,19 @@ function foldPartition(identity, domain, value) {
|
|
|
149
152
|
return bytesToHex(sha256(new TextEncoder().encode(`${domain}\0${identity}\0${value}`)));
|
|
150
153
|
}
|
|
151
154
|
/**
|
|
152
|
-
* Folds a cache scope
|
|
153
|
-
* identity.
|
|
154
|
-
* source, the timezone moves bucket boundaries
|
|
155
|
-
*
|
|
155
|
+
* Folds a cache scope, a non-default timezone and an alternate time axis into
|
|
156
|
+
* a deployed definition identity. Each changes the rows one release returns
|
|
157
|
+
* (`scope` picks the data source, the timezone moves bucket boundaries, the
|
|
158
|
+
* axis picks the column they bucket), so they must separate keys even when
|
|
159
|
+
* the definitions are identical.
|
|
156
160
|
*/
|
|
157
|
-
export function scopedDefinitionIdentity(identity, scope, timezone) {
|
|
161
|
+
export function scopedDefinitionIdentity(identity, scope, timezone, timeKey) {
|
|
158
162
|
let folded = identity;
|
|
159
163
|
if (scope !== undefined)
|
|
160
164
|
folded = foldPartition(folded, 'hypequery.ts.cache-scope.v1', scope);
|
|
161
165
|
if (timezone !== undefined)
|
|
162
166
|
folded = foldPartition(folded, 'hypequery.ts.cache-timezone.v1', timezone);
|
|
167
|
+
if (timeKey !== undefined)
|
|
168
|
+
folded = foldPartition(folded, 'hypequery.ts.cache-time-key.v1', timeKey);
|
|
163
169
|
return folded;
|
|
164
170
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-cache-keys.d.ts","sourceRoot":"","sources":["../../src/cache/protocol-cache-keys.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAEhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol-cache-keys.d.ts","sourceRoot":"","sources":["../../src/cache/protocol-cache-keys.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAEhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAMrB,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,cAAc,CAAC;AACjD,eAAO,MAAM,yBAAyB,YAAY,CAAC;AAInD,0EAA0E;AAC1E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAChC,WAAW,EAAE,OAAO,GACnB,wBAAwB,CAqC1B;AAwID;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,wBAAwB,EAClC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,gBAAgB,GAAG,SAAS,EACrC,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,GAAG,SAAS,CAkBpB;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,wBAAwB,EAClC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GAAG,SAAS,EACrC,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,GAAG,SAAS,CAgBpB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { buildProtocolCachePreimage, deriveProtocolCacheKey, validateCanonicalValue, } from '@hypequery/protocol';
|
|
2
2
|
import { getMetricGrain, getMetricRef } from '../utils/metric-handle.js';
|
|
3
|
+
import { runtimeConstraints } from '../utils/row-scope.js';
|
|
3
4
|
import { localDefinitionIdentity, scopedDefinitionIdentity } from './definition-identity.js';
|
|
5
|
+
import { selectsAlternateTimeKey } from '../utils/dataset-time-keys.js';
|
|
4
6
|
/** Namespace defaults, so caching works without any configuration. */
|
|
5
7
|
export const DEFAULT_CACHE_PROJECT = 'hypequery';
|
|
6
8
|
export const DEFAULT_CACHE_ENVIRONMENT = 'default';
|
|
@@ -91,10 +93,23 @@ function filterNode(filter) {
|
|
|
91
93
|
right: { kind: 'literal', value: literal },
|
|
92
94
|
};
|
|
93
95
|
}
|
|
94
|
-
|
|
96
|
+
/**
|
|
97
|
+
* The call's filters as the preimage sees them: the caller's, then the
|
|
98
|
+
* enforced constraints (RFC 0020). Constraints change rows, so they must
|
|
99
|
+
* change the key; the preimage sorts and dedupes filters, so a constraint and
|
|
100
|
+
* an identical caller filter (which yield the same rows) share an entry.
|
|
101
|
+
*/
|
|
102
|
+
function effectiveFilters(query, context) {
|
|
103
|
+
const constraints = runtimeConstraints(context);
|
|
104
|
+
if (constraints.length === 0)
|
|
105
|
+
return query.filters;
|
|
106
|
+
return [...(query.filters ?? []), ...constraints];
|
|
107
|
+
}
|
|
108
|
+
function sharedQueryFields(query, context) {
|
|
109
|
+
const filters = effectiveFilters(query, context);
|
|
95
110
|
return {
|
|
96
111
|
...(query.dimensions !== undefined ? { dimensions: [...query.dimensions] } : {}),
|
|
97
|
-
...(
|
|
112
|
+
...(filters !== undefined ? { filters: filters.map(filterNode) } : {}),
|
|
98
113
|
...(query.segments !== undefined ? { segments: [...query.segments] } : {}),
|
|
99
114
|
...(query.orderBy !== undefined
|
|
100
115
|
? { orderBy: query.orderBy.map(({ field, direction }) => ({ field, direction })) }
|
|
@@ -143,11 +158,19 @@ function deriveKey(settings, query, definitionIdentity, context, rowLimit) {
|
|
|
143
158
|
function partitionTimezone(query) {
|
|
144
159
|
return query.timezone === 'UTC' ? undefined : query.timezone;
|
|
145
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* RFC 0009's normalized query has no time axis either. An alternate axis is
|
|
163
|
+
* folded in like the timezone; the default, named or omitted, folds in nothing.
|
|
164
|
+
*/
|
|
165
|
+
function partitionTimeKey(root, query) {
|
|
166
|
+
return selectsAlternateTimeKey(root, query.timeKey) ? query.timeKey : undefined;
|
|
167
|
+
}
|
|
146
168
|
function definitionFor(settings, root, scope, query, metric) {
|
|
147
169
|
const timezone = partitionTimezone(query);
|
|
170
|
+
const timeKey = partitionTimeKey(root, query);
|
|
148
171
|
return settings.definitionIdentity !== undefined
|
|
149
|
-
? scopedDefinitionIdentity(settings.definitionIdentity, scope, timezone)
|
|
150
|
-
: localDefinitionIdentity(root, { metric, scope, timezone });
|
|
172
|
+
? scopedDefinitionIdentity(settings.definitionIdentity, scope, timezone, timeKey)
|
|
173
|
+
: localDefinitionIdentity(root, { metric, scope, timezone, timeKey });
|
|
151
174
|
}
|
|
152
175
|
/**
|
|
153
176
|
* The RFC 0013 store key for a dataset query, or `undefined` when the call
|
|
@@ -164,7 +187,7 @@ export function datasetCacheKey(settings, ds, query, context, scope) {
|
|
|
164
187
|
const wire = {
|
|
165
188
|
kind: 'dataset',
|
|
166
189
|
dataset: ds.name,
|
|
167
|
-
...sharedQueryFields(query),
|
|
190
|
+
...sharedQueryFields(query, context),
|
|
168
191
|
...(query.measures !== undefined ? { measures: [...query.measures] } : {}),
|
|
169
192
|
...(query.by !== undefined ? { by: query.by } : {}),
|
|
170
193
|
};
|
|
@@ -184,7 +207,7 @@ export function metricCacheKey(settings, metric, query, context, scope) {
|
|
|
184
207
|
kind: 'metric',
|
|
185
208
|
dataset: ref.dataset.name,
|
|
186
209
|
metric: ref.name,
|
|
187
|
-
...sharedQueryFields(query),
|
|
210
|
+
...sharedQueryFields(query, context),
|
|
188
211
|
...(grain !== undefined ? { by: grain } : {}),
|
|
189
212
|
};
|
|
190
213
|
const definition = definitionFor(settings, ref.dataset, scope, query, ref.spec);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAElB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAElB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,CAAC;AAoG3B;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAyBR;AAED,oDAAoD;AACpD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAsBR"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { windowQuerySignature } from '../utils/window-query-signature.js';
|
|
2
2
|
import { getMetricGrain, getMetricRef } from '../utils/metric-handle.js';
|
|
3
3
|
import { getRuntimeTenantPredicate } from '../utils/tenant-runtime.js';
|
|
4
|
+
import { runtimeConstraints } from '../utils/row-scope.js';
|
|
4
5
|
import { buildRelationshipBuilderContext } from '../utils/relationship-builder-plan.js';
|
|
5
6
|
import { stableStringify } from '../utils/canonical-json.js';
|
|
6
7
|
export { stableStringify };
|
|
@@ -41,7 +42,7 @@ function orderBySignature(orderBy) {
|
|
|
41
42
|
*/
|
|
42
43
|
function activatesTenantScopedJoin(ds, query, context) {
|
|
43
44
|
const joinCtx = buildRelationshipBuilderContext(ds, query, context);
|
|
44
|
-
return !!joinCtx && joinCtx.joins.some((join) => join.
|
|
45
|
+
return !!joinCtx && joinCtx.joins.some((join) => join.scope.length > 0);
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
48
|
* Tenant portion of the key. A dataset with a `tenantKey` is strictly
|
|
@@ -64,6 +65,11 @@ function tenantSignature(ds, query, context) {
|
|
|
64
65
|
}
|
|
65
66
|
return { key: ds.tenantKey, operator: predicate.operator, value: predicate.value };
|
|
66
67
|
}
|
|
68
|
+
/** Enforced constraints change rows; absent when none, keeping existing signatures. */
|
|
69
|
+
function constraintSignature(context) {
|
|
70
|
+
const constraints = runtimeConstraints(context);
|
|
71
|
+
return constraints.length ? { constraints: filterSignature([...constraints]) } : {};
|
|
72
|
+
}
|
|
67
73
|
/**
|
|
68
74
|
* Selected segments keyed by their resolved definitions, not just their names,
|
|
69
75
|
* so editing a segment cannot serve rows cached under the old one. Absent when
|
|
@@ -90,6 +96,8 @@ export function buildDatasetQuerySignature(ds, query, context) {
|
|
|
90
96
|
kind: 'dataset',
|
|
91
97
|
target: ds.name,
|
|
92
98
|
source: ds.source,
|
|
99
|
+
// Omitted when false so existing datasets keep their cache keys.
|
|
100
|
+
...(ds.rowResolution ? { rowResolution: ds.rowResolution } : {}),
|
|
93
101
|
dimensions: query.dimensions ?? null,
|
|
94
102
|
// `null` distinguishes the "all measures" default from an explicit [].
|
|
95
103
|
measures: query.measures ?? null,
|
|
@@ -104,6 +112,7 @@ export function buildDatasetQuerySignature(ds, query, context) {
|
|
|
104
112
|
limit: query.limit ?? null,
|
|
105
113
|
offset: query.offset ?? null,
|
|
106
114
|
tenant: tenantSignature(ds, query, context),
|
|
115
|
+
...constraintSignature(context),
|
|
107
116
|
scope: scopeSignature(context),
|
|
108
117
|
});
|
|
109
118
|
}
|
|
@@ -116,6 +125,7 @@ export function buildMetricQuerySignature(metric, query, context) {
|
|
|
116
125
|
kind: 'metric',
|
|
117
126
|
target: `${ref.dataset.name}.${ref.name}`,
|
|
118
127
|
source: ref.dataset.source,
|
|
128
|
+
...(ref.dataset.rowResolution ? { rowResolution: ref.dataset.rowResolution } : {}),
|
|
119
129
|
metricKind: ref.spec.__type,
|
|
120
130
|
dimensions: query.dimensions ?? null,
|
|
121
131
|
filters: filterSignature(query.filters),
|
|
@@ -126,6 +136,7 @@ export function buildMetricQuerySignature(metric, query, context) {
|
|
|
126
136
|
limit: query.limit ?? null,
|
|
127
137
|
offset: query.offset ?? null,
|
|
128
138
|
tenant: tenantSignature(ref.dataset, query, context),
|
|
139
|
+
...constraintSignature(context),
|
|
129
140
|
scope: scopeSignature(context),
|
|
130
141
|
});
|
|
131
142
|
}
|
package/dist/catalog.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { RowResolution } from './types.js';
|
|
1
2
|
import type { ProtocolExpression } from '@hypequery/protocol';
|
|
2
3
|
import type { RelationshipKey } from './types.js';
|
|
3
4
|
import { type WindowCatalogMetadata } from './utils/window-catalog-metadata.js';
|
|
4
5
|
import type { AnyDatasetInstance, DimensionDefinition, MeasureDefinition, MetricHandle, RelationshipDefinition, SemanticFilterDefinition, DatasetLimits, DatasetDefaults, DatasetFreshness, SemanticMetadata, TimeGrain } from './types.js';
|
|
6
|
+
import type { AggregateStateFunction } from './utils/aggregate-state-functions.js';
|
|
5
7
|
export interface DimensionCatalogEntry extends SemanticMetadata {
|
|
6
8
|
type: DimensionDefinition['fieldType'];
|
|
7
9
|
column?: string;
|
|
@@ -18,6 +20,8 @@ export interface MeasureCatalogEntry extends SemanticMetadata, WindowCatalogMeta
|
|
|
18
20
|
argField?: string;
|
|
19
21
|
/** Percentile level in [0, 1]. */
|
|
20
22
|
level?: number;
|
|
23
|
+
/** State function a `merge` measure finalizes (`uniq` for `uniqMerge`). */
|
|
24
|
+
stateFunction?: AggregateStateFunction;
|
|
21
25
|
sql?: string;
|
|
22
26
|
label?: string;
|
|
23
27
|
description?: string;
|
|
@@ -81,11 +85,14 @@ export interface DatasetCatalog extends SemanticMetadata {
|
|
|
81
85
|
name: string;
|
|
82
86
|
description?: string;
|
|
83
87
|
source: string;
|
|
88
|
+
rowResolution?: RowResolution;
|
|
84
89
|
freshness?: DatasetFreshness;
|
|
85
90
|
owner?: string;
|
|
86
91
|
defaults?: DatasetDefaults;
|
|
87
92
|
tenantKey?: string;
|
|
88
93
|
timeKey?: string;
|
|
94
|
+
/** Alternate time axes a query may select; absent when the dataset declares none. */
|
|
95
|
+
timeKeys?: string[];
|
|
89
96
|
dimensions: Record<string, DimensionCatalogEntry>;
|
|
90
97
|
measures: Record<string, MeasureCatalogEntry>;
|
|
91
98
|
/** Dataset-owned post-aggregation measures; absent in older hosted catalogs. */
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EAAyB,KAAK,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEvG,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACV,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/catalog.js
CHANGED
|
@@ -5,7 +5,7 @@ import { windowCatalogMetadata } from './utils/window-catalog-metadata.js';
|
|
|
5
5
|
import { splitDatasetMeasures } from './utils/dataset-measures.js';
|
|
6
6
|
import { SEMANTIC_FILTER_OPERATORS } from './constants.js';
|
|
7
7
|
import { datasetTimeGrains } from './utils/dataset-time-grains.js';
|
|
8
|
-
import {
|
|
8
|
+
import { isApproximateBaseMeasure, isApproximateDerivedMeasure, isApproximateMeasure } from './utils/approximate-measures.js';
|
|
9
9
|
import { usesTimeMeasure } from './utils/time-query-measures.js';
|
|
10
10
|
import { measureSupportedGrains } from './utils/measure-time-grains.js';
|
|
11
11
|
import { listGroupableRelationshipFields, listQueryableRelationshipFields, } from './utils/relationship-fields.js';
|
|
@@ -28,12 +28,13 @@ function measureToCatalog(measure) {
|
|
|
28
28
|
field: measure.field,
|
|
29
29
|
argField: measure.argField,
|
|
30
30
|
level: measure.level,
|
|
31
|
+
...(measure.stateFunction !== undefined ? { stateFunction: measure.stateFunction } : {}),
|
|
31
32
|
sql: measure.sql,
|
|
32
33
|
label: measure.label,
|
|
33
34
|
description: measure.description,
|
|
34
35
|
...snapshotSemanticMetadata(measure),
|
|
35
36
|
filterCount: measure.filters?.length ?? 0,
|
|
36
|
-
...(
|
|
37
|
+
...(isApproximateBaseMeasure(measure) ? { approximate: true } : {}),
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
40
|
function filterToCatalog(filter, dimensions) {
|
|
@@ -113,11 +114,13 @@ export function getDatasetCatalog(dataset) {
|
|
|
113
114
|
description: dataset.description,
|
|
114
115
|
...snapshotSemanticMetadata(dataset),
|
|
115
116
|
source: dataset.source,
|
|
117
|
+
...(dataset.rowResolution === undefined ? {} : { rowResolution: { ...dataset.rowResolution } }),
|
|
116
118
|
freshness: dataset.freshness,
|
|
117
119
|
owner: dataset.owner,
|
|
118
120
|
defaults: dataset.defaults,
|
|
119
121
|
tenantKey: dataset.tenantKey,
|
|
120
122
|
timeKey: dataset.timeKey,
|
|
123
|
+
...(dataset.timeKeys?.length ? { timeKeys: [...dataset.timeKeys] } : {}),
|
|
121
124
|
dimensions: Object.fromEntries(Object.entries(dataset.dimensions).map(([name, dimension]) => [
|
|
122
125
|
name,
|
|
123
126
|
dimensionToCatalog(dimension),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ProtocolClientContract, type ProtocolClientEndpoint } from '@hypequery/protocol';
|
|
2
|
+
import { type ZodTypeAny } from 'zod';
|
|
3
|
+
import { type CanonicalSemanticQuerySchemas } from '../semantic-query-schema.js';
|
|
4
|
+
import type { JsonSchema } from '../tools.js';
|
|
5
|
+
export interface ClientEndpointQuerySchema {
|
|
6
|
+
readonly endpoint: ProtocolClientEndpoint;
|
|
7
|
+
readonly http: ZodTypeAny;
|
|
8
|
+
readonly httpJsonSchema: JsonSchema;
|
|
9
|
+
}
|
|
10
|
+
export interface ClientContractQuerySchemas extends CanonicalSemanticQuerySchemas {
|
|
11
|
+
readonly contract: ProtocolClientContract;
|
|
12
|
+
readonly endpoints: ReadonlyMap<string, ClientEndpointQuerySchema>;
|
|
13
|
+
}
|
|
14
|
+
/** Compile typed endpoint and MCP schemas from the same validated client descriptor.
|
|
15
|
+
* JSON Schema describes structural constraints; execution must retain the runtime
|
|
16
|
+
* validator for selected-field dependencies, uniqueness, and combined budgets.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildClientContractQuerySchemas(input: unknown): ClientContractQuerySchemas;
|
|
19
|
+
//# sourceMappingURL=query-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-schema.d.ts","sourceRoot":"","sources":["../../src/client-contract/query-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,sBAAsB,EAAE,KAAK,sBAAsB,EACzD,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAK,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,EAAwB,KAAK,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;CACrC;AACD,MAAM,WAAW,0BAA2B,SAAQ,6BAA6B;IAC/E,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;CACpE;AA4DD;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,0BAA0B,CAe1F"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { validateProtocolClientContract, validateProtocolClientQuery, } from '@hypequery/protocol';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { toSemanticJsonSchema } from '../semantic-query-schema.js';
|
|
4
|
+
function union(schemas) {
|
|
5
|
+
return schemas.length === 0 ? z.never() : schemas.length === 1 ? schemas[0]
|
|
6
|
+
: z.union(schemas);
|
|
7
|
+
}
|
|
8
|
+
function enumeration(values) {
|
|
9
|
+
return values.length ? z.enum(values) : z.never();
|
|
10
|
+
}
|
|
11
|
+
function predicates(endpoint, having) {
|
|
12
|
+
const definitions = having ? Object.entries(endpoint.measures).filter(([, m]) => m.having)
|
|
13
|
+
.map(([key]) => [key, { type: 'number', operators: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn', 'between'] }])
|
|
14
|
+
: Object.entries(endpoint.filters);
|
|
15
|
+
return union(definitions.flatMap(([key, field]) => field.operators.map(operator => {
|
|
16
|
+
const scalar = field.type === 'number' ? z.number().finite()
|
|
17
|
+
: field.type === 'boolean' ? z.boolean() : z.string();
|
|
18
|
+
const value = operator === 'between' ? z.tuple([scalar, scalar])
|
|
19
|
+
: operator === 'in' || operator === 'notIn' ? z.array(scalar).min(1).max(endpoint.limits.maxFilterValues)
|
|
20
|
+
: scalar;
|
|
21
|
+
return z.object({ [having ? 'measure' : 'field']: z.literal(key), operator: z.literal(operator), value }).strict();
|
|
22
|
+
})));
|
|
23
|
+
}
|
|
24
|
+
function endpointSchema(contract, endpoint, transport) {
|
|
25
|
+
const caps = endpoint.limits;
|
|
26
|
+
const groupable = Object.keys(endpoint.dimensions).filter(key => endpoint.dimensions[key].groupable);
|
|
27
|
+
const orderable = [...Object.keys(endpoint.dimensions).filter(key => endpoint.dimensions[key].groupable && endpoint.dimensions[key].orderable),
|
|
28
|
+
...Object.keys(endpoint.measures), ...(endpoint.time ? ['period'] : [])];
|
|
29
|
+
const fields = {
|
|
30
|
+
dimensions: z.array(enumeration(groupable)).max(caps.maxDimensions).optional(),
|
|
31
|
+
filters: z.array(predicates(endpoint, false)).max(caps.maxPredicates).optional(),
|
|
32
|
+
orderBy: z.array(z.object({ field: enumeration(orderable), direction: z.enum(['asc', 'desc']) }).strict()).max(caps.maxOrderBy).optional(),
|
|
33
|
+
// HTTP clamps a larger limit to the endpoint's maximum. An agent should
|
|
34
|
+
// see the real ceiling, rather than learn of truncation from metadata.
|
|
35
|
+
limit: z.number().int().min(1).max(transport === 'mcp' ? caps.maxLimit : Number.MAX_SAFE_INTEGER).optional(),
|
|
36
|
+
offset: z.number().int().min(0).max(caps.maxOffset).optional(),
|
|
37
|
+
includeMeta: (endpoint.metadata ? z.boolean() : z.literal(false)).optional(),
|
|
38
|
+
};
|
|
39
|
+
if (endpoint.kind === 'dataset') {
|
|
40
|
+
fields.measures = z.array(enumeration(Object.keys(endpoint.measures))).max(caps.maxMeasures).optional();
|
|
41
|
+
fields.having = z.array(predicates(endpoint, true)).max(caps.maxPredicates).optional();
|
|
42
|
+
}
|
|
43
|
+
if (endpoint.time) {
|
|
44
|
+
fields[transport === 'http' ? 'by' : 'grain'] = enumeration(endpoint.time.grains).optional();
|
|
45
|
+
if (endpoint.time.timezone)
|
|
46
|
+
fields.timezone = z.string().optional();
|
|
47
|
+
}
|
|
48
|
+
if (transport === 'mcp') {
|
|
49
|
+
fields.dataset = z.literal(endpoint.dataset);
|
|
50
|
+
if (endpoint.kind === 'metric')
|
|
51
|
+
fields.metric = z.literal(endpoint.id);
|
|
52
|
+
}
|
|
53
|
+
// Validate before zod reads properties: the runtime validator snapshots input
|
|
54
|
+
// without invoking accessors, so a hostile getter cannot escape safeParse.
|
|
55
|
+
return z.preprocess((input, context) => {
|
|
56
|
+
try {
|
|
57
|
+
validateProtocolClientQuery(contract, endpoint.id, input, transport);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
context.addIssue({ code: z.ZodIssueCode.custom, message: 'Invalid client query.' });
|
|
61
|
+
return z.NEVER;
|
|
62
|
+
}
|
|
63
|
+
return input;
|
|
64
|
+
}, z.object(fields).strict());
|
|
65
|
+
}
|
|
66
|
+
/** Compile typed endpoint and MCP schemas from the same validated client descriptor.
|
|
67
|
+
* JSON Schema describes structural constraints; execution must retain the runtime
|
|
68
|
+
* validator for selected-field dependencies, uniqueness, and combined budgets.
|
|
69
|
+
*/
|
|
70
|
+
export function buildClientContractQuerySchemas(input) {
|
|
71
|
+
const contract = validateProtocolClientContract(input);
|
|
72
|
+
const endpoints = new Map();
|
|
73
|
+
const datasets = [], metrics = [];
|
|
74
|
+
for (const endpoint of contract.endpoints) {
|
|
75
|
+
const http = endpointSchema(contract, endpoint, 'http');
|
|
76
|
+
endpoints.set(endpoint.id, { endpoint, http, httpJsonSchema: toSemanticJsonSchema(http) });
|
|
77
|
+
(endpoint.kind === 'dataset' ? datasets : metrics).push(endpointSchema(contract, endpoint, 'mcp'));
|
|
78
|
+
}
|
|
79
|
+
// Preserve the existing fixed MCP tool names while making empty views uncallable.
|
|
80
|
+
const queryDataset = datasets.length ? union(datasets) : z.object({ dataset: z.never() }).strict();
|
|
81
|
+
const queryMetric = metrics.length ? union(metrics) : z.object({ dataset: z.never(), metric: z.never() }).strict();
|
|
82
|
+
return { contract, endpoints, queryDataset, queryMetric,
|
|
83
|
+
queryDatasetJsonSchema: toSemanticJsonSchema(queryDataset),
|
|
84
|
+
queryMetricJsonSchema: toSemanticJsonSchema(queryMetric), manifestHash: contract.contentHash };
|
|
85
|
+
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
import type { MetricFilter, TimeGrain } from './types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Maps time grain to ClickHouse date truncation functions.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Grain SQL is engine-specific and now rendered by the datasets
|
|
9
|
+
* SQL dialect; use {@link SUPPORTED_TIME_GRAINS} to enumerate grains. Kept
|
|
10
|
+
* for compatibility and no longer read by the planner.
|
|
7
11
|
*/
|
|
8
12
|
export declare const GRAIN_FUNCTIONS: Record<TimeGrain, string>;
|
|
9
|
-
/**
|
|
10
|
-
* The set of time grains supported by the planner. Derived from
|
|
11
|
-
* {@link GRAIN_FUNCTIONS} so the two never drift apart.
|
|
12
|
-
*/
|
|
13
|
+
/** The set of time grains supported by the planner, finest first. */
|
|
13
14
|
export declare const SUPPORTED_TIME_GRAINS: TimeGrain[];
|
|
14
15
|
/**
|
|
15
16
|
* The filter operators accepted by semantic dataset and metric inputs.
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAyB,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEjF
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAyB,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEjF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAQrD,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,EAAE,SAAS,EAAkE,CAAC;AAEhH;;GAEG;AACH,eAAO,MAAM,yBAAyB,oFAWkB,CAAC;AAIzD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,YAAY,CAAC,UAAU,CAAC,CAEhG;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,4EAUe,CAAC;AAEtD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAEvE"}
|
package/dist/constants.js
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Maps time grain to ClickHouse date truncation functions.
|
|
6
|
+
*
|
|
7
|
+
* @deprecated Grain SQL is engine-specific and now rendered by the datasets
|
|
8
|
+
* SQL dialect; use {@link SUPPORTED_TIME_GRAINS} to enumerate grains. Kept
|
|
9
|
+
* for compatibility and no longer read by the planner.
|
|
6
10
|
*/
|
|
7
11
|
export const GRAIN_FUNCTIONS = {
|
|
8
12
|
minute: 'toStartOfMinute',
|
|
@@ -13,11 +17,8 @@ export const GRAIN_FUNCTIONS = {
|
|
|
13
17
|
quarter: 'toStartOfQuarter',
|
|
14
18
|
year: 'toStartOfYear',
|
|
15
19
|
};
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
* {@link GRAIN_FUNCTIONS} so the two never drift apart.
|
|
19
|
-
*/
|
|
20
|
-
export const SUPPORTED_TIME_GRAINS = Object.keys(GRAIN_FUNCTIONS);
|
|
20
|
+
/** The set of time grains supported by the planner, finest first. */
|
|
21
|
+
export const SUPPORTED_TIME_GRAINS = ['minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
|
|
21
22
|
/**
|
|
22
23
|
* The filter operators accepted by semantic dataset and metric inputs.
|
|
23
24
|
*/
|
|
@@ -61,5 +62,5 @@ export const SEMANTIC_HAVING_OPERATORS = [
|
|
|
61
62
|
* Narrowing guard for a runtime-provided grain value.
|
|
62
63
|
*/
|
|
63
64
|
export function isSupportedTimeGrain(grain) {
|
|
64
|
-
return typeof grain === 'string' &&
|
|
65
|
+
return typeof grain === 'string' && SUPPORTED_TIME_GRAINS.includes(grain);
|
|
65
66
|
}
|
package/dist/contract.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RowResolution } from './types.js';
|
|
1
2
|
import type { RelationshipKey } from './types.js';
|
|
2
3
|
import { type WindowCatalogMetadata } from './utils/window-catalog-metadata.js';
|
|
3
4
|
import { type DatasetCatalog, type DatasetCatalogSource, type DimensionCatalogEntry, type MeasureCatalogEntry, type SegmentCatalogEntry, type MetricCatalogEntry, type FilterCatalogEntry, type RelationshipCatalogEntry } from './catalog.js';
|
|
@@ -23,6 +24,8 @@ export interface ContractMeasure extends SemanticMetadata, WindowCatalogMetadata
|
|
|
23
24
|
argField?: string;
|
|
24
25
|
/** Percentile level in [0, 1]. */
|
|
25
26
|
level?: number;
|
|
27
|
+
/** State function a `merge` measure finalizes. */
|
|
28
|
+
stateFunction?: MeasureCatalogEntry['stateFunction'];
|
|
26
29
|
sql?: string;
|
|
27
30
|
label?: string;
|
|
28
31
|
description?: string;
|
|
@@ -61,11 +64,13 @@ export interface ContractDataset extends SemanticMetadata {
|
|
|
61
64
|
name: string;
|
|
62
65
|
description?: string;
|
|
63
66
|
source: string;
|
|
67
|
+
rowResolution?: RowResolution;
|
|
64
68
|
freshness?: DatasetFreshness;
|
|
65
69
|
owner?: string;
|
|
66
70
|
defaults?: DatasetDefaults;
|
|
67
71
|
tenantKey?: string;
|
|
68
72
|
timeKey?: string;
|
|
73
|
+
timeKeys?: string[];
|
|
69
74
|
requiresTenant: boolean;
|
|
70
75
|
supportedGrains: string[];
|
|
71
76
|
dimensions: Record<string, ContractDimension>;
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|