@objectstack/service-analytics 17.0.0-rc.4 → 17.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +816 -0
- package/dist/index.cjs +371 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -11
- package/dist/index.d.ts +57 -11
- package/dist/index.js +374 -30
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -105,23 +105,32 @@ type RelationshipResolver = (baseObject: string, relationshipName: string) => st
|
|
|
105
105
|
*/
|
|
106
106
|
interface DatasetCompileOptions {
|
|
107
107
|
/**
|
|
108
|
-
* [#5115] The datasource `objectName`
|
|
109
|
-
*
|
|
110
|
-
* object
|
|
108
|
+
* [#5115] The datasource `objectName` is BOUND to, or `undefined` when nothing
|
|
109
|
+
* authoritative can answer (no data engine, unknown object) — or when nothing
|
|
110
|
+
* binds the object at all and it rides the deployment's default datasource.
|
|
111
111
|
*
|
|
112
112
|
* With it the compiler can settle at COMPILE time what #5033 could only
|
|
113
113
|
* report at QUERY time: a dataset whose join crosses datasources declares a
|
|
114
114
|
* statement no driver can execute, because the analytics engine lowers the
|
|
115
115
|
* whole dataset into ONE SQL statement on the base object's datasource.
|
|
116
116
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
117
|
+
* [#5288] What the host supplies here changed shape, the rule below did not.
|
|
118
|
+
* It used to be the object's DECLARED `datasource` — step 1 of the five
|
|
119
|
+
* `ObjectQL.getDriver` routes by — so an object placed by a
|
|
120
|
+
* `datasourceMapping` rule, by the ADR-0057 §3.6 lifecycle split, or by its
|
|
121
|
+
* package's `defaultDatasource` answered `'default'` and was read here as
|
|
122
|
+
* unanswered. The built-in host (`plugin.ts`) now asks the engine's own
|
|
123
|
+
* resolver instead, so those three placements ARE visible from here and a join
|
|
124
|
+
* between two objects bound to two different datasources is decidable
|
|
125
|
+
* whichever mechanism bound them.
|
|
126
|
+
*
|
|
127
|
+
* Still deliberately UNANSWERED: `'default'`, and the object that no rule
|
|
128
|
+
* places anywhere. The deployment's default driver keeps its natural name
|
|
129
|
+
* (#3826), so "rides the default" is reported as `undefined` rather than as a
|
|
130
|
+
* name — which means a join from a bound object to a default-riding one stays
|
|
131
|
+
* undecidable here and remains the query-time diagnostic's business (#5288
|
|
132
|
+
* records this boundary; widening it is #5115's follow-up, not this rule's).
|
|
133
|
+
* See {@link compileDataset}.
|
|
125
134
|
*/
|
|
126
135
|
getObjectDatasource?: (objectName: string) => string | undefined;
|
|
127
136
|
/**
|
|
@@ -407,6 +416,15 @@ interface AnalyticsServiceConfig {
|
|
|
407
416
|
* datasources before any query is ever built. Absence keeps the pre-#5115
|
|
408
417
|
* behaviour exactly ("cannot answer, do not block") — the query-time
|
|
409
418
|
* diagnostic above stays as the backstop.
|
|
419
|
+
*
|
|
420
|
+
* [#5288] "Bound to" above is the whole contract, and it took until #5288 for
|
|
421
|
+
* the built-in host to honour it: `plugin.ts` answered with the object's
|
|
422
|
+
* DECLARED `datasource` — step 1 of the five `ObjectQL.getDriver` routes by —
|
|
423
|
+
* so an object placed by a `datasourceMapping` rule, by the ADR-0057 §3.6
|
|
424
|
+
* lifecycle split, or by its package's `defaultDatasource` reported
|
|
425
|
+
* `'default'` and sent the message above to the wrong database. It now asks
|
|
426
|
+
* `ObjectQL.resolveEffectiveDatasource`. A custom host owes the same answer:
|
|
427
|
+
* the datasource an object is BOUND to, `undefined` when nothing binds it.
|
|
410
428
|
*/
|
|
411
429
|
getObjectDatasource?: (objectName: string) => string | undefined;
|
|
412
430
|
/**
|
|
@@ -665,6 +683,13 @@ declare class AnalyticsService implements IAnalyticsService {
|
|
|
665
683
|
* the data path's `resolveQueryFields`: they are engine-assigned rather than
|
|
666
684
|
* declared, and a gate stricter than the engine it guards would reject
|
|
667
685
|
* queries that used to work.
|
|
686
|
+
*
|
|
687
|
+
* [#5918] Its `stripPrefix` below is deliberately NOT narrowed the way the two
|
|
688
|
+
* MINTS were. This is a RESOLVER — it mirrors `lookupMember`'s tiers to answer
|
|
689
|
+
* "which Metric will the strategy read", and that tier order did not change.
|
|
690
|
+
* What changed is what can reach it: a dotted measure is now either a
|
|
691
|
+
* `<cube>.` qualifier or a key the cube itself declares, because every other
|
|
692
|
+
* dotted spelling is refused at the mint before this gate runs.
|
|
668
693
|
*/
|
|
669
694
|
private assertMeasureFields;
|
|
670
695
|
/**
|
|
@@ -1041,6 +1066,19 @@ declare class DatasetExecutor {
|
|
|
1041
1066
|
* ISO strings chronologically, and bucket keys are minted sort-stable.)
|
|
1042
1067
|
*/
|
|
1043
1068
|
private timeDimensionsOf;
|
|
1069
|
+
/**
|
|
1070
|
+
* The EFFECTIVE bucket size one dimension is grouped at for this selection,
|
|
1071
|
+
* or `undefined` when it is not a date dimension or nothing states a size (in
|
|
1072
|
+
* which case the runtime groups the raw column).
|
|
1073
|
+
*
|
|
1074
|
+
* One definition, two readers, deliberately: {@link buildQuery} uses it to
|
|
1075
|
+
* decide the `GROUP BY`, and {@link runCompare} uses it to realign the
|
|
1076
|
+
* comparison pass's bucket keys (#6007). Those two MUST agree — realigning
|
|
1077
|
+
* `month` keys a query grouped by `quarter` would move every comparison value
|
|
1078
|
+
* onto a bucket that does not exist — and the way to make them agree is to
|
|
1079
|
+
* have one of them, not two that look alike.
|
|
1080
|
+
*/
|
|
1081
|
+
private granularityOf;
|
|
1044
1082
|
private buildQuery;
|
|
1045
1083
|
private runCompare;
|
|
1046
1084
|
}
|
|
@@ -1464,6 +1502,14 @@ declare class ObjectQLStrategy implements AnalyticsStrategy {
|
|
|
1464
1502
|
* string — `String(…)`, the same normalisation `like-pattern.ts` applies at the
|
|
1465
1503
|
* two SQL emitters and `driver-sql`'s `applyLike` applies at the driver, so one
|
|
1466
1504
|
* `$contains` means one thing on every face (#5567's invariant).
|
|
1505
|
+
*
|
|
1506
|
+
* [#5234] Those four `String(…)` calls now only ever see a value that renders
|
|
1507
|
+
* faithfully: `fieldLeaves` refuses an object comparand on this family before a
|
|
1508
|
+
* leaf exists. That ordering is load-bearing rather than incidental — this arm
|
|
1509
|
+
* is a PRODUCER for the engine, so stringifying an object here would have
|
|
1510
|
+
* laundered it into `'[object Object]'` and handed a driver a perfectly
|
|
1511
|
+
* well-typed string. A strict driver downstream could never have seen the shape
|
|
1512
|
+
* it was strict about, which is why the guard sits at the door and not here.
|
|
1467
1513
|
*/
|
|
1468
1514
|
private convertFilter;
|
|
1469
1515
|
private extractObjectName;
|
package/dist/index.d.ts
CHANGED
|
@@ -105,23 +105,32 @@ type RelationshipResolver = (baseObject: string, relationshipName: string) => st
|
|
|
105
105
|
*/
|
|
106
106
|
interface DatasetCompileOptions {
|
|
107
107
|
/**
|
|
108
|
-
* [#5115] The datasource `objectName`
|
|
109
|
-
*
|
|
110
|
-
* object
|
|
108
|
+
* [#5115] The datasource `objectName` is BOUND to, or `undefined` when nothing
|
|
109
|
+
* authoritative can answer (no data engine, unknown object) — or when nothing
|
|
110
|
+
* binds the object at all and it rides the deployment's default datasource.
|
|
111
111
|
*
|
|
112
112
|
* With it the compiler can settle at COMPILE time what #5033 could only
|
|
113
113
|
* report at QUERY time: a dataset whose join crosses datasources declares a
|
|
114
114
|
* statement no driver can execute, because the analytics engine lowers the
|
|
115
115
|
* whole dataset into ONE SQL statement on the base object's datasource.
|
|
116
116
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
117
|
+
* [#5288] What the host supplies here changed shape, the rule below did not.
|
|
118
|
+
* It used to be the object's DECLARED `datasource` — step 1 of the five
|
|
119
|
+
* `ObjectQL.getDriver` routes by — so an object placed by a
|
|
120
|
+
* `datasourceMapping` rule, by the ADR-0057 §3.6 lifecycle split, or by its
|
|
121
|
+
* package's `defaultDatasource` answered `'default'` and was read here as
|
|
122
|
+
* unanswered. The built-in host (`plugin.ts`) now asks the engine's own
|
|
123
|
+
* resolver instead, so those three placements ARE visible from here and a join
|
|
124
|
+
* between two objects bound to two different datasources is decidable
|
|
125
|
+
* whichever mechanism bound them.
|
|
126
|
+
*
|
|
127
|
+
* Still deliberately UNANSWERED: `'default'`, and the object that no rule
|
|
128
|
+
* places anywhere. The deployment's default driver keeps its natural name
|
|
129
|
+
* (#3826), so "rides the default" is reported as `undefined` rather than as a
|
|
130
|
+
* name — which means a join from a bound object to a default-riding one stays
|
|
131
|
+
* undecidable here and remains the query-time diagnostic's business (#5288
|
|
132
|
+
* records this boundary; widening it is #5115's follow-up, not this rule's).
|
|
133
|
+
* See {@link compileDataset}.
|
|
125
134
|
*/
|
|
126
135
|
getObjectDatasource?: (objectName: string) => string | undefined;
|
|
127
136
|
/**
|
|
@@ -407,6 +416,15 @@ interface AnalyticsServiceConfig {
|
|
|
407
416
|
* datasources before any query is ever built. Absence keeps the pre-#5115
|
|
408
417
|
* behaviour exactly ("cannot answer, do not block") — the query-time
|
|
409
418
|
* diagnostic above stays as the backstop.
|
|
419
|
+
*
|
|
420
|
+
* [#5288] "Bound to" above is the whole contract, and it took until #5288 for
|
|
421
|
+
* the built-in host to honour it: `plugin.ts` answered with the object's
|
|
422
|
+
* DECLARED `datasource` — step 1 of the five `ObjectQL.getDriver` routes by —
|
|
423
|
+
* so an object placed by a `datasourceMapping` rule, by the ADR-0057 §3.6
|
|
424
|
+
* lifecycle split, or by its package's `defaultDatasource` reported
|
|
425
|
+
* `'default'` and sent the message above to the wrong database. It now asks
|
|
426
|
+
* `ObjectQL.resolveEffectiveDatasource`. A custom host owes the same answer:
|
|
427
|
+
* the datasource an object is BOUND to, `undefined` when nothing binds it.
|
|
410
428
|
*/
|
|
411
429
|
getObjectDatasource?: (objectName: string) => string | undefined;
|
|
412
430
|
/**
|
|
@@ -665,6 +683,13 @@ declare class AnalyticsService implements IAnalyticsService {
|
|
|
665
683
|
* the data path's `resolveQueryFields`: they are engine-assigned rather than
|
|
666
684
|
* declared, and a gate stricter than the engine it guards would reject
|
|
667
685
|
* queries that used to work.
|
|
686
|
+
*
|
|
687
|
+
* [#5918] Its `stripPrefix` below is deliberately NOT narrowed the way the two
|
|
688
|
+
* MINTS were. This is a RESOLVER — it mirrors `lookupMember`'s tiers to answer
|
|
689
|
+
* "which Metric will the strategy read", and that tier order did not change.
|
|
690
|
+
* What changed is what can reach it: a dotted measure is now either a
|
|
691
|
+
* `<cube>.` qualifier or a key the cube itself declares, because every other
|
|
692
|
+
* dotted spelling is refused at the mint before this gate runs.
|
|
668
693
|
*/
|
|
669
694
|
private assertMeasureFields;
|
|
670
695
|
/**
|
|
@@ -1041,6 +1066,19 @@ declare class DatasetExecutor {
|
|
|
1041
1066
|
* ISO strings chronologically, and bucket keys are minted sort-stable.)
|
|
1042
1067
|
*/
|
|
1043
1068
|
private timeDimensionsOf;
|
|
1069
|
+
/**
|
|
1070
|
+
* The EFFECTIVE bucket size one dimension is grouped at for this selection,
|
|
1071
|
+
* or `undefined` when it is not a date dimension or nothing states a size (in
|
|
1072
|
+
* which case the runtime groups the raw column).
|
|
1073
|
+
*
|
|
1074
|
+
* One definition, two readers, deliberately: {@link buildQuery} uses it to
|
|
1075
|
+
* decide the `GROUP BY`, and {@link runCompare} uses it to realign the
|
|
1076
|
+
* comparison pass's bucket keys (#6007). Those two MUST agree — realigning
|
|
1077
|
+
* `month` keys a query grouped by `quarter` would move every comparison value
|
|
1078
|
+
* onto a bucket that does not exist — and the way to make them agree is to
|
|
1079
|
+
* have one of them, not two that look alike.
|
|
1080
|
+
*/
|
|
1081
|
+
private granularityOf;
|
|
1044
1082
|
private buildQuery;
|
|
1045
1083
|
private runCompare;
|
|
1046
1084
|
}
|
|
@@ -1464,6 +1502,14 @@ declare class ObjectQLStrategy implements AnalyticsStrategy {
|
|
|
1464
1502
|
* string — `String(…)`, the same normalisation `like-pattern.ts` applies at the
|
|
1465
1503
|
* two SQL emitters and `driver-sql`'s `applyLike` applies at the driver, so one
|
|
1466
1504
|
* `$contains` means one thing on every face (#5567's invariant).
|
|
1505
|
+
*
|
|
1506
|
+
* [#5234] Those four `String(…)` calls now only ever see a value that renders
|
|
1507
|
+
* faithfully: `fieldLeaves` refuses an object comparand on this family before a
|
|
1508
|
+
* leaf exists. That ordering is load-bearing rather than incidental — this arm
|
|
1509
|
+
* is a PRODUCER for the engine, so stringifying an object here would have
|
|
1510
|
+
* laundered it into `'[object Object]'` and handed a driver a perfectly
|
|
1511
|
+
* well-typed string. A strict driver downstream could never have seen the shape
|
|
1512
|
+
* it was strict about, which is why the guard sits at the door and not here.
|
|
1467
1513
|
*/
|
|
1468
1514
|
private convertFilter;
|
|
1469
1515
|
private extractObjectName;
|