@pythia-software/query-table-core 0.9.7 → 0.9.9
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/dist/index.d.ts +78 -1
- package/dist/index.js +249 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,10 +23,10 @@ function parseCellDisplay(raw, context = "cell display") {
|
|
|
23
23
|
throw Error(`${context}: ${reason}`);
|
|
24
24
|
};
|
|
25
25
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return fail("expected an object");
|
|
26
|
-
const
|
|
27
|
-
if (typeof
|
|
28
|
-
const allowed = options[
|
|
29
|
-
for (const [key, value] of Object.entries(
|
|
26
|
+
const record3 = raw;
|
|
27
|
+
if (typeof record3.kind !== "string" || !Object.prototype.hasOwnProperty.call(options, record3.kind)) return fail("unsupported kind");
|
|
28
|
+
const allowed = options[record3.kind];
|
|
29
|
+
for (const [key, value] of Object.entries(record3)) {
|
|
30
30
|
if (key === "kind") continue;
|
|
31
31
|
const rule = Object.prototype.hasOwnProperty.call(allowed, key) ? allowed[key] : void 0;
|
|
32
32
|
if (!rule) return fail(`unsupported option ${key}`);
|
|
@@ -40,13 +40,16 @@ function parseCellDisplay(raw, context = "cell display") {
|
|
|
40
40
|
if (key === "pattern" && value.length > 160) return fail("pattern must be at most 160 characters");
|
|
41
41
|
}
|
|
42
42
|
return {
|
|
43
|
-
...
|
|
44
|
-
...
|
|
45
|
-
...
|
|
43
|
+
...record3,
|
|
44
|
+
...record3.labels ? { labels: { ...record3.labels } } : {},
|
|
45
|
+
...record3.tones ? { tones: { ...record3.tones } } : {}
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// src/properties.ts
|
|
50
|
+
function isPropertyFieldLoaded(field, loadedFields) {
|
|
51
|
+
return !loadedFields || loadedFields.includes(field.name) || field.source.kind === "derived" && field.source.dependencies !== void 0 && field.source.dependencies.every((name) => loadedFields.includes(name));
|
|
52
|
+
}
|
|
50
53
|
var MAX_PROPERTIES = 200;
|
|
51
54
|
var string = (value, max = 256) => typeof value === "string" && value.length > 0 && value.length <= max;
|
|
52
55
|
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -444,6 +447,71 @@ function renderItemPageTemplate(template, schema, row, id, query) {
|
|
|
444
447
|
return fillUrlTemplate(template, ITEM_PAGE_TOKENS, (token) => token === "id" ? id : token === "query" ? query : readFieldValue(schema.fields.find((field) => field.name === token.slice(6)), row));
|
|
445
448
|
}
|
|
446
449
|
|
|
450
|
+
// src/jsonInspection.ts
|
|
451
|
+
var MAX_JSON_INSPECTIONS = 200;
|
|
452
|
+
var MAX_JSON_PATHS = 5e3;
|
|
453
|
+
var record2 = (x) => x !== null && typeof x === "object" && !Array.isArray(x);
|
|
454
|
+
var text = (x, max) => typeof x === "string" && x.length > 0 && x.length <= max;
|
|
455
|
+
function isJsonPath(path) {
|
|
456
|
+
return text(path, 1e4) && /^\$(?:\[(?:0|[1-9]\d*|"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[\da-fA-F]{4}))*")\])*$/.test(path);
|
|
457
|
+
}
|
|
458
|
+
function isJsonBucketId(path) {
|
|
459
|
+
if (!text(path, 10032)) return false;
|
|
460
|
+
const index = path.lastIndexOf(":bucket:");
|
|
461
|
+
return index > 0 && isJsonPath(path.slice(0, index)) && /^(?:0|[1-9]\d*)$/.test(path.slice(index + 8)) && Number.isSafeInteger(Number(path.slice(index + 8))) && Number(path.slice(index + 8)) >= 20 && Number(path.slice(index + 8)) % 20 === 0;
|
|
462
|
+
}
|
|
463
|
+
function jsonInspectionScopeKey(scope) {
|
|
464
|
+
return JSON.stringify([scope.dataset, scope.rowId, scope.field]);
|
|
465
|
+
}
|
|
466
|
+
function parseJsonInspectionState(input) {
|
|
467
|
+
if (!record2(input) || input.version !== 1 || typeof input.open !== "boolean" || typeof input.raw !== "boolean" || typeof input.search !== "string" || input.search.length > 1e4 || input.searchMode !== "filter" && input.searchMode !== "find" || typeof input.visibleEntryLimit !== "number" || !Number.isInteger(input.visibleEntryLimit) || input.visibleEntryLimit < 1 || input.visibleEntryLimit > 1e4)
|
|
468
|
+
throw Error("Invalid or unsupported JSON inspection state.");
|
|
469
|
+
const paths = (value, valid) => {
|
|
470
|
+
if (!Array.isArray(value) || value.length > MAX_JSON_PATHS || !value.every(valid) || new Set(value).size !== value.length)
|
|
471
|
+
throw Error("Invalid JSON inspection paths.");
|
|
472
|
+
return value.slice();
|
|
473
|
+
};
|
|
474
|
+
const state = {
|
|
475
|
+
version: 1,
|
|
476
|
+
open: input.open,
|
|
477
|
+
search: input.search,
|
|
478
|
+
searchMode: input.searchMode,
|
|
479
|
+
raw: input.raw,
|
|
480
|
+
collapsedPaths: paths(input.collapsedPaths, isJsonPath),
|
|
481
|
+
expandedBuckets: paths(input.expandedBuckets, isJsonBucketId),
|
|
482
|
+
visibleEntryLimit: input.visibleEntryLimit,
|
|
483
|
+
searchOverrides: []
|
|
484
|
+
};
|
|
485
|
+
if (input.selectedMatch !== void 0) {
|
|
486
|
+
const match = input.selectedMatch;
|
|
487
|
+
if (!record2(match) || !isJsonPath(match.path) || match.part !== "key" && match.part !== "value" && match.part !== "path" || typeof match.start !== "number" || !Number.isSafeInteger(match.start) || match.start < 0 || match.start > 1048576)
|
|
488
|
+
throw Error("Invalid JSON match identity.");
|
|
489
|
+
state.selectedMatch = { path: match.path, part: match.part, start: match.start };
|
|
490
|
+
}
|
|
491
|
+
if (!Array.isArray(input.searchOverrides) || input.searchOverrides.length > MAX_JSON_PATHS) throw Error("Invalid JSON search expansion overrides.");
|
|
492
|
+
const seen = /* @__PURE__ */ new Set();
|
|
493
|
+
for (const entry of input.searchOverrides) {
|
|
494
|
+
if (!record2(entry) || !(isJsonPath(entry.path) || isJsonBucketId(entry.path)) || typeof entry.expanded !== "boolean" || seen.has(entry.path))
|
|
495
|
+
throw Error("Invalid JSON search expansion override.");
|
|
496
|
+
seen.add(entry.path);
|
|
497
|
+
state.searchOverrides.push({ path: entry.path, expanded: entry.expanded });
|
|
498
|
+
}
|
|
499
|
+
return state;
|
|
500
|
+
}
|
|
501
|
+
function parseJsonInspections(input) {
|
|
502
|
+
if (!Array.isArray(input) || input.length > MAX_JSON_INSPECTIONS) throw Error("Invalid JSON inspection scopes.");
|
|
503
|
+
const seen = /* @__PURE__ */ new Set();
|
|
504
|
+
return input.map((entry) => {
|
|
505
|
+
if (!record2(entry) || !text(entry.dataset, 256) || !text(entry.field, 256) || !(text(entry.rowId, 1e3) || typeof entry.rowId === "number" && Number.isFinite(entry.rowId)))
|
|
506
|
+
throw Error("Invalid JSON inspection scope.");
|
|
507
|
+
const scope = { dataset: entry.dataset, rowId: entry.rowId, field: entry.field };
|
|
508
|
+
const key = jsonInspectionScopeKey(scope);
|
|
509
|
+
if (seen.has(key)) throw Error("Duplicate JSON inspection scope.");
|
|
510
|
+
seen.add(key);
|
|
511
|
+
return { ...scope, state: parseJsonInspectionState(entry.state) };
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
447
515
|
// src/metricNormalize.ts
|
|
448
516
|
var METRIC_OPTION_SPECS = {
|
|
449
517
|
top: {
|
|
@@ -559,16 +627,16 @@ var METRIC_OPTION_SPECS = {
|
|
|
559
627
|
};
|
|
560
628
|
function normalizeMetricOptions(raw) {
|
|
561
629
|
const out = {}, diagnostics = [];
|
|
562
|
-
const
|
|
630
|
+
const record3 = (x) => !!x && typeof x === "object" && !Array.isArray(x);
|
|
563
631
|
const copy = (input, specs) => {
|
|
564
632
|
const result = {};
|
|
565
633
|
for (const [key, spec] of Object.entries(specs)) {
|
|
566
634
|
const v = input[key];
|
|
567
635
|
if (v === void 0) continue;
|
|
568
636
|
if (spec === "minCount") {
|
|
569
|
-
const m =
|
|
637
|
+
const m = record3(v) ? copy(v, METRIC_OPTION_SPECS.minCount) : v;
|
|
570
638
|
const named = (x) => x === void 0 || typeof x === "string" && !!x && x.length <= 256;
|
|
571
|
-
if (
|
|
639
|
+
if (record3(m) ? m.min !== void 0 && m.distinct === void 0 !== (m.sum === void 0) && named(m.distinct) && named(m.sum) : typeof m === "number" && Number.isSafeInteger(m) && m >= 1 && m <= 1e6)
|
|
572
640
|
result[key] = m;
|
|
573
641
|
else diagnostics.push(`Invalid metric ${key}.`);
|
|
574
642
|
continue;
|
|
@@ -584,7 +652,7 @@ function normalizeMetricOptions(raw) {
|
|
|
584
652
|
copy(raw, METRIC_OPTION_SPECS.top)
|
|
585
653
|
);
|
|
586
654
|
if (raw.window !== void 0) {
|
|
587
|
-
if (
|
|
655
|
+
if (record3(raw.window)) {
|
|
588
656
|
const w = copy(raw.window, METRIC_OPTION_SPECS.window);
|
|
589
657
|
const periods = raw.window.periods;
|
|
590
658
|
if (periods === "all" || Number.isSafeInteger(periods) && periods >= 0 && periods <= 1e6)
|
|
@@ -594,12 +662,12 @@ function normalizeMetricOptions(raw) {
|
|
|
594
662
|
} else diagnostics.push("Invalid metric window.");
|
|
595
663
|
}
|
|
596
664
|
if (raw.dateGrouping !== void 0) {
|
|
597
|
-
if (
|
|
665
|
+
if (record3(raw.dateGrouping)) {
|
|
598
666
|
const d = copy(raw.dateGrouping, METRIC_OPTION_SPECS.dateGrouping);
|
|
599
667
|
if (typeof d.field !== "string" || !d.field || d.field.length > 256 || !d.interval || typeof d.includeEmpty !== "boolean" || !d.range)
|
|
600
668
|
diagnostics.push("Invalid metric date grouping.");
|
|
601
669
|
const occurrence = raw.dateGrouping.occurrence;
|
|
602
|
-
if (
|
|
670
|
+
if (record3(occurrence)) {
|
|
603
671
|
const o = copy(occurrence, METRIC_OPTION_SPECS.occurrence);
|
|
604
672
|
if (!o.interval || typeof o.includeEmpty !== "boolean")
|
|
605
673
|
diagnostics.push("Invalid metric date grouping occurrence.");
|
|
@@ -610,32 +678,32 @@ function normalizeMetricOptions(raw) {
|
|
|
610
678
|
} else diagnostics.push("Invalid metric date grouping.");
|
|
611
679
|
}
|
|
612
680
|
if (raw.display !== void 0) {
|
|
613
|
-
if (
|
|
681
|
+
if (record3(raw.display)) {
|
|
614
682
|
if (typeof raw.display.kind !== "string")
|
|
615
683
|
diagnostics.push("Invalid metric display kind.");
|
|
616
684
|
const d = copy(raw.display, METRIC_OPTION_SPECS.display);
|
|
617
685
|
for (const k of ["xScale", "yScale"]) {
|
|
618
|
-
if (
|
|
686
|
+
if (record3(raw.display[k]))
|
|
619
687
|
d[k] = copy(raw.display[k], METRIC_OPTION_SPECS.scale);
|
|
620
688
|
else if (raw.display[k] !== void 0)
|
|
621
689
|
diagnostics.push(`Invalid metric ${k}.`);
|
|
622
690
|
}
|
|
623
691
|
for (const k of ["format", "xFormat", "yFormat"])
|
|
624
|
-
if (
|
|
692
|
+
if (record3(raw.display[k]))
|
|
625
693
|
d[k] = copy(raw.display[k], METRIC_OPTION_SPECS.format);
|
|
626
|
-
if (
|
|
694
|
+
if (record3(raw.display.list))
|
|
627
695
|
d.list = copy(raw.display.list, METRIC_OPTION_SPECS.list);
|
|
628
|
-
if (
|
|
696
|
+
if (record3(raw.display.pivot))
|
|
629
697
|
d.pivot = copy(raw.display.pivot, METRIC_OPTION_SPECS.pivot);
|
|
630
698
|
out.display = { kind: "auto", ...d };
|
|
631
699
|
} else diagnostics.push("Invalid metric display.");
|
|
632
700
|
}
|
|
633
701
|
if (raw.distribution !== void 0) {
|
|
634
|
-
if (
|
|
702
|
+
if (record3(raw.distribution))
|
|
635
703
|
out.distribution = copy(raw.distribution, METRIC_OPTION_SPECS.distribution);
|
|
636
704
|
else diagnostics.push("Invalid metric distribution.");
|
|
637
705
|
}
|
|
638
|
-
if (
|
|
706
|
+
if (record3(raw.layout)) {
|
|
639
707
|
const l = copy(raw.layout, METRIC_OPTION_SPECS.layout);
|
|
640
708
|
for (const k of ["widthRem", "heightRem", "minWidthRem", "minHeightRem"])
|
|
641
709
|
l[k] = Math.max(1, Math.min(1e3, Number(l[k] ?? 1)));
|
|
@@ -647,7 +715,7 @@ function normalizeMetricOptions(raw) {
|
|
|
647
715
|
diagnostics.push("Invalid metric sort.");
|
|
648
716
|
if (Array.isArray(raw.sort))
|
|
649
717
|
out.sort = raw.sort.slice(0, 20).flatMap((s) => {
|
|
650
|
-
if (!
|
|
718
|
+
if (!record3(s) || typeof s.key !== "string" || !/^(value|y|count|samples|group(?:0|[1-9][0-9]?))$/.test(s.key) || !["asc", "desc"].includes(String(s.dir))) {
|
|
651
719
|
diagnostics.push("Invalid metric sort.");
|
|
652
720
|
return [];
|
|
653
721
|
}
|
|
@@ -1387,6 +1455,7 @@ function normalizeQuery(input, fallback, links) {
|
|
|
1387
1455
|
}
|
|
1388
1456
|
if (Object.keys(views).length) details.views = views;
|
|
1389
1457
|
}
|
|
1458
|
+
if (raw.itemDetails.jsonInspections !== void 0) details.jsonInspections = parseJsonInspections(raw.itemDetails.jsonInspections);
|
|
1390
1459
|
const active = raw.itemDetails.active;
|
|
1391
1460
|
if (isRecord(active) && (active.mode === "modal" || active.mode === "expand") && modes.includes(active.mode) && (typeof active.id === "string" && active.id.length > 0 && active.id.length <= 1e3 || typeof active.id === "number" && Number.isFinite(active.id))) {
|
|
1392
1461
|
details.active = { id: active.id, mode: active.mode };
|
|
@@ -1962,11 +2031,11 @@ function localQuerySnapshotCache(options2 = {}) {
|
|
|
1962
2031
|
if (!Number.isInteger(maxEntries) || maxEntries < 1 || !Number.isFinite(maxBytes) || maxBytes < 1) throw Error("Invalid query link cache limits.");
|
|
1963
2032
|
const storage = () => options2.storage ?? globalThis.localStorage;
|
|
1964
2033
|
function read() {
|
|
1965
|
-
const
|
|
1966
|
-
if (!
|
|
2034
|
+
const text2 = storage().getItem(storageKey);
|
|
2035
|
+
if (!text2) return [];
|
|
1967
2036
|
let raw;
|
|
1968
2037
|
try {
|
|
1969
|
-
raw = JSON.parse(
|
|
2038
|
+
raw = JSON.parse(text2);
|
|
1970
2039
|
} catch {
|
|
1971
2040
|
return [];
|
|
1972
2041
|
}
|
|
@@ -1984,12 +2053,12 @@ function localQuerySnapshotCache(options2 = {}) {
|
|
|
1984
2053
|
const entry = entries.find((e) => e.key === key && e.snapshot.code === code);
|
|
1985
2054
|
if (entry) {
|
|
1986
2055
|
entry.durable = true;
|
|
1987
|
-
let
|
|
1988
|
-
while (
|
|
2056
|
+
let text2 = JSON.stringify(entries);
|
|
2057
|
+
while (text2.length * 2 > maxBytes && entries.length > 1) {
|
|
1989
2058
|
entries.splice(entries[0] === entry ? 1 : 0, 1);
|
|
1990
|
-
|
|
2059
|
+
text2 = JSON.stringify(entries);
|
|
1991
2060
|
}
|
|
1992
|
-
if (
|
|
2061
|
+
if (text2.length * 2 <= maxBytes) storage().setItem(storageKey, text2);
|
|
1993
2062
|
}
|
|
1994
2063
|
},
|
|
1995
2064
|
get(key, code) {
|
|
@@ -2003,26 +2072,26 @@ function localQuerySnapshotCache(options2 = {}) {
|
|
|
2003
2072
|
const old = entries.find((e) => e.key === key && e.snapshot.code === snapshot.code);
|
|
2004
2073
|
if (old) {
|
|
2005
2074
|
if (old.snapshot.token !== snapshot.token) throw Error("A query link code cannot be overwritten.");
|
|
2006
|
-
const
|
|
2007
|
-
if (storage().getItem(storageKey) !==
|
|
2075
|
+
const text3 = JSON.stringify(entries);
|
|
2076
|
+
if (storage().getItem(storageKey) !== text3) storage().setItem(storageKey, text3);
|
|
2008
2077
|
return;
|
|
2009
2078
|
}
|
|
2010
2079
|
entries.push({ key, snapshot: validateQuerySnapshot(snapshot) });
|
|
2011
2080
|
while (entries.length > maxEntries) entries.shift();
|
|
2012
|
-
let
|
|
2013
|
-
while (
|
|
2081
|
+
let text2 = JSON.stringify(entries);
|
|
2082
|
+
while (text2.length * 2 > maxBytes && entries.length > 1) {
|
|
2014
2083
|
entries.shift();
|
|
2015
|
-
|
|
2084
|
+
text2 = JSON.stringify(entries);
|
|
2016
2085
|
}
|
|
2017
|
-
if (
|
|
2018
|
-
storage().setItem(storageKey,
|
|
2086
|
+
if (text2.length * 2 > maxBytes) throw Error("This query is too large for the local link cache.");
|
|
2087
|
+
storage().setItem(storageKey, text2);
|
|
2019
2088
|
}
|
|
2020
2089
|
};
|
|
2021
2090
|
}
|
|
2022
2091
|
function memoryQuerySnapshotCache() {
|
|
2023
|
-
let
|
|
2024
|
-
return localQuerySnapshotCache({ storage: { getItem: () =>
|
|
2025
|
-
|
|
2092
|
+
let text2 = null;
|
|
2093
|
+
return localQuerySnapshotCache({ storage: { getItem: () => text2, setItem: (_key, value) => {
|
|
2094
|
+
text2 = value;
|
|
2026
2095
|
} } });
|
|
2027
2096
|
}
|
|
2028
2097
|
var QuerySnapshotHttpError = class extends Error {
|
|
@@ -2061,10 +2130,10 @@ async function snapshotHttpError(response) {
|
|
|
2061
2130
|
bytes.set(chunk, offset);
|
|
2062
2131
|
offset += chunk.length;
|
|
2063
2132
|
}
|
|
2064
|
-
const
|
|
2065
|
-
let reason =
|
|
2133
|
+
const text2 = new TextDecoder().decode(bytes);
|
|
2134
|
+
let reason = text2;
|
|
2066
2135
|
if (type === "application/json") {
|
|
2067
|
-
const body = JSON.parse(
|
|
2136
|
+
const body = JSON.parse(text2);
|
|
2068
2137
|
reason = body?.message ?? body?.error?.message ?? body?.error;
|
|
2069
2138
|
const code2 = body?.code ?? body?.error?.code;
|
|
2070
2139
|
if (typeof code2 === "string" && /^[A-Za-z0-9_.-]{1,64}$/.test(code2)) serverCode = code2;
|
|
@@ -2762,23 +2831,23 @@ function compileFormula(source, fields, resolve, extension) {
|
|
|
2762
2831
|
let match;
|
|
2763
2832
|
if (source[pos] === "[") {
|
|
2764
2833
|
pos++;
|
|
2765
|
-
let
|
|
2834
|
+
let text2 = "";
|
|
2766
2835
|
let closed = false;
|
|
2767
2836
|
while (pos < source.length) {
|
|
2768
2837
|
if (source[pos] === "]") {
|
|
2769
2838
|
if (source[pos + 1] === "]") {
|
|
2770
|
-
|
|
2839
|
+
text2 += "]";
|
|
2771
2840
|
pos += 2;
|
|
2772
2841
|
} else {
|
|
2773
2842
|
pos++;
|
|
2774
2843
|
closed = true;
|
|
2775
2844
|
break;
|
|
2776
2845
|
}
|
|
2777
|
-
} else
|
|
2846
|
+
} else text2 += source[pos++];
|
|
2778
2847
|
}
|
|
2779
2848
|
if (!closed)
|
|
2780
2849
|
throw new FormulaError("Unclosed field reference.", from, pos);
|
|
2781
|
-
tokens.push({ kind: "field", text, from, to: pos });
|
|
2850
|
+
tokens.push({ kind: "field", text: text2, from, to: pos });
|
|
2782
2851
|
} else if (source[pos] === '"') {
|
|
2783
2852
|
pos++;
|
|
2784
2853
|
while (pos < source.length && source[pos] !== '"') {
|
|
@@ -2798,9 +2867,9 @@ function compileFormula(source, fields, resolve, extension) {
|
|
|
2798
2867
|
}
|
|
2799
2868
|
} else if (source[pos] === "'") {
|
|
2800
2869
|
const end = source.indexOf("'", pos + 1);
|
|
2801
|
-
const
|
|
2870
|
+
const text2 = end < 0 ? "" : source.slice(pos + 1, end);
|
|
2802
2871
|
throw new FormulaError(
|
|
2803
|
-
end < 0 ||
|
|
2872
|
+
end < 0 || text2.length > 40 || /["\\\n]/.test(text2) ? 'Text literals use double quotes ("text"), not single quotes.' : `Text literals use double quotes: write "${text2}" instead of '${text2}'.`,
|
|
2804
2873
|
from,
|
|
2805
2874
|
end < 0 ? pos + 1 : end + 1
|
|
2806
2875
|
);
|
|
@@ -3886,24 +3955,24 @@ function planMetricSeries(query, schema, options2 = {}) {
|
|
|
3886
3955
|
);
|
|
3887
3956
|
const plan = compileMetric(source, schema, options2.resolveComputed);
|
|
3888
3957
|
const texts = [];
|
|
3889
|
-
const at = (
|
|
3890
|
-
const index = texts.indexOf(
|
|
3891
|
-
return index < 0 ? texts.push(
|
|
3958
|
+
const at = (text2) => {
|
|
3959
|
+
const index = texts.indexOf(text2);
|
|
3960
|
+
return index < 0 ? texts.push(text2) - 1 : index;
|
|
3892
3961
|
};
|
|
3893
3962
|
let reductions;
|
|
3894
3963
|
if (c.window && (c.window.reduce ?? "total") === "total")
|
|
3895
3964
|
reductions = plan.aggregates.map((node) => {
|
|
3896
|
-
const
|
|
3897
|
-
if (node.name !== "AVG") return { name: node.name, part: at(
|
|
3898
|
-
const input =
|
|
3965
|
+
const text2 = source.slice(node.from, node.to);
|
|
3966
|
+
if (node.name !== "AVG") return { name: node.name, part: at(text2) };
|
|
3967
|
+
const input = text2.slice(text2.indexOf("(") + 1, text2.lastIndexOf(")"));
|
|
3899
3968
|
return { name: "AVG", sum: at(`SUM(${input})`), count: at(`COUNT(${input})`) };
|
|
3900
3969
|
});
|
|
3901
3970
|
else at(source);
|
|
3902
3971
|
const parts = (groupBy) => texts.map(
|
|
3903
|
-
(
|
|
3972
|
+
(text2) => ({
|
|
3904
3973
|
id: id(),
|
|
3905
3974
|
// The whole legacy measure keeps its operation, so v1 servers run it.
|
|
3906
|
-
...
|
|
3975
|
+
...text2 === source && c.expression === void 0 ? { op: c.op, ...c.field ? { field: c.field } : {} } : { op: "count", expression: text2 },
|
|
3907
3976
|
groupBy,
|
|
3908
3977
|
...scoped(groupBy)
|
|
3909
3978
|
})
|
|
@@ -4606,8 +4675,8 @@ function createGroupingModel(inputSchema) {
|
|
|
4606
4675
|
}));
|
|
4607
4676
|
return rows.reduce((best, row) => {
|
|
4608
4677
|
for (const term of terms) {
|
|
4609
|
-
const value = (
|
|
4610
|
-
const raw = term.def ? readFieldValue(term.def,
|
|
4678
|
+
const value = (record3) => {
|
|
4679
|
+
const raw = term.def ? readFieldValue(term.def, record3) : record3[schema.idField];
|
|
4611
4680
|
if (raw == null || term.def?.type !== "datetime") return raw;
|
|
4612
4681
|
const instant = Date.parse(String(raw));
|
|
4613
4682
|
return Number.isFinite(instant) ? instant : null;
|
|
@@ -7364,6 +7433,119 @@ function groupSourceQuery(query, group, schema) {
|
|
|
7364
7433
|
const source = exitGrouping(query);
|
|
7365
7434
|
return { ...source, where: appendWhereTerms(source.where, terms), offset: 0 };
|
|
7366
7435
|
}
|
|
7436
|
+
|
|
7437
|
+
// src/attention.ts
|
|
7438
|
+
function validTarget(target) {
|
|
7439
|
+
return typeof target.dataset === "string" && target.dataset.length > 0 && target.dataset.length <= 256 && (target.rowId === void 0 || typeof target.rowId === "string" && target.rowId.length > 0 && target.rowId.length <= 1e3 || typeof target.rowId === "number" && Number.isFinite(target.rowId)) && (target.field === void 0 || target.rowId !== void 0 && typeof target.field === "string" && target.field.length > 0 && target.field.length <= 256) && (target.path === void 0 || target.field !== void 0 && isJsonPath(target.path));
|
|
7440
|
+
}
|
|
7441
|
+
function attentionTargetKey(target) {
|
|
7442
|
+
return JSON.stringify([target.dataset, target.rowId ?? null, target.field ?? null, target.path ?? null]);
|
|
7443
|
+
}
|
|
7444
|
+
var cancelled = () => new Error("Attention navigation cancelled.");
|
|
7445
|
+
function abortable(promise, signal) {
|
|
7446
|
+
return new Promise((resolve, reject) => {
|
|
7447
|
+
const abort = () => {
|
|
7448
|
+
cleanup();
|
|
7449
|
+
reject(cancelled());
|
|
7450
|
+
};
|
|
7451
|
+
const cleanup = () => signal.removeEventListener("abort", abort);
|
|
7452
|
+
if (signal.aborted) {
|
|
7453
|
+
reject(cancelled());
|
|
7454
|
+
return;
|
|
7455
|
+
}
|
|
7456
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
7457
|
+
promise.then((value) => {
|
|
7458
|
+
cleanup();
|
|
7459
|
+
resolve(value);
|
|
7460
|
+
}, (error) => {
|
|
7461
|
+
cleanup();
|
|
7462
|
+
reject(error);
|
|
7463
|
+
});
|
|
7464
|
+
});
|
|
7465
|
+
}
|
|
7466
|
+
function createAttentionRegistry() {
|
|
7467
|
+
const providers = /* @__PURE__ */ new Map();
|
|
7468
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
7469
|
+
let current;
|
|
7470
|
+
const lookup = (target) => providers.get(attentionTargetKey(target))?.slice(-1)[0];
|
|
7471
|
+
return {
|
|
7472
|
+
cancel() {
|
|
7473
|
+
current?.abort();
|
|
7474
|
+
current = void 0;
|
|
7475
|
+
},
|
|
7476
|
+
register(target, provider) {
|
|
7477
|
+
if (!validTarget(target)) throw Error("Invalid semantic attention target.");
|
|
7478
|
+
const key = attentionTargetKey(target);
|
|
7479
|
+
const entries = providers.get(key) ?? [];
|
|
7480
|
+
providers.set(key, [...entries, provider]);
|
|
7481
|
+
listeners.forEach((listener) => listener());
|
|
7482
|
+
return () => {
|
|
7483
|
+
const remaining = providers.get(key)?.filter((entry) => entry !== provider) ?? [];
|
|
7484
|
+
if (remaining.length) providers.set(key, remaining);
|
|
7485
|
+
else providers.delete(key);
|
|
7486
|
+
};
|
|
7487
|
+
},
|
|
7488
|
+
whenRegistered(target, signal, except) {
|
|
7489
|
+
return new Promise((resolve, reject) => {
|
|
7490
|
+
const cleanup = () => {
|
|
7491
|
+
listeners.delete(check);
|
|
7492
|
+
signal.removeEventListener("abort", abort);
|
|
7493
|
+
};
|
|
7494
|
+
const abort = () => {
|
|
7495
|
+
cleanup();
|
|
7496
|
+
reject(cancelled());
|
|
7497
|
+
};
|
|
7498
|
+
const check = () => {
|
|
7499
|
+
const provider = lookup(target);
|
|
7500
|
+
if (provider && provider !== except) {
|
|
7501
|
+
cleanup();
|
|
7502
|
+
resolve(provider);
|
|
7503
|
+
}
|
|
7504
|
+
};
|
|
7505
|
+
if (signal.aborted) {
|
|
7506
|
+
reject(cancelled());
|
|
7507
|
+
return;
|
|
7508
|
+
}
|
|
7509
|
+
listeners.add(check);
|
|
7510
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
7511
|
+
check();
|
|
7512
|
+
});
|
|
7513
|
+
},
|
|
7514
|
+
async resolve(target, options2) {
|
|
7515
|
+
current?.abort();
|
|
7516
|
+
const controller = new AbortController();
|
|
7517
|
+
current = controller;
|
|
7518
|
+
const signal = controller.signal;
|
|
7519
|
+
const abort = () => controller.abort();
|
|
7520
|
+
options2?.signal?.addEventListener("abort", abort, { once: true });
|
|
7521
|
+
if (options2?.signal?.aborted) controller.abort();
|
|
7522
|
+
const result = (status) => ({ status, target });
|
|
7523
|
+
try {
|
|
7524
|
+
if (signal.aborted) return result("cancelled");
|
|
7525
|
+
if (!validTarget(target)) return result("unavailable");
|
|
7526
|
+
const candidates = [
|
|
7527
|
+
target,
|
|
7528
|
+
{ dataset: target.dataset, ...target.rowId !== void 0 ? { rowId: target.rowId } : {}, ...target.field !== void 0 ? { field: target.field } : {} },
|
|
7529
|
+
{ dataset: target.dataset, ...target.rowId !== void 0 ? { rowId: target.rowId } : {} },
|
|
7530
|
+
{ dataset: target.dataset }
|
|
7531
|
+
];
|
|
7532
|
+
const provider = candidates.map(lookup).find(Boolean);
|
|
7533
|
+
if (!provider) return result("unavailable");
|
|
7534
|
+
if (provider.ready) await abortable(provider.ready(signal), signal);
|
|
7535
|
+
if (provider.materialize && !await abortable(Promise.resolve(provider.materialize(target, signal)), signal)) return result("unavailable");
|
|
7536
|
+
if (signal.aborted) return result("cancelled");
|
|
7537
|
+
const revealed = await abortable(Promise.resolve(provider.reveal(target, signal)), signal);
|
|
7538
|
+
return result(signal.aborted ? "cancelled" : revealed ? "revealed" : "unavailable");
|
|
7539
|
+
} catch (error) {
|
|
7540
|
+
if (signal.aborted) return result("cancelled");
|
|
7541
|
+
throw error;
|
|
7542
|
+
} finally {
|
|
7543
|
+
options2?.signal?.removeEventListener("abort", abort);
|
|
7544
|
+
if (current === controller) current = void 0;
|
|
7545
|
+
}
|
|
7546
|
+
}
|
|
7547
|
+
};
|
|
7548
|
+
}
|
|
7367
7549
|
export {
|
|
7368
7550
|
AGG_OPS_BY_TYPE,
|
|
7369
7551
|
AGG_OPS_NEEDING_FIELD,
|
|
@@ -7381,6 +7563,8 @@ export {
|
|
|
7381
7563
|
MAX_HOST_QUERY_STATE_BYTES,
|
|
7382
7564
|
MAX_HOST_QUERY_VALUES,
|
|
7383
7565
|
MAX_HOST_QUERY_VALUE_LENGTH,
|
|
7566
|
+
MAX_JSON_INSPECTIONS,
|
|
7567
|
+
MAX_JSON_PATHS,
|
|
7384
7568
|
MAX_METRIC_WINDOW_PERIODS,
|
|
7385
7569
|
MAX_ORDER_BY_TERMS,
|
|
7386
7570
|
MAX_PROPERTIES,
|
|
@@ -7408,6 +7592,7 @@ export {
|
|
|
7408
7592
|
applyAggregations,
|
|
7409
7593
|
applyPatch,
|
|
7410
7594
|
applyQuery,
|
|
7595
|
+
attentionTargetKey,
|
|
7411
7596
|
boxSummary,
|
|
7412
7597
|
branchesOf,
|
|
7413
7598
|
calendarGroupKey,
|
|
@@ -7416,6 +7601,7 @@ export {
|
|
|
7416
7601
|
compileFormula,
|
|
7417
7602
|
compileMetric,
|
|
7418
7603
|
computedFieldName,
|
|
7604
|
+
createAttentionRegistry,
|
|
7419
7605
|
createGroupingModel,
|
|
7420
7606
|
createPropertyView,
|
|
7421
7607
|
createQueryLinkService,
|
|
@@ -7451,17 +7637,21 @@ export {
|
|
|
7451
7637
|
isGroupLinkValue,
|
|
7452
7638
|
isGroupable,
|
|
7453
7639
|
isGroupingTimeZone,
|
|
7640
|
+
isJsonBucketId,
|
|
7641
|
+
isJsonPath,
|
|
7454
7642
|
isMeasurable,
|
|
7455
7643
|
isMetricCycle,
|
|
7456
7644
|
isNegativePredicate,
|
|
7457
7645
|
isOrGroup,
|
|
7458
7646
|
isOrOfAndsGroup,
|
|
7647
|
+
isPropertyFieldLoaded,
|
|
7459
7648
|
isPushdownFilter,
|
|
7460
7649
|
isSelectable,
|
|
7461
7650
|
isSortable,
|
|
7462
7651
|
isWhereConjunction,
|
|
7463
7652
|
isWhereGroup,
|
|
7464
7653
|
itemPageFields,
|
|
7654
|
+
jsonInspectionScopeKey,
|
|
7465
7655
|
jsonPropertyViewStorage,
|
|
7466
7656
|
loadSchema,
|
|
7467
7657
|
localPropertyViewStorage,
|
|
@@ -7504,6 +7694,8 @@ export {
|
|
|
7504
7694
|
opPairsForField,
|
|
7505
7695
|
opsForField,
|
|
7506
7696
|
parseHostQueryState,
|
|
7697
|
+
parseJsonInspectionState,
|
|
7698
|
+
parseJsonInspections,
|
|
7507
7699
|
parseRelativeDuration,
|
|
7508
7700
|
percentile,
|
|
7509
7701
|
planMetricSeries,
|