@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.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 record2 = raw;
27
- if (typeof record2.kind !== "string" || !Object.prototype.hasOwnProperty.call(options, record2.kind)) return fail("unsupported kind");
28
- const allowed = options[record2.kind];
29
- for (const [key, value] of Object.entries(record2)) {
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
- ...record2,
44
- ...record2.labels ? { labels: { ...record2.labels } } : {},
45
- ...record2.tones ? { tones: { ...record2.tones } } : {}
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 record2 = (x) => !!x && typeof x === "object" && !Array.isArray(x);
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 = record2(v) ? copy(v, METRIC_OPTION_SPECS.minCount) : v;
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 (record2(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)
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 (record2(raw.window)) {
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 (record2(raw.dateGrouping)) {
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 (record2(occurrence)) {
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 (record2(raw.display)) {
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 (record2(raw.display[k]))
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 (record2(raw.display[k]))
692
+ if (record3(raw.display[k]))
625
693
  d[k] = copy(raw.display[k], METRIC_OPTION_SPECS.format);
626
- if (record2(raw.display.list))
694
+ if (record3(raw.display.list))
627
695
  d.list = copy(raw.display.list, METRIC_OPTION_SPECS.list);
628
- if (record2(raw.display.pivot))
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 (record2(raw.distribution))
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 (record2(raw.layout)) {
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 (!record2(s) || typeof s.key !== "string" || !/^(value|y|count|samples|group(?:0|[1-9][0-9]?))$/.test(s.key) || !["asc", "desc"].includes(String(s.dir))) {
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 text = storage().getItem(storageKey);
1966
- if (!text) return [];
2034
+ const text2 = storage().getItem(storageKey);
2035
+ if (!text2) return [];
1967
2036
  let raw;
1968
2037
  try {
1969
- raw = JSON.parse(text);
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 text = JSON.stringify(entries);
1988
- while (text.length * 2 > maxBytes && entries.length > 1) {
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
- text = JSON.stringify(entries);
2059
+ text2 = JSON.stringify(entries);
1991
2060
  }
1992
- if (text.length * 2 <= maxBytes) storage().setItem(storageKey, text);
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 text2 = JSON.stringify(entries);
2007
- if (storage().getItem(storageKey) !== text2) storage().setItem(storageKey, text2);
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 text = JSON.stringify(entries);
2013
- while (text.length * 2 > maxBytes && entries.length > 1) {
2081
+ let text2 = JSON.stringify(entries);
2082
+ while (text2.length * 2 > maxBytes && entries.length > 1) {
2014
2083
  entries.shift();
2015
- text = JSON.stringify(entries);
2084
+ text2 = JSON.stringify(entries);
2016
2085
  }
2017
- if (text.length * 2 > maxBytes) throw Error("This query is too large for the local link cache.");
2018
- storage().setItem(storageKey, text);
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 text = null;
2024
- return localQuerySnapshotCache({ storage: { getItem: () => text, setItem: (_key, value) => {
2025
- text = value;
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 text = new TextDecoder().decode(bytes);
2065
- let reason = text;
2133
+ const text2 = new TextDecoder().decode(bytes);
2134
+ let reason = text2;
2066
2135
  if (type === "application/json") {
2067
- const body = JSON.parse(text);
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 text = "";
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
- text += "]";
2839
+ text2 += "]";
2771
2840
  pos += 2;
2772
2841
  } else {
2773
2842
  pos++;
2774
2843
  closed = true;
2775
2844
  break;
2776
2845
  }
2777
- } else text += source[pos++];
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 text = end < 0 ? "" : source.slice(pos + 1, end);
2870
+ const text2 = end < 0 ? "" : source.slice(pos + 1, end);
2802
2871
  throw new FormulaError(
2803
- end < 0 || text.length > 40 || /["\\\n]/.test(text) ? 'Text literals use double quotes ("text"), not single quotes.' : `Text literals use double quotes: write "${text}" instead of '${text}'.`,
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 = (text) => {
3890
- const index = texts.indexOf(text);
3891
- return index < 0 ? texts.push(text) - 1 : index;
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 text = source.slice(node.from, node.to);
3897
- if (node.name !== "AVG") return { name: node.name, part: at(text) };
3898
- const input = text.slice(text.indexOf("(") + 1, text.lastIndexOf(")"));
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
- (text) => ({
3972
+ (text2) => ({
3904
3973
  id: id(),
3905
3974
  // The whole legacy measure keeps its operation, so v1 servers run it.
3906
- ...text === source && c.expression === void 0 ? { op: c.op, ...c.field ? { field: c.field } : {} } : { op: "count", expression: text },
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 = (record2) => {
4610
- const raw = term.def ? readFieldValue(term.def, record2) : record2[schema.idField];
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,