@milaboratories/graph-maker 1.1.157 → 1.1.158

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.
Files changed (65) hide show
  1. package/dist/GraphMaker/constantsCommon.d.ts +1 -0
  2. package/dist/GraphMaker/constantsCommon.d.ts.map +1 -1
  3. package/dist/GraphMaker/constantsCommon.js +17 -16
  4. package/dist/GraphMaker/constantsCommon.js.map +1 -1
  5. package/dist/GraphMaker/forms/AxesSettingsForm/HeatmapAxesSettingsForm.vue.d.ts.map +1 -1
  6. package/dist/GraphMaker/forms/AxesSettingsForm/HeatmapAxesSettingsForm.vue.js +104 -93
  7. package/dist/GraphMaker/forms/AxesSettingsForm/HeatmapAxesSettingsForm.vue.js.map +1 -1
  8. package/dist/GraphMaker/index.vue.js +33 -33
  9. package/dist/GraphMaker/index.vue.js.map +1 -1
  10. package/dist/GraphMaker/utils/createChartSettingsForRender/composeHeatmapSettings.d.ts +1 -0
  11. package/dist/GraphMaker/utils/createChartSettingsForRender/composeHeatmapSettings.d.ts.map +1 -1
  12. package/dist/GraphMaker/utils/createChartSettingsForRender/composeHeatmapSettings.js +11 -11
  13. package/dist/GraphMaker/utils/createChartSettingsForRender/composeHeatmapSettings.js.map +1 -1
  14. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/ChartRenderer.js +136 -135
  15. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/ChartRenderer.js.map +1 -1
  16. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/HeatmapSettingsImpl.js +2 -2
  17. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/HeatmapSettingsImpl.js.map +1 -1
  18. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/Annotation.js +115 -107
  19. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/Annotation.js.map +1 -1
  20. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/AnnotationCellsCanvas.js +99 -0
  21. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/AnnotationCellsCanvas.js.map +1 -0
  22. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/AnnotationCellsSvg.js +57 -0
  23. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/AnnotationCellsSvg.js.map +1 -0
  24. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/index.js +43 -43
  25. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Annotations/index.js.map +1 -1
  26. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/CanvasCells.js +85 -0
  27. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/CanvasCells.js.map +1 -0
  28. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Captions/AxisCaptions.js +5 -5
  29. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Captions/GroupCaptions.js +16 -16
  30. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Chart.js +191 -197
  31. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/Chart.js.map +1 -1
  32. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/ChartsGroup.js +29 -27
  33. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/ChartsGroup.js.map +1 -1
  34. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/SvgCells.js +38 -0
  35. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/SvgCells.js.map +1 -0
  36. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/tooltipUtils.js +44 -0
  37. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/components/tooltipUtils.js.map +1 -0
  38. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/constants.js +16 -15
  39. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/constants.js.map +1 -1
  40. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getCells.js +63 -66
  41. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getCells.js.map +1 -1
  42. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/index.js +64 -62
  43. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/index.js.map +1 -1
  44. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/utils/calculateChartSideElementSizes.js +9 -9
  45. package/dist/node_modules/@milaboratories/miplots4/dist/histogram/components/ChartsGroup.js +14 -14
  46. package/dist/node_modules/@milaboratories/miplots4/dist/types/heatmap.js +5 -4
  47. package/dist/node_modules/@milaboratories/miplots4/dist/types/heatmap.js.map +1 -1
  48. package/dist/node_modules/@milaboratories/pf-plots/dist/constants.js +10 -8
  49. package/dist/node_modules/@milaboratories/pf-plots/dist/constants.js.map +1 -1
  50. package/dist/node_modules/@milaboratories/pf-plots/dist/controllers/ComponentController.js +21 -21
  51. package/dist/node_modules/@milaboratories/pf-plots/dist/controllers/controllersByChartType/bubble.js +19 -19
  52. package/dist/node_modules/@milaboratories/pf-plots/dist/controllers/controllersByChartType/heatmap.js +8 -8
  53. package/dist/node_modules/@milaboratories/pf-plots/dist/controllers/controllersByChartType/scatterplot-umap.js +9 -9
  54. package/dist/node_modules/@milaboratories/pf-plots/dist/controllers/controllersByChartType/scatterplot.js +7 -7
  55. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@milaboratories/pl-model-common/dist/drivers/blob.js +2 -2
  56. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@milaboratories/pl-model-common/dist/drivers/blob.js.map +1 -1
  57. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js +59 -57
  58. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js.map +1 -1
  59. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@platforma-sdk/model/dist/components/PlDataTable.js.map +1 -1
  60. package/dist/node_modules/@milaboratories/pf-plots/dist/node_modules/@platforma-sdk/model/dist/render/util/label.js +13 -13
  61. package/dist/node_modules/@milaboratories/pf-plots/dist/pframe/ColumnsProvider.js +137 -133
  62. package/dist/node_modules/@milaboratories/pf-plots/dist/pframe/ColumnsProvider.js.map +1 -1
  63. package/dist/node_modules/@milaboratories/pf-plots/dist/utils.js +74 -74
  64. package/dist/node_modules/@milaboratories/pf-plots/dist/utils.js.map +1 -1
  65. package/package.json +3 -3
@@ -1,7 +1,7 @@
1
1
  import { ensureError as A } from "../../../errors.js";
2
2
  import { canonicalizeJson as l } from "../../../json.js";
3
3
  import o from "../../../../../../zod/lib/index.js";
4
- const V = {
4
+ const w = {
5
5
  Int: "Int",
6
6
  Long: "Long",
7
7
  Float: "Float",
@@ -12,16 +12,16 @@ const V = {
12
12
  function m(n, e) {
13
13
  return n == null ? void 0 : n[e];
14
14
  }
15
- function g(n, e, t, a = "readMetadataJsonOrThrow") {
16
- const r = m(n, t);
17
- if (r === void 0)
15
+ function g(n, e, t, r = "readMetadataJsonOrThrow") {
16
+ const a = m(n, t);
17
+ if (a === void 0)
18
18
  return;
19
19
  const s = e[t];
20
20
  try {
21
- const i = JSON.parse(r);
21
+ const i = JSON.parse(a);
22
22
  return s.parse(i);
23
23
  } catch (i) {
24
- throw new Error(`${a} failed, key: ${String(t)}, value: ${r}, error: ${A(i)}`);
24
+ throw new Error(`${r} failed, key: ${String(t)}, value: ${a}, error: ${A(i)}`);
25
25
  }
26
26
  }
27
27
  function b(n, e, t) {
@@ -37,6 +37,7 @@ const p = {
37
37
  IsVirtual: "pl7.app/graph/isVirtual"
38
38
  },
39
39
  HideDataFromUi: "pl7.app/hideDataFromUi",
40
+ HideDataFromGraphs: "pl7.app/hideDataFromGraphs",
40
41
  IsLinkerColumn: "pl7.app/isLinkerColumn",
41
42
  Label: "pl7.app/label",
42
43
  Max: "pl7.app/max",
@@ -56,6 +57,7 @@ const p = {
56
57
  [p.DiscreteValues]: o.array(o.string()).or(o.array(o.number())),
57
58
  [p.Graph.IsVirtual]: o.boolean(),
58
59
  [p.HideDataFromUi]: o.boolean(),
60
+ [p.HideDataFromGraphs]: o.boolean(),
59
61
  [p.IsLinkerColumn]: o.boolean(),
60
62
  [p.Max]: o.number(),
61
63
  [p.Min]: o.number(),
@@ -65,7 +67,7 @@ const p = {
65
67
  [p.Table.OrderPriority]: o.number(),
66
68
  [p.Trace]: o.record(o.string(), o.unknown())
67
69
  };
68
- function D(n, e) {
70
+ function J(n, e) {
69
71
  return m(n == null ? void 0 : n.annotations, e);
70
72
  }
71
73
  function S(n, e) {
@@ -74,113 +76,113 @@ function S(n, e) {
74
76
  function u(n) {
75
77
  return { axis: n, children: [] };
76
78
  }
77
- function M(n) {
79
+ function D(n) {
78
80
  const e = u(n);
79
81
  let t = [e];
80
82
  for (; t.length; ) {
81
- const a = [];
82
- for (const r of t)
83
- r.children = r.axis.parentAxesSpec.map(u), a.push(...r.children);
84
- t = a;
83
+ const r = [];
84
+ for (const a of t)
85
+ a.children = a.axis.parentAxesSpec.map(u), r.push(...a.children);
86
+ t = r;
85
87
  }
86
88
  return e;
87
89
  }
88
- function I(n) {
90
+ function F(n) {
89
91
  const e = [n.axis];
90
92
  let t = [n];
91
93
  for (; t.length; ) {
92
- const a = [];
93
- for (const r of t)
94
- for (const s of r.children)
95
- e.push(s.axis), a.push(s);
96
- t = a;
94
+ const r = [];
95
+ for (const a of t)
96
+ for (const s of a.children)
97
+ e.push(s.axis), r.push(s);
98
+ t = r;
97
99
  }
98
100
  return e;
99
101
  }
100
- function d(n) {
101
- return l(I(M(n)).map(f));
102
+ function f(n) {
103
+ return l(F(D(n)).map(d));
102
104
  }
103
- function P(n, e) {
105
+ function I(n, e) {
104
106
  if (n.name !== e.name)
105
107
  return n.name < e.name ? 1 : -1;
106
108
  if (n.type !== e.type)
107
109
  return n.type < e.type ? 1 : -1;
108
- const t = l(n.domain ?? {}), a = l(e.domain ?? {});
109
- if (t !== a)
110
- return t < a ? 1 : -1;
111
- const r = d(n), s = d(e);
112
- if (r !== s)
113
- return r < s ? 1 : -1;
110
+ const t = l(n.domain ?? {}), r = l(e.domain ?? {});
111
+ if (t !== r)
112
+ return t < r ? 1 : -1;
113
+ const a = f(n), s = f(e);
114
+ if (a !== s)
115
+ return a < s ? 1 : -1;
114
116
  const i = l(n.annotations ?? {}), c = l(e.annotations ?? {});
115
117
  return i !== c ? i < c ? 1 : -1 : 0;
116
118
  }
117
- function T(n) {
119
+ function M(n) {
118
120
  const e = S(n, p.Parents);
119
121
  return e === void 0 ? [] : e;
120
122
  }
121
123
  function h(n) {
122
- n.parentAxesSpec.forEach(h), n.parentAxesSpec.sort(P);
124
+ n.parentAxesSpec.forEach(h), n.parentAxesSpec.sort(I);
123
125
  }
124
- function L(n) {
126
+ function P(n) {
125
127
  let e = [u(n)];
126
- const t = new Set(l(f(n)));
128
+ const t = new Set(l(d(n)));
127
129
  for (; e.length; ) {
128
- const a = [], r = /* @__PURE__ */ new Set();
130
+ const r = [], a = /* @__PURE__ */ new Set();
129
131
  for (const s of e) {
130
132
  s.children = s.axis.parentAxesSpec.map(u);
131
133
  for (const i of s.children) {
132
- const c = l(f(i.axis));
133
- if (!r.has(c)) {
134
- if (a.push(i), r.add(c), t.has(c))
134
+ const c = l(d(i.axis));
135
+ if (!a.has(c)) {
136
+ if (r.push(i), a.add(c), t.has(c))
135
137
  return !0;
136
138
  t.add(c);
137
139
  }
138
140
  }
139
141
  }
140
- e = a;
142
+ e = r;
141
143
  }
142
144
  return !1;
143
145
  }
144
- function F(n) {
146
+ function O(n) {
145
147
  if (!n.length)
146
148
  return [];
147
149
  const e = n.map((t) => {
148
- const { parentAxes: a, ...r } = t;
149
- return { ...r, annotations: { ...r.annotations }, parentAxesSpec: [] };
150
+ const { parentAxes: r, ...a } = t;
151
+ return { ...a, annotations: { ...a.annotations }, parentAxesSpec: [] };
150
152
  });
151
- return n.forEach((t, a) => {
152
- var r;
153
- const s = e[a];
153
+ return n.forEach((t, r) => {
154
+ var a;
155
+ const s = e[r];
154
156
  if (t.parentAxes)
155
157
  s.parentAxesSpec = t.parentAxes.map((i) => e[i]);
156
158
  else {
157
- const i = T(t).map((c) => e.find((x) => x.name === c));
158
- s.parentAxesSpec = i.some((c) => c === void 0) ? [] : i, (r = s.annotations) == null || delete r[p.Parents];
159
+ const i = M(t).map((c) => e.find((x) => x.name === c));
160
+ s.parentAxesSpec = i.some((c) => c === void 0) ? [] : i, (a = s.annotations) == null || delete a[p.Parents];
159
161
  }
160
- }), e.some(L) ? e.forEach((t) => {
162
+ }), e.some(P) ? e.forEach((t) => {
161
163
  t.parentAxesSpec = [];
162
164
  }) : e.forEach((t) => {
163
165
  h(t);
164
166
  }), e;
165
167
  }
166
- const O = {
168
+ const V = {
167
169
  Label: "pl7.app/label"
168
170
  };
169
- function f(n) {
170
- const { type: e, name: t, domain: a } = n, r = { type: e, name: t };
171
- return a && Object.entries(a).length > 0 && Object.assign(r, { domain: a }), r;
171
+ function d(n) {
172
+ const { type: e, name: t, domain: r } = n, a = { type: e, name: t };
173
+ return r && Object.entries(r).length > 0 && Object.assign(a, { domain: r }), a;
172
174
  }
173
175
  export {
174
176
  p as Annotation,
175
177
  y as AnnotationJson,
176
- O as PColumnName,
177
- V as ValueType,
178
- d as canonicalizeAxisWithParents,
179
- I as getArrayFromAxisTree,
180
- M as getAxesTree,
181
- f as getAxisId,
182
- F as getNormalizedAxesList,
183
- D as readAnnotation,
178
+ V as PColumnName,
179
+ w as ValueType,
180
+ f as canonicalizeAxisWithParents,
181
+ F as getArrayFromAxisTree,
182
+ D as getAxesTree,
183
+ d as getAxisId,
184
+ O as getNormalizedAxesList,
185
+ J as readAnnotation,
184
186
  S as readAnnotationJson,
185
187
  m as readMetadata,
186
188
  b as readMetadataJson,
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sources":["../../../../../../../../../../../../node_modules/@milaboratories/pf-plots/node_modules/@milaboratories/pl-model-common/src/drivers/pframe/spec/spec.ts"],"sourcesContent":["import { ensureError } from '../../../errors';\nimport {\n canonicalizeJson,\n type CanonicalizedJson,\n type StringifiedJson,\n} from '../../../json';\nimport type {\n PObject,\n PObjectId,\n PObjectSpec,\n} from '../../../pool';\nimport { z } from 'zod';\n\ntype Expect<T extends true> = T;\ntype Equal<X, Y> =\n (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;\n\nexport const ValueType = {\n Int: 'Int',\n Long: 'Long',\n Float: 'Float',\n Double: 'Double',\n String: 'String',\n Bytes: 'Bytes',\n} as const;\n\n/** PFrame columns and axes within them may store one of these types. */\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport type Metadata = Record<string, string>;\n\nexport function readMetadata<U extends Metadata, T extends keyof U = keyof U>(\n metadata: Metadata | undefined,\n key: T,\n): U[T] | undefined {\n return (metadata as U | undefined)?.[key];\n}\n\ntype MetadataJsonImpl<M> = {\n [P in keyof M as (M[P] extends StringifiedJson ? P : never)]: M[P] extends StringifiedJson<infer U> ? z.ZodType<U> : never;\n};\nexport type MetadataJson<M> = MetadataJsonImpl<Required<M>>;\n\nexport function readMetadataJsonOrThrow<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n methodNameInError: string = 'readMetadataJsonOrThrow',\n): z.infer<MetadataJson<M>[T]> | undefined {\n const json = readMetadata<M, T>(metadata, key);\n if (json === undefined) return undefined;\n\n const schema = metadataJson[key];\n try {\n const value = JSON.parse(json);\n return schema.parse(value);\n } catch (error: unknown) {\n throw new Error(\n `${methodNameInError} failed, `\n + `key: ${String(key)}, `\n + `value: ${json}, `\n + `error: ${ensureError(error)}`,\n );\n }\n}\n\nexport function readMetadataJson<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n): z.infer<MetadataJson<M>[T]> | undefined {\n try {\n return readMetadataJsonOrThrow(metadata, metadataJson, key);\n } catch {\n return undefined; // treat invalid values as unset\n }\n}\n\n/// Well-known domains\nexport const Domain = {\n Alphabet: 'pl7.app/alphabet',\n BlockId: 'pl7.app/blockId',\n} as const;\n\nexport type Domain = Metadata & Partial<{\n [Domain.Alphabet]: 'nucleotide' | 'aminoacid' | string;\n [Domain.BlockId]: string;\n}>;\n\nexport type DomainJson = MetadataJson<Domain>;\nexport const DomainJson: DomainJson = {};\n\n/// Helper function for reading plain domain values\nexport function readDomain<T extends keyof Domain>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): Domain[T] | undefined {\n return readMetadata<Domain, T>(spec?.domain, key);\n}\n\n/// Helper function for reading json-encoded domain values, throws on JSON parsing error\nexport function readDomainJsonOrThrow<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJsonOrThrow<Domain, T>(spec?.domain, DomainJson, key, 'readDomainJsonOrThrow');\n}\n\n/// Helper function for reading json-encoded domain values, returns undefined on JSON parsing error\nexport function readDomainJson<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJson<Domain, T>(spec?.domain, DomainJson, key);\n}\n\n/// Well-known annotations\nexport const Annotation = {\n Alphabet: 'pl7.app/alphabet',\n DiscreteValues: 'pl7.app/discreteValues',\n Format: 'pl7.app/format',\n Graph: {\n IsVirtual: 'pl7.app/graph/isVirtual',\n },\n HideDataFromUi: 'pl7.app/hideDataFromUi',\n IsLinkerColumn: 'pl7.app/isLinkerColumn',\n Label: 'pl7.app/label',\n Max: 'pl7.app/max',\n Min: 'pl7.app/min',\n Parents: 'pl7.app/parents',\n Sequence: {\n Annotation: {\n Mapping: 'pl7.app/sequence/annotation/mapping',\n },\n IsAnnotation: 'pl7.app/sequence/isAnnotation',\n },\n Table: {\n FontFamily: 'pl7.app/table/fontFamily',\n OrderPriority: 'pl7.app/table/orderPriority',\n Visibility: 'pl7.app/table/visibility',\n },\n Trace: 'pl7.app/trace',\n} as const;\n\nexport type Annotation = Metadata & Partial<{\n [Annotation.Alphabet]: 'nucleotide' | 'aminoacid' | string;\n [Annotation.DiscreteValues]: StringifiedJson<number[]> | StringifiedJson<string[]>;\n [Annotation.Format]: string;\n [Annotation.Graph.IsVirtual]: StringifiedJson<boolean>;\n [Annotation.HideDataFromUi]: StringifiedJson<boolean>;\n [Annotation.IsLinkerColumn]: StringifiedJson<boolean>;\n [Annotation.Label]: string;\n [Annotation.Max]: StringifiedJson<number>;\n [Annotation.Min]: StringifiedJson<number>;\n [Annotation.Parents]: StringifiedJson<AxisSpec['name'][]>;\n [Annotation.Sequence.Annotation.Mapping]: StringifiedJson<Record<string, string>>;\n [Annotation.Sequence.IsAnnotation]: StringifiedJson<boolean>;\n [Annotation.Table.FontFamily]: string;\n [Annotation.Table.OrderPriority]: StringifiedJson<number>;\n [Annotation.Table.Visibility]: 'hidden' | 'optional' | string;\n [Annotation.Trace]: StringifiedJson<Record<string, unknown>>;\n}>;\n\n// export const AxisSpec = z.object({\n// type: z.nativeEnum(ValueType),\n// name: z.string(),\n// domain: z.record(z.string(), z.string()).optional(),\n// annotations: z.record(z.string(), z.string()).optional(),\n// parentAxes: z.array(z.number()).optional(),\n// }).passthrough();\n// type _test = Expect<Equal<\n// Readonly<z.infer<typeof AxisSpec>>,\n// Readonly<AxisSpec & Record<string, unknown>>\n// >>;\n\nexport type AnnotationJson = MetadataJson<Annotation>;\nexport const AnnotationJson: AnnotationJson = {\n [Annotation.DiscreteValues]: z.array(z.string()).or(z.array(z.number())),\n [Annotation.Graph.IsVirtual]: z.boolean(),\n [Annotation.HideDataFromUi]: z.boolean(),\n [Annotation.IsLinkerColumn]: z.boolean(),\n [Annotation.Max]: z.number(),\n [Annotation.Min]: z.number(),\n [Annotation.Parents]: z.array(z.string()),\n [Annotation.Sequence.Annotation.Mapping]: z.record(z.string(), z.string()),\n [Annotation.Sequence.IsAnnotation]: z.boolean(),\n [Annotation.Table.OrderPriority]: z.number(),\n [Annotation.Trace]: z.record(z.string(), z.unknown()),\n};\n\n/// Helper function for reading plain annotation values\nexport function readAnnotation<T extends keyof Annotation>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): Annotation[T] | undefined {\n return readMetadata<Annotation, T>(spec?.annotations, key);\n}\n\n/// Helper function for reading json-encoded annotation values, throws on JSON parsing error\nexport function readAnnotationJsonOrThrow<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJsonOrThrow<Annotation, T>(spec?.annotations, AnnotationJson, key, 'readAnnotationJsonOrThrow');\n}\n\n/// Helper function for reading json-encoded annotation values, returns undefined on JSON parsing error\nexport function readAnnotationJson<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJson<Annotation, T>(spec?.annotations, AnnotationJson, key);\n}\n\n/**\n * Specification of an individual axis.\n *\n * Each axis is a part of a composite key that addresses data inside the PColumn.\n *\n * Each record inside a PColumn is addressed by a unique tuple of values set for\n * all the axes specified in the column spec.\n * */\nexport interface AxisSpec {\n /** Type of the axis value. Should not use non-key types like float or double. */\n readonly type: ValueType;\n\n /** Name of the axis */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Any additional information attached to the axis that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /**\n * Parent axes provide contextual grouping for the axis in question, establishing\n * a hierarchy where the current axis is dependent on one or more axes for its\n * full definition and meaning. For instance, in a data structure where each\n * \"container\" axis may contain multiple \"item\" axes, the `item` axis would\n * list the index of the `container` axis in this field to denote its dependency.\n *\n * This means that the identity or significance of the `item` axis is only\n * interpretable when combined with its parent `container` axis. An `item` axis\n * index by itself may be non-unique and only gains uniqueness within the context\n * of its parent `container`. Therefore, the `parentAxes` field is essential for\n * mapping these relationships and ensuring data coherence across nested or\n * multi-level data models.\n *\n * A list of zero-based indices of parent axes in the overall axes specification\n * from the column spec. Each index corresponds to the position of a parent axis\n * in the list that defines the structure of the data model.\n */\n readonly parentAxes?: number[];\n}\n\n/** Parents are specs, not indexes; normalized axis can be used considering its parents independently from column */\nexport interface AxisSpecNormalized extends Omit<AxisSpec, 'parentAxes'> {\n parentAxesSpec: AxisSpecNormalized[];\n}\n\n/** Tree: axis is a root, its parents are children */\nexport type AxisTree = {\n axis: AxisSpecNormalized;\n children: AxisTree[]; // parents\n};\n\nfunction makeAxisTree(axis: AxisSpecNormalized): AxisTree {\n return { axis, children: [] };\n}\n\n/** Build tree by axis parents annotations */\nexport function getAxesTree(rootAxis: AxisSpecNormalized): AxisTree {\n const root = makeAxisTree(rootAxis);\n let nodesQ = [root];\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n nextNodes.push(...node.children);\n }\n nodesQ = nextNodes;\n }\n return root;\n}\n\n/** Get set of canonicalized axisIds from axisTree */\nexport function getSetFromAxisTree(tree: AxisTree): Set<CanonicalizedJson<AxisId>> {\n const set = new Set([canonicalizeJson(getAxisId(tree.axis))]);\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n set.add(canonicalizeJson(getAxisId(parent.axis)));\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return set;\n}\n\n/** Get array of axisSpecs from axisTree */\nexport function getArrayFromAxisTree(tree: AxisTree): AxisSpecNormalized[] {\n const res = [tree.axis];\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n res.push(parent.axis);\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return res;\n}\n\nexport function canonicalizeAxisWithParents(axis: AxisSpecNormalized) {\n return canonicalizeJson(getArrayFromAxisTree(getAxesTree(axis)).map(getAxisId));\n}\n\nfunction normalizingAxesComparator(axis1: AxisSpecNormalized, axis2: AxisSpecNormalized): 1 | -1 | 0 {\n if (axis1.name !== axis2.name) {\n return axis1.name < axis2.name ? 1 : -1;\n }\n if (axis1.type !== axis2.type) {\n return axis1.type < axis2.type ? 1 : -1;\n }\n const domain1 = canonicalizeJson(axis1.domain ?? {});\n const domain2 = canonicalizeJson(axis2.domain ?? {});\n if (domain1 !== domain2) {\n return domain1 < domain2 ? 1 : -1;\n }\n\n const parents1 = canonicalizeAxisWithParents(axis1);\n const parents2 = canonicalizeAxisWithParents(axis2);\n\n if (parents1 !== parents2) {\n return parents1 < parents2 ? 1 : -1;\n }\n\n const annotation1 = canonicalizeJson(axis1.annotations ?? {});\n const annotation2 = canonicalizeJson(axis2.annotations ?? {});\n if (annotation1 !== annotation2) {\n return annotation1 < annotation2 ? 1 : -1;\n }\n return 0;\n}\n\nfunction parseParentsFromAnnotations(axis: AxisSpec) {\n const parentsList = readAnnotationJson(axis, Annotation.Parents);\n if (parentsList === undefined) {\n return [];\n }\n return parentsList;\n}\n\nfunction sortParentsDeep(axisSpec: AxisSpecNormalized) {\n axisSpec.parentAxesSpec.forEach(sortParentsDeep);\n axisSpec.parentAxesSpec.sort(normalizingAxesComparator);\n}\n\nfunction hasCycleOfParents(axisSpec: AxisSpecNormalized) {\n const root = makeAxisTree(axisSpec);\n let nodesQ = [root];\n const ancestors = new Set(canonicalizeJson(getAxisId(axisSpec)));\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n const levelIds = new Set<CanonicalizedJson<AxisId>>();\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n for (const child of node.children) {\n const childId = canonicalizeJson(getAxisId(child.axis));\n if (!levelIds.has(childId)) {\n nextNodes.push(child);\n levelIds.add(childId);\n if (ancestors.has(childId)) {\n return true;\n }\n ancestors.add(childId);\n }\n }\n }\n nodesQ = nextNodes;\n }\n return false;\n}\n\n/** Create list of normalized axisSpec (parents are in array of specs, not indexes) */\nexport function getNormalizedAxesList(axes: AxisSpec[]): AxisSpecNormalized[] {\n if (!axes.length) {\n return [];\n }\n const modifiedAxes: AxisSpecNormalized[] = axes.map((axis) => {\n const { parentAxes: _, ...copiedRest } = axis;\n return { ...copiedRest, annotations: { ...copiedRest.annotations }, parentAxesSpec: [] };\n });\n\n axes.forEach((axis, idx) => {\n const modifiedAxis = modifiedAxes[idx];\n if (axis.parentAxes) { // if we have parents by indexes then take from the list\n modifiedAxis.parentAxesSpec = axis.parentAxes.map((idx) => modifiedAxes[idx]);\n } else { // else try to parse from annotation name\n const parents = parseParentsFromAnnotations(axis).map((name) => modifiedAxes.find((axis) => axis.name === name));\n modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined) ? [] : parents as AxisSpecNormalized[];\n\n delete modifiedAxis.annotations?.[Annotation.Parents];\n }\n });\n\n if (modifiedAxes.some(hasCycleOfParents)) { // Axes list is broken\n modifiedAxes.forEach((axis) => {\n axis.parentAxesSpec = [];\n });\n } else {\n modifiedAxes.forEach((axis) => {\n sortParentsDeep(axis);\n });\n }\n\n return modifiedAxes;\n}\n\n/** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */\nexport function getDenormalizedAxesList(axesSpec: AxisSpecNormalized[]): AxisSpec[] {\n const idsList = axesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));\n return axesSpec.map((axisSpec) => {\n const parentsIds = axisSpec.parentAxesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));\n const parentIdxs = parentsIds.map((id) => idsList.indexOf(id));\n const { parentAxesSpec: _, ...copiedRest } = axisSpec;\n if (parentIdxs.length) {\n return { ...copiedRest, parentAxes: parentIdxs } as AxisSpec;\n }\n return copiedRest;\n });\n}\n\n/** Common type representing spec for all the axes in a column */\nexport type AxesSpec = AxisSpec[];\n\n/// Well-known column names\nexport const PColumnName = {\n Label: 'pl7.app/label',\n Table: {\n RowSelection: 'pl7.app/table/row-selection',\n },\n} as const;\n\n/**\n * Full column specification including all axes specs and specs of the column\n * itself.\n *\n * A PColumn in its essence represents a mapping from a fixed size, explicitly\n * typed tuple to an explicitly typed value.\n *\n * (axis1Value1, axis2Value1, ...) -> columnValue\n *\n * Each element in tuple correspond to the axis having the same index in axesSpec.\n * */\nexport interface PUniversalColumnSpec extends PObjectSpec {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: 'PColumn';\n\n /** Type of column values */\n readonly valueType: string;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Any additional information attached to the column that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes specifications */\n readonly axesSpec: AxesSpec;\n}\n\n/**\n * Specification of a data column.\n *\n * Data column is a specialized type of PColumn that stores only simple values (strings and numbers)\n * addressed by multiple keys. This is in contrast to other PColumn variants that can store more complex\n * values like files or other abstract data types. Data columns are optimized for storing and processing\n * basic tabular data.\n */\nexport interface PDataColumnSpec extends PUniversalColumnSpec {\n /** Type of column values */\n readonly valueType: ValueType;\n}\n\n// @todo: change this to PUniversalColumnSpec\nexport type PColumnSpec = PDataColumnSpec;\n\n/** Unique PColumnSpec identifier */\nexport type PColumnSpecId = {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: 'PColumn';\n\n /** Type of column values */\n readonly valueType: ValueType;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes id */\n readonly axesId: AxesId;\n};\n\nexport function getPColumnSpecId(spec: PColumnSpec): PColumnSpecId {\n return {\n kind: spec.kind,\n valueType: spec.valueType,\n name: spec.name,\n domain: spec.domain,\n parentAxes: spec.parentAxes,\n axesId: getAxesId(spec.axesSpec),\n };\n}\n\nexport interface PColumn<Data> extends PObject<Data> {\n /** PColumn spec, allowing it to be found among other PObjects */\n readonly spec: PColumnSpec;\n}\n\n/** Columns in a PFrame also have internal identifier, this object represents\n * combination of specs and such id */\nexport interface PColumnIdAndSpec {\n /** Internal column id within the PFrame */\n readonly columnId: PObjectId;\n\n /** Column spec */\n readonly spec: PColumnSpec;\n}\n\n/** Get column id and spec from a column */\nexport function getColumnIdAndSpec<Data>(column: PColumn<Data>): PColumnIdAndSpec {\n return {\n columnId: column.id,\n spec: column.spec,\n };\n}\n\n/** Information returned by {@link PFrame.listColumns} method */\nexport interface PColumnInfo extends PColumnIdAndSpec {\n /** True if data was associated with this PColumn */\n readonly hasData: boolean;\n}\n\nexport interface AxisId {\n /** Type of the axis or column value. For an axis should not use non-key\n * types like float or double. */\n readonly type: ValueType;\n\n /** Name of the axis or column */\n readonly name: string;\n\n /** Adds auxiliary information to the axis or column name and type to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n}\n\n/** Array of axis ids */\nexport type AxesId = AxisId[];\n\n/** Extracts axis ids from axis spec */\nexport function getAxisId(spec: AxisSpec): AxisId {\n const { type, name, domain } = spec;\n const result = { type, name };\n if (domain && Object.entries(domain).length > 0) {\n Object.assign(result, { domain });\n }\n return result;\n}\n\n/** Extracts axes ids from axes spec array from column spec */\nexport function getAxesId(spec: AxesSpec): AxesId {\n return spec.map(getAxisId);\n}\n\n/** Canonicalizes axis id */\nexport function canonicalizeAxisId(id: AxisId): CanonicalizedJson<AxisId> {\n return canonicalizeJson(getAxisId(id));\n}\n\n/** Returns true if all domains from query are found in target */\nfunction matchDomain(query?: Record<string, string>, target?: Record<string, string>) {\n if (query === undefined) return target === undefined;\n if (target === undefined) return true;\n for (const k in target) {\n if (query[k] !== target[k]) return false;\n }\n return true;\n}\n\n/** Returns whether \"match\" axis id is compatible with the \"query\" */\nexport function matchAxisId(query: AxisId, target: AxisId): boolean {\n return query.name === target.name && matchDomain(query.domain, target.domain);\n}\n"],"names":["ValueType","readMetadata","metadata","key","readMetadataJsonOrThrow","metadataJson","methodNameInError","json","schema","value","error","ensureError","readMetadataJson","Annotation","AnnotationJson","z","readAnnotation","spec","readAnnotationJson","makeAxisTree","axis","getAxesTree","rootAxis","root","nodesQ","nextNodes","node","getArrayFromAxisTree","tree","res","parent","canonicalizeAxisWithParents","canonicalizeJson","getAxisId","normalizingAxesComparator","axis1","axis2","domain1","domain2","parents1","parents2","annotation1","annotation2","parseParentsFromAnnotations","parentsList","sortParentsDeep","axisSpec","hasCycleOfParents","ancestors","levelIds","child","childId","getNormalizedAxesList","axes","modifiedAxes","_","copiedRest","idx","modifiedAxis","parents","name","p","_a","PColumnName","type","domain","result"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"spec.js","sources":["../../../../../../../../../../../../node_modules/@milaboratories/pf-plots/node_modules/@milaboratories/pl-model-common/src/drivers/pframe/spec/spec.ts"],"sourcesContent":["import { ensureError } from '../../../errors';\nimport {\n canonicalizeJson,\n type CanonicalizedJson,\n type StringifiedJson,\n} from '../../../json';\nimport type {\n PObject,\n PObjectId,\n PObjectSpec,\n} from '../../../pool';\nimport { z } from 'zod';\n\nexport const ValueType = {\n Int: 'Int',\n Long: 'Long',\n Float: 'Float',\n Double: 'Double',\n String: 'String',\n Bytes: 'Bytes',\n} as const;\n\n/** PFrame columns and axes within them may store one of these types. */\nexport type ValueType = (typeof ValueType)[keyof typeof ValueType];\n\nexport type Metadata = Record<string, string>;\n\nexport function readMetadata<U extends Metadata, T extends keyof U = keyof U>(\n metadata: Metadata | undefined,\n key: T,\n): U[T] | undefined {\n return (metadata as U | undefined)?.[key];\n}\n\ntype MetadataJsonImpl<M> = {\n [P in keyof M as (M[P] extends StringifiedJson ? P : never)]: M[P] extends StringifiedJson<infer U> ? z.ZodType<U> : never;\n};\nexport type MetadataJson<M> = MetadataJsonImpl<Required<M>>;\n\nexport function readMetadataJsonOrThrow<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n methodNameInError: string = 'readMetadataJsonOrThrow',\n): z.infer<MetadataJson<M>[T]> | undefined {\n const json = readMetadata<M, T>(metadata, key);\n if (json === undefined) return undefined;\n\n const schema = metadataJson[key];\n try {\n const value = JSON.parse(json);\n return schema.parse(value);\n } catch (error: unknown) {\n throw new Error(\n `${methodNameInError} failed, `\n + `key: ${String(key)}, `\n + `value: ${json}, `\n + `error: ${ensureError(error)}`,\n );\n }\n}\n\nexport function readMetadataJson<M extends Metadata, T extends keyof MetadataJson<M>>(\n metadata: Metadata | undefined,\n metadataJson: MetadataJson<M>,\n key: T,\n): z.infer<MetadataJson<M>[T]> | undefined {\n try {\n return readMetadataJsonOrThrow(metadata, metadataJson, key);\n } catch {\n return undefined; // treat invalid values as unset\n }\n}\n\n/// Well-known domains\nexport const Domain = {\n Alphabet: 'pl7.app/alphabet',\n BlockId: 'pl7.app/blockId',\n} as const;\n\nexport type Domain = Metadata & Partial<{\n [Domain.Alphabet]: 'nucleotide' | 'aminoacid' | string;\n [Domain.BlockId]: string;\n}>;\n\nexport type DomainJson = MetadataJson<Domain>;\nexport const DomainJson: DomainJson = {};\n\n/// Helper function for reading plain domain values\nexport function readDomain<T extends keyof Domain>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): Domain[T] | undefined {\n return readMetadata<Domain, T>(spec?.domain, key);\n}\n\n/// Helper function for reading json-encoded domain values, throws on JSON parsing error\nexport function readDomainJsonOrThrow<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJsonOrThrow<Domain, T>(spec?.domain, DomainJson, key, 'readDomainJsonOrThrow');\n}\n\n/// Helper function for reading json-encoded domain values, returns undefined on JSON parsing error\nexport function readDomainJson<T extends keyof DomainJson>(\n spec: { domain?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<DomainJson[T]> | undefined {\n return readMetadataJson<Domain, T>(spec?.domain, DomainJson, key);\n}\n\n/// Well-known annotations\nexport const Annotation = {\n Alphabet: 'pl7.app/alphabet',\n Description: 'pl7.app/description',\n DiscreteValues: 'pl7.app/discreteValues',\n Format: 'pl7.app/format',\n Graph: {\n IsVirtual: 'pl7.app/graph/isVirtual',\n },\n HideDataFromUi: 'pl7.app/hideDataFromUi',\n HideDataFromGraphs: 'pl7.app/hideDataFromGraphs',\n IsLinkerColumn: 'pl7.app/isLinkerColumn',\n Label: 'pl7.app/label',\n Max: 'pl7.app/max',\n Min: 'pl7.app/min',\n Parents: 'pl7.app/parents',\n Sequence: {\n Annotation: {\n Mapping: 'pl7.app/sequence/annotation/mapping',\n },\n IsAnnotation: 'pl7.app/sequence/isAnnotation',\n },\n Table: {\n FontFamily: 'pl7.app/table/fontFamily',\n OrderPriority: 'pl7.app/table/orderPriority',\n Visibility: 'pl7.app/table/visibility',\n },\n Trace: 'pl7.app/trace',\n} as const;\n\nexport type Annotation = Metadata & Partial<{\n [Annotation.Alphabet]: 'nucleotide' | 'aminoacid' | string;\n [Annotation.Description]: string;\n [Annotation.DiscreteValues]: StringifiedJson<number[]> | StringifiedJson<string[]>;\n [Annotation.Format]: string;\n [Annotation.Graph.IsVirtual]: StringifiedJson<boolean>;\n [Annotation.HideDataFromUi]: StringifiedJson<boolean>;\n [Annotation.HideDataFromGraphs]: StringifiedJson<boolean>;\n [Annotation.IsLinkerColumn]: StringifiedJson<boolean>;\n [Annotation.Label]: string;\n [Annotation.Max]: StringifiedJson<number>;\n [Annotation.Min]: StringifiedJson<number>;\n [Annotation.Parents]: StringifiedJson<AxisSpec['name'][]>;\n [Annotation.Sequence.Annotation.Mapping]: StringifiedJson<Record<string, string>>;\n [Annotation.Sequence.IsAnnotation]: StringifiedJson<boolean>;\n [Annotation.Table.FontFamily]: string;\n [Annotation.Table.OrderPriority]: StringifiedJson<number>;\n [Annotation.Table.Visibility]: 'hidden' | 'optional' | string;\n [Annotation.Trace]: StringifiedJson<Record<string, unknown>>;\n}>;\n\n// export const AxisSpec = z.object({\n// type: z.nativeEnum(ValueType),\n// name: z.string(),\n// domain: z.record(z.string(), z.string()).optional(),\n// annotations: z.record(z.string(), z.string()).optional(),\n// parentAxes: z.array(z.number()).optional(),\n// }).passthrough();\n//\n// type Expect<T extends true> = T;\n// type Equal<X, Y> =\n// (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;\n//\n// type _test = Expect<Equal<\n// Readonly<z.infer<typeof AxisSpec>>,\n// Readonly<AxisSpec & Record<string, unknown>>\n// >>;\n\nexport type AnnotationJson = MetadataJson<Annotation>;\nexport const AnnotationJson: AnnotationJson = {\n [Annotation.DiscreteValues]: z.array(z.string()).or(z.array(z.number())),\n [Annotation.Graph.IsVirtual]: z.boolean(),\n [Annotation.HideDataFromUi]: z.boolean(),\n [Annotation.HideDataFromGraphs]: z.boolean(),\n [Annotation.IsLinkerColumn]: z.boolean(),\n [Annotation.Max]: z.number(),\n [Annotation.Min]: z.number(),\n [Annotation.Parents]: z.array(z.string()),\n [Annotation.Sequence.Annotation.Mapping]: z.record(z.string(), z.string()),\n [Annotation.Sequence.IsAnnotation]: z.boolean(),\n [Annotation.Table.OrderPriority]: z.number(),\n [Annotation.Trace]: z.record(z.string(), z.unknown()),\n};\n\n/// Helper function for reading plain annotation values\nexport function readAnnotation<T extends keyof Annotation>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): Annotation[T] | undefined {\n return readMetadata<Annotation, T>(spec?.annotations, key);\n}\n\n/// Helper function for reading json-encoded annotation values, throws on JSON parsing error\nexport function readAnnotationJsonOrThrow<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJsonOrThrow<Annotation, T>(spec?.annotations, AnnotationJson, key, 'readAnnotationJsonOrThrow');\n}\n\n/// Helper function for reading json-encoded annotation values, returns undefined on JSON parsing error\nexport function readAnnotationJson<T extends keyof AnnotationJson>(\n spec: { annotations?: Metadata | undefined } | undefined,\n key: T,\n): z.infer<AnnotationJson[T]> | undefined {\n return readMetadataJson<Annotation, T>(spec?.annotations, AnnotationJson, key);\n}\n\n/**\n * Specification of an individual axis.\n *\n * Each axis is a part of a composite key that addresses data inside the PColumn.\n *\n * Each record inside a PColumn is addressed by a unique tuple of values set for\n * all the axes specified in the column spec.\n */\nexport interface AxisSpec {\n /** Type of the axis value. Should not use non-key types like float or double. */\n readonly type: ValueType;\n\n /** Name of the axis */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Any additional information attached to the axis that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /**\n * Parent axes provide contextual grouping for the axis in question, establishing\n * a hierarchy where the current axis is dependent on one or more axes for its\n * full definition and meaning. For instance, in a data structure where each\n * \"container\" axis may contain multiple \"item\" axes, the `item` axis would\n * list the index of the `container` axis in this field to denote its dependency.\n *\n * This means that the identity or significance of the `item` axis is only\n * interpretable when combined with its parent `container` axis. An `item` axis\n * index by itself may be non-unique and only gains uniqueness within the context\n * of its parent `container`. Therefore, the `parentAxes` field is essential for\n * mapping these relationships and ensuring data coherence across nested or\n * multi-level data models.\n *\n * A list of zero-based indices of parent axes in the overall axes specification\n * from the column spec. Each index corresponds to the position of a parent axis\n * in the list that defines the structure of the data model.\n */\n readonly parentAxes?: number[];\n}\n\n/** Parents are specs, not indexes; normalized axis can be used considering its parents independently from column */\nexport interface AxisSpecNormalized extends Omit<AxisSpec, 'parentAxes'> {\n parentAxesSpec: AxisSpecNormalized[];\n}\n\n/** Tree: axis is a root, its parents are children */\nexport type AxisTree = {\n axis: AxisSpecNormalized;\n children: AxisTree[]; // parents\n};\n\nfunction makeAxisTree(axis: AxisSpecNormalized): AxisTree {\n return { axis, children: [] };\n}\n\n/** Build tree by axis parents annotations */\nexport function getAxesTree(rootAxis: AxisSpecNormalized): AxisTree {\n const root = makeAxisTree(rootAxis);\n let nodesQ = [root];\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n nextNodes.push(...node.children);\n }\n nodesQ = nextNodes;\n }\n return root;\n}\n\n/** Get set of canonicalized axisIds from axisTree */\nexport function getSetFromAxisTree(tree: AxisTree): Set<CanonicalizedJson<AxisId>> {\n const set = new Set([canonicalizeJson(getAxisId(tree.axis))]);\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n set.add(canonicalizeJson(getAxisId(parent.axis)));\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return set;\n}\n\n/** Get array of axisSpecs from axisTree */\nexport function getArrayFromAxisTree(tree: AxisTree): AxisSpecNormalized[] {\n const res = [tree.axis];\n let nodesQ = [tree];\n while (nodesQ.length) {\n const nextNodes = [];\n for (const node of nodesQ) {\n for (const parent of node.children) {\n res.push(parent.axis);\n nextNodes.push(parent);\n }\n }\n nodesQ = nextNodes;\n }\n return res;\n}\n\nexport function canonicalizeAxisWithParents(axis: AxisSpecNormalized) {\n return canonicalizeJson(getArrayFromAxisTree(getAxesTree(axis)).map(getAxisId));\n}\n\nfunction normalizingAxesComparator(axis1: AxisSpecNormalized, axis2: AxisSpecNormalized): 1 | -1 | 0 {\n if (axis1.name !== axis2.name) {\n return axis1.name < axis2.name ? 1 : -1;\n }\n if (axis1.type !== axis2.type) {\n return axis1.type < axis2.type ? 1 : -1;\n }\n const domain1 = canonicalizeJson(axis1.domain ?? {});\n const domain2 = canonicalizeJson(axis2.domain ?? {});\n if (domain1 !== domain2) {\n return domain1 < domain2 ? 1 : -1;\n }\n\n const parents1 = canonicalizeAxisWithParents(axis1);\n const parents2 = canonicalizeAxisWithParents(axis2);\n\n if (parents1 !== parents2) {\n return parents1 < parents2 ? 1 : -1;\n }\n\n const annotation1 = canonicalizeJson(axis1.annotations ?? {});\n const annotation2 = canonicalizeJson(axis2.annotations ?? {});\n if (annotation1 !== annotation2) {\n return annotation1 < annotation2 ? 1 : -1;\n }\n return 0;\n}\n\nfunction parseParentsFromAnnotations(axis: AxisSpec) {\n const parentsList = readAnnotationJson(axis, Annotation.Parents);\n if (parentsList === undefined) {\n return [];\n }\n return parentsList;\n}\n\nfunction sortParentsDeep(axisSpec: AxisSpecNormalized) {\n axisSpec.parentAxesSpec.forEach(sortParentsDeep);\n axisSpec.parentAxesSpec.sort(normalizingAxesComparator);\n}\n\nfunction hasCycleOfParents(axisSpec: AxisSpecNormalized) {\n const root = makeAxisTree(axisSpec);\n let nodesQ = [root];\n const ancestors = new Set(canonicalizeJson(getAxisId(axisSpec)));\n while (nodesQ.length) {\n const nextNodes: AxisTree[] = [];\n const levelIds = new Set<CanonicalizedJson<AxisId>>();\n for (const node of nodesQ) {\n node.children = node.axis.parentAxesSpec.map(makeAxisTree);\n for (const child of node.children) {\n const childId = canonicalizeJson(getAxisId(child.axis));\n if (!levelIds.has(childId)) {\n nextNodes.push(child);\n levelIds.add(childId);\n if (ancestors.has(childId)) {\n return true;\n }\n ancestors.add(childId);\n }\n }\n }\n nodesQ = nextNodes;\n }\n return false;\n}\n\n/** Create list of normalized axisSpec (parents are in array of specs, not indexes) */\nexport function getNormalizedAxesList(axes: AxisSpec[]): AxisSpecNormalized[] {\n if (!axes.length) {\n return [];\n }\n const modifiedAxes: AxisSpecNormalized[] = axes.map((axis) => {\n const { parentAxes: _, ...copiedRest } = axis;\n return { ...copiedRest, annotations: { ...copiedRest.annotations }, parentAxesSpec: [] };\n });\n\n axes.forEach((axis, idx) => {\n const modifiedAxis = modifiedAxes[idx];\n if (axis.parentAxes) { // if we have parents by indexes then take from the list\n modifiedAxis.parentAxesSpec = axis.parentAxes.map((idx) => modifiedAxes[idx]);\n } else { // else try to parse from annotation name\n const parents = parseParentsFromAnnotations(axis).map((name) => modifiedAxes.find((axis) => axis.name === name));\n modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined) ? [] : parents as AxisSpecNormalized[];\n\n delete modifiedAxis.annotations?.[Annotation.Parents];\n }\n });\n\n if (modifiedAxes.some(hasCycleOfParents)) { // Axes list is broken\n modifiedAxes.forEach((axis) => {\n axis.parentAxesSpec = [];\n });\n } else {\n modifiedAxes.forEach((axis) => {\n sortParentsDeep(axis);\n });\n }\n\n return modifiedAxes;\n}\n\n/** Create list of regular axisSpec from normalized (parents are indexes, inside of current axes list) */\nexport function getDenormalizedAxesList(axesSpec: AxisSpecNormalized[]): AxisSpec[] {\n const idsList = axesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));\n return axesSpec.map((axisSpec) => {\n const parentsIds = axisSpec.parentAxesSpec.map((axisSpec) => canonicalizeJson(getAxisId(axisSpec)));\n const parentIdxs = parentsIds.map((id) => idsList.indexOf(id));\n const { parentAxesSpec: _, ...copiedRest } = axisSpec;\n if (parentIdxs.length) {\n return { ...copiedRest, parentAxes: parentIdxs } as AxisSpec;\n }\n return copiedRest;\n });\n}\n\n/** Common type representing spec for all the axes in a column */\nexport type AxesSpec = AxisSpec[];\n\n/// Well-known column names\nexport const PColumnName = {\n Label: 'pl7.app/label',\n Table: {\n RowSelection: 'pl7.app/table/row-selection',\n },\n} as const;\n\n/**\n * Full column specification including all axes specs and specs of the column\n * itself.\n *\n * A PColumn in its essence represents a mapping from a fixed size, explicitly\n * typed tuple to an explicitly typed value.\n *\n * (axis1Value1, axis2Value1, ...) -> columnValue\n *\n * Each element in tuple correspond to the axis having the same index in axesSpec.\n */\nexport interface PUniversalColumnSpec extends PObjectSpec {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: 'PColumn';\n\n /** Type of column values */\n readonly valueType: string;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** Any additional information attached to the column that does not affect its\n * identifier */\n readonly annotations?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes specifications */\n readonly axesSpec: AxesSpec;\n}\n\n/**\n * Specification of a data column.\n *\n * Data column is a specialized type of PColumn that stores only simple values (strings and numbers)\n * addressed by multiple keys. This is in contrast to other PColumn variants that can store more complex\n * values like files or other abstract data types. Data columns are optimized for storing and processing\n * basic tabular data.\n */\nexport interface PDataColumnSpec extends PUniversalColumnSpec {\n /** Type of column values */\n readonly valueType: ValueType;\n}\n\n// @todo: change this to PUniversalColumnSpec\nexport type PColumnSpec = PDataColumnSpec;\n\n/** Unique PColumnSpec identifier */\nexport type PColumnSpecId = {\n /** Defines specific type of BObject, the most generic type of unit of\n * information in Platforma Project. */\n readonly kind: 'PColumn';\n\n /** Type of column values */\n readonly valueType: ValueType;\n\n /** Column name */\n readonly name: string;\n\n /** Adds auxiliary information to the axis name, type and parents to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n\n /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */\n readonly parentAxes?: number[];\n\n /** Axes id */\n readonly axesId: AxesId;\n};\n\nexport function getPColumnSpecId(spec: PColumnSpec): PColumnSpecId {\n return {\n kind: spec.kind,\n valueType: spec.valueType,\n name: spec.name,\n domain: spec.domain,\n parentAxes: spec.parentAxes,\n axesId: getAxesId(spec.axesSpec),\n };\n}\n\nexport interface PColumn<Data> extends PObject<Data> {\n /** PColumn spec, allowing it to be found among other PObjects */\n readonly spec: PColumnSpec;\n}\n\n/** Columns in a PFrame also have internal identifier, this object represents\n * combination of specs and such id */\nexport interface PColumnIdAndSpec {\n /** Internal column id within the PFrame */\n readonly columnId: PObjectId;\n\n /** Column spec */\n readonly spec: PColumnSpec;\n}\n\n/** Get column id and spec from a column */\nexport function getColumnIdAndSpec<Data>(column: PColumn<Data>): PColumnIdAndSpec {\n return {\n columnId: column.id,\n spec: column.spec,\n };\n}\n\n/** Information returned by {@link PFrame.listColumns} method */\nexport interface PColumnInfo extends PColumnIdAndSpec {\n /** True if data was associated with this PColumn */\n readonly hasData: boolean;\n}\n\nexport interface AxisId {\n /** Type of the axis or column value. For an axis should not use non-key\n * types like float or double. */\n readonly type: ValueType;\n\n /** Name of the axis or column */\n readonly name: string;\n\n /** Adds auxiliary information to the axis or column name and type to form a\n * unique identifier */\n readonly domain?: Record<string, string>;\n}\n\n/** Array of axis ids */\nexport type AxesId = AxisId[];\n\n/** Extracts axis ids from axis spec */\nexport function getAxisId(spec: AxisSpec): AxisId {\n const { type, name, domain } = spec;\n const result = { type, name };\n if (domain && Object.entries(domain).length > 0) {\n Object.assign(result, { domain });\n }\n return result;\n}\n\n/** Extracts axes ids from axes spec array from column spec */\nexport function getAxesId(spec: AxesSpec): AxesId {\n return spec.map(getAxisId);\n}\n\n/** Canonicalizes axis id */\nexport function canonicalizeAxisId(id: AxisId): CanonicalizedJson<AxisId> {\n return canonicalizeJson(getAxisId(id));\n}\n\n/** Returns true if all domains from query are found in target */\nfunction matchDomain(query?: Record<string, string>, target?: Record<string, string>) {\n if (query === undefined) return target === undefined;\n if (target === undefined) return true;\n for (const k in target) {\n if (query[k] !== target[k]) return false;\n }\n return true;\n}\n\n/** Returns whether \"match\" axis id is compatible with the \"query\" */\nexport function matchAxisId(query: AxisId, target: AxisId): boolean {\n return query.name === target.name && matchDomain(query.domain, target.domain);\n}\n"],"names":["ValueType","readMetadata","metadata","key","readMetadataJsonOrThrow","metadataJson","methodNameInError","json","schema","value","error","ensureError","readMetadataJson","Annotation","AnnotationJson","z","readAnnotation","spec","readAnnotationJson","makeAxisTree","axis","getAxesTree","rootAxis","root","nodesQ","nextNodes","node","getArrayFromAxisTree","tree","res","parent","canonicalizeAxisWithParents","canonicalizeJson","getAxisId","normalizingAxesComparator","axis1","axis2","domain1","domain2","parents1","parents2","annotation1","annotation2","parseParentsFromAnnotations","parentsList","sortParentsDeep","axisSpec","hasCycleOfParents","ancestors","levelIds","child","childId","getNormalizedAxesList","axes","modifiedAxes","_","copiedRest","idx","modifiedAxis","parents","name","p","_a","PColumnName","type","domain","result"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- {"version":3,"file":"PlDataTable.js","sources":["../../../../../../../../../../node_modules/@milaboratories/pf-plots/node_modules/@platforma-sdk/model/src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n matchAxisId,\n PColumnName,\n readAnnotation,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n} from '../render';\nimport {\n PColumnCollection,\n TreeNodeAccessor,\n} from '../render';\nimport { isLinkerColumn } from './PFrameForGraphs';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\n\n/**\n * PlDataTableV2 persisted state\n */\nexport type PlDataTableStateV2 =\n // Old versions of the state\n | {\n // no version\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sourceId?: string;\n sheets?: Record<CanonicalizedJson<AxisId>, string | number>;\n };\n pTableParams?: {\n sorting?: PTableSorting[];\n filters?: PTableRecordFilter[];\n };\n }\n | {\n version: 2;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n }[];\n pTableParams: {\n hiddenColIds: PObjectId[] | null;\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n }\n | {\n version: 3;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n pTableParams: PTableParamsV2;\n }\n // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2): PlDataTableStateV2Normalized {\n // v1 -> v2\n if (!('version' in state)) {\n // Non upgradeable as sourceId calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v2 -> v3\n if (state.version === 2) {\n state = {\n version: 3,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n filtersState: [],\n })),\n pTableParams: makeDefaultPTableParams(),\n };\n }\n // v3 -> v4\n if (state.version === 3) {\n // Non upgradeable as column ids calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Referense value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Referense value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Referense value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contins corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Check if column is a label column */\nexport function isLabelColumn(column: PColumnSpec) {\n return column.axesSpec.length === 1 && column.name === PColumnName.Label;\n}\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\n/** Check if all columns are computed */\nexport function allColumnsComputed(\n columns: PColumn<PColumnValues | TreeNodeAccessor | DataInfo<TreeNodeAccessor>>[],\n): boolean {\n type Data = typeof columns[number]['data'];\n const isValues = (d: Data): d is PColumnValues => Array.isArray(d);\n const isAccessor = (d: Data): d is TreeNodeAccessor => d instanceof TreeNodeAccessor;\n const isDataInfo = (d: Data): d is DataInfo<TreeNodeAccessor> =>\n typeof d === 'object' && 'type' in d;\n\n return columns\n .map((c) => c.data)\n .every((d): boolean => {\n if (isValues(d)) {\n return true;\n } else if (isAccessor(d)) {\n return d.getIsReadyOrError();\n } else if (isDataInfo(d)) {\n const type = d.type;\n switch (type) {\n case 'Json':\n return true;\n case 'JsonPartitioned':\n return Object.values(d.parts).every((p) => p.getIsReadyOrError());\n case 'BinaryPartitioned':\n return Object.values(d.parts)\n .every((p) => p.index.getIsReadyOrError() && p.values.getIsReadyOrError());\n case 'ParquetPartitioned':\n return Object.values(d.parts)\n .every((p) => p.getIsReadyOrError());\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw Error(`unsupported column data type: ${d satisfies never}`);\n }\n });\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(c.spec)) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === 'hidden';\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === 'optional';\n}\n\n/**\n * Return unique entries of the array by the provided id\n * For each id, the last entry is kept\n */\nexport function uniqueBy<T>(array: T[], makeId: (entry: T) => string): T[] {\n return [...new Map(array.map((e) => [makeId(e), e])).values()];\n}\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n inputColumns: PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>[],\n tableState: PlDataTableStateV2,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (inputColumns.length === 0) return undefined;\n const columns = inputColumns.filter((c) => isLinkerColumn(c.spec) || !isColumnHidden(c.spec));\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n const fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n [...fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a)))],\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n if (ops?.coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => ops?.coreColumnPredicate?.(c.spec) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allColumnsComputed([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":["isLabelColumn","column","PColumnName"],"mappings":";;;;;;AAwdM,SAAUA,EAAcC,GAAmB;AAC/C,SAAOA,EAAO,SAAS,WAAW,KAAKA,EAAO,SAASC,EAAY;AACrE;","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"PlDataTable.js","sources":["../../../../../../../../../../node_modules/@milaboratories/pf-plots/node_modules/@platforma-sdk/model/src/components/PlDataTable.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpec,\n CanonicalizedJson,\n DataInfo,\n ListOptionBase,\n PColumn,\n PColumnIdAndSpec,\n PColumnSpec,\n PColumnValues,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableColumnSpec,\n PTableDef,\n PTableHandle,\n PTableRecordFilter,\n PTableRecordSingleValueFilterV2,\n PTableSorting,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n matchAxisId,\n PColumnName,\n readAnnotation,\n uniqueBy,\n} from '@milaboratories/pl-model-common';\nimport type {\n AxisLabelProvider,\n ColumnProvider,\n PColumnDataUniversal,\n RenderCtx,\n} from '../render';\nimport {\n PColumnCollection,\n TreeNodeAccessor,\n} from '../render';\nimport { isLinkerColumn } from './PFrameForGraphs';\n\nexport type PlTableColumnId = {\n /** Original column spec */\n source: PTableColumnSpec;\n /** Column spec with labeled axes replaced by label columns */\n labeled: PTableColumnSpec;\n};\n\nexport type PlTableColumnIdJson = CanonicalizedJson<PlTableColumnId>;\n\nexport type PlDataTableGridStateCore = {\n /** Includes column ordering */\n columnOrder?: {\n /** All colIds in order */\n orderedColIds: PlTableColumnIdJson[];\n };\n /** Includes current sort columns and direction */\n sort?: {\n /** Sorted columns and directions in order */\n sortModel: {\n /** Column Id to apply the sort to. */\n colId: PlTableColumnIdJson;\n /** Sort direction */\n sort: 'asc' | 'desc';\n }[];\n };\n /** Includes column visibility */\n columnVisibility?: {\n /** All colIds which were hidden */\n hiddenColIds: PlTableColumnIdJson[];\n };\n};\n\nexport type PlDataTableSheet = {\n /** spec of the axis to use */\n axis: AxisSpec;\n /** options to show in the filter dropdown */\n options: ListOptionBase<string | number>[];\n /** default (selected) value */\n defaultValue?: string | number;\n};\n\nexport type PlDataTableSheetState = {\n /** id of the axis */\n axisId: AxisId;\n /** selected value */\n value: string | number;\n};\n\n/**\n * PlDataTableV2 persisted state\n */\nexport type PlDataTableStateV2 =\n // Old versions of the state\n | {\n // no version\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sourceId?: string;\n sheets?: Record<CanonicalizedJson<AxisId>, string | number>;\n };\n pTableParams?: {\n sorting?: PTableSorting[];\n filters?: PTableRecordFilter[];\n };\n }\n | {\n version: 2;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n }[];\n pTableParams: {\n hiddenColIds: PObjectId[] | null;\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n }\n | {\n version: 3;\n stateCache: {\n sourceId: string;\n gridState: {\n columnOrder?: {\n orderedColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n sort?: {\n sortModel: {\n colId: CanonicalizedJson<PTableColumnSpec>;\n sort: 'asc' | 'desc';\n }[];\n };\n columnVisibility?: {\n hiddenColIds: CanonicalizedJson<PTableColumnSpec>[];\n };\n };\n sheetsState: PlDataTableSheetState[];\n filtersState: PlDataTableFilterState[];\n }[];\n pTableParams: PTableParamsV2;\n }\n // Normalized state\n | PlDataTableStateV2Normalized;\n\nexport type PlDataTableStateV2CacheEntry = {\n /** DataSource identifier for state management */\n sourceId: string;\n /** Internal ag-grid state */\n gridState: PlDataTableGridStateCore;\n /** Sheets state */\n sheetsState: PlDataTableSheetState[];\n /** Filters state */\n filtersState: PlDataTableFilterState[];\n};\n\nexport type PTableParamsV2 =\n | {\n sourceId: null;\n hiddenColIds: null;\n partitionFilters: [];\n filters: [];\n sorting: [];\n }\n | {\n sourceId: string;\n hiddenColIds: PObjectId[] | null;\n partitionFilters: PTableRecordFilter[];\n filters: PTableRecordFilter[];\n sorting: PTableSorting[];\n };\n\nexport type PlDataTableStateV2Normalized = {\n /** Version for upgrades */\n version: 4;\n /** Internal states, LRU cache for 5 sourceId-s */\n stateCache: PlDataTableStateV2CacheEntry[];\n /** PTable params derived from the cache state for the current sourceId */\n pTableParams: PTableParamsV2;\n};\n\nexport function makeDefaultPTableParams(): PTableParamsV2 {\n return {\n sourceId: null,\n hiddenColIds: null,\n partitionFilters: [],\n filters: [],\n sorting: [],\n };\n}\n\n/** Create default PlDataTableStateV2 */\nexport function createPlDataTableStateV2(): PlDataTableStateV2Normalized {\n return {\n version: 4,\n stateCache: [],\n pTableParams: makeDefaultPTableParams(),\n };\n}\n\n/** Upgrade PlDataTableStateV2 to the latest version */\nexport function upgradePlDataTableStateV2(state: PlDataTableStateV2 | undefined): PlDataTableStateV2Normalized {\n // Block just added, had no state, model started earlier than the UI\n if (!state) {\n return createPlDataTableStateV2();\n }\n // v1 -> v2\n if (!('version' in state)) {\n // Non upgradeable as sourceId calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n // v2 -> v3\n if (state.version === 2) {\n state = {\n version: 3,\n stateCache: state.stateCache.map((entry) => ({\n ...entry,\n filtersState: [],\n })),\n pTableParams: makeDefaultPTableParams(),\n };\n }\n // v3 -> v4\n if (state.version === 3) {\n // Non upgradeable as column ids calculation algorithm has changed, resetting state to default\n state = createPlDataTableStateV2();\n }\n return state;\n}\n\nexport type PlDataTableFilterState = {\n id: PTableColumnId;\n alphabetic: boolean;\n filter: null | {\n value: PlTableFilter;\n disabled: boolean;\n };\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNotNA = {\n /** Predicate type */\n type: 'isNotNA';\n};\n\n/** PlTableFilters filter entry */\nexport type PlTableFilterIsNA = {\n /** Predicate type */\n type: 'isNA';\n};\n\n/** PlTableFilters filter entries applicable to both string and number values */\nexport type PlTableFilterCommon = PlTableFilterIsNotNA | PlTableFilterIsNA;\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberEquals = {\n /** Predicate type */\n type: 'number_equals';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberNotEquals = {\n /** Predicate type */\n type: 'number_notEquals';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThan = {\n /** Predicate type */\n type: 'number_greaterThan';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberGreaterThanOrEqualTo = {\n /** Predicate type */\n type: 'number_greaterThanOrEqualTo';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThan = {\n /** Predicate type */\n type: 'number_lessThan';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberLessThanOrEqualTo = {\n /** Predicate type */\n type: 'number_lessThanOrEqualTo';\n /** Referense value */\n reference: number;\n};\n\n/** PlTableFilters numeric filter entry */\nexport type PlTableFilterNumberBetween = {\n /** Predicate type */\n type: 'number_between';\n /** Referense value for the lower bound */\n lowerBound: number;\n /** Defines whether values equal to lower bound reference value should be matched */\n includeLowerBound: boolean;\n /** Referense value for the upper bound */\n upperBound: number;\n /** Defines whether values equal to upper bound reference value should be matched */\n includeUpperBound: boolean;\n};\n\n/** All PlTableFilters numeric filter entries */\nexport type PlTableFilterNumber =\n | PlTableFilterCommon\n | PlTableFilterNumberEquals\n | PlTableFilterNumberNotEquals\n | PlTableFilterNumberGreaterThan\n | PlTableFilterNumberGreaterThanOrEqualTo\n | PlTableFilterNumberLessThan\n | PlTableFilterNumberLessThanOrEqualTo\n | PlTableFilterNumberBetween;\n/** All types of PlTableFilters numeric filter entries */\nexport type PlTableFilterNumberType = PlTableFilterNumber['type'];\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringEquals = {\n /** Predicate type */\n type: 'string_equals';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringNotEquals = {\n /** Predicate type */\n type: 'string_notEquals';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContains = {\n /** Predicate type */\n type: 'string_contains';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotContain = {\n /** Predicate type */\n type: 'string_doesNotContain';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringMatches = {\n /** Predicate type */\n type: 'string_matches';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringDoesNotMatch = {\n /** Predicate type */\n type: 'string_doesNotMatch';\n /** Referense value */\n reference: string;\n};\n\n/** PlTableFilters string filter entry */\nexport type PlTableFilterStringContainsFuzzyMatch = {\n /** Predicate type */\n type: 'string_containsFuzzyMatch';\n /** Referense value */\n reference: string;\n /**\n * Maximum acceptable edit distance between reference value and matched substring\n * @see https://en.wikipedia.org/wiki/Edit_distance\n */\n maxEdits: number;\n /**\n * When {@link substitutionsOnly} is set to false\n * Levenshtein distance is used as edit distance (substitutions and indels)\n * @see https://en.wikipedia.org/wiki/Levenshtein_distance\n * When {@link substitutionsOnly} is set to true\n * Hamming distance is used as edit distance (substitutions only)\n * @see https://en.wikipedia.org/wiki/Hamming_distance\n */\n substitutionsOnly: boolean;\n /**\n * Single character in {@link reference} that will labelColumn any\n * single character in searched text.\n */\n wildcard?: string;\n};\n\n/** All PlTableFilters string filter entries */\nexport type PlTableFilterString =\n | PlTableFilterCommon\n | PlTableFilterStringEquals\n | PlTableFilterStringNotEquals\n | PlTableFilterStringContains\n | PlTableFilterStringDoesNotContain\n | PlTableFilterStringMatches\n | PlTableFilterStringDoesNotMatch\n | PlTableFilterStringContainsFuzzyMatch;\n/** All types of PlTableFilters string filter entries */\nexport type PlTableFilterStringType = PlTableFilterString['type'];\n\n/** All PlTableFilters filter entries */\nexport type PlTableFilter = PlTableFilterNumber | PlTableFilterString;\n/** All types of PlTableFilters filter entries */\nexport type PlTableFilterType = PlTableFilter['type'];\n\nexport type CreatePlDataTableOps = {\n /** Filters for columns and non-partitioned axes */\n filters?: PTableRecordFilter[];\n\n /** Sorting to columns hidden from user */\n sorting?: PTableSorting[];\n\n /**\n * Selects columns for which will be inner-joined to the table.\n *\n * Default behaviour: all columns are considered to be core\n */\n coreColumnPredicate?: (spec: PColumnSpec) => boolean;\n\n /**\n * Determines how core columns should be joined together:\n * inner - so user will only see records present in all core columns\n * full - so user will only see records present in any of the core columns\n *\n * All non-core columns will be left joined to the table produced by the core\n * columns, in other words records form the pool of non-core columns will only\n * make their way into the final table if core table contins corresponding key.\n *\n * Default: 'full'\n */\n coreJoinType?: 'inner' | 'full';\n};\n\n/** Check if column is a label column */\nexport function isLabelColumn(column: PColumnSpec) {\n return column.axesSpec.length === 1 && column.name === PColumnName.Label;\n}\n\n/** Get all label columns from the result pool */\nexport function getAllLabelColumns(\n resultPool: AxisLabelProvider & ColumnProvider,\n): PColumn<PColumnDataUniversal>[] | undefined {\n return new PColumnCollection()\n .addAxisLabelProvider(resultPool)\n .addColumnProvider(resultPool)\n .getColumns({\n name: PColumnName.Label,\n axes: [{}], // exactly one axis\n }, { dontWaitAllData: true });\n}\n\n/** Get label columns matching the provided columns from the result pool */\nexport function getMatchingLabelColumns(\n columns: PColumnIdAndSpec[],\n allLabelColumns: PColumn<PColumnDataUniversal>[],\n): PColumn<PColumnDataUniversal>[] {\n // split input columns into label and value columns\n const inputLabelColumns: typeof columns = [];\n const inputValueColumns: typeof columns = [];\n for (const column of columns) {\n if (isLabelColumn(column.spec)) {\n inputLabelColumns.push(column);\n } else {\n inputValueColumns.push(column);\n }\n }\n\n // collect distinct axes of value columns\n const unlabeledAxes: AxisId[] = [];\n for (const column of inputValueColumns) {\n for (const axis of column.spec.axesSpec) {\n const axisId = getAxisId(axis);\n if (!unlabeledAxes.some((id) => matchAxisId(id, axisId))) {\n unlabeledAxes.push(axisId);\n }\n }\n }\n\n // remove axes matched by input label columns\n for (const labelColumn of inputLabelColumns) {\n const labelAxisId = getAxisId(labelColumn.spec.axesSpec[0]);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n\n // warning: changing this id will break backward compatibility\n const colId = (id: PObjectId, domain?: Record<string, string>): PObjectId => {\n let wid = id.toString();\n if (domain) {\n for (const k in domain) {\n wid += k;\n wid += domain[k];\n }\n }\n return wid as PObjectId;\n };\n\n // search label columns for unmatched axes\n const labelColumns: typeof allLabelColumns = [];\n for (const labelColumn of allLabelColumns) {\n const labelAxis = labelColumn.spec.axesSpec[0];\n const labelAxisId = getAxisId(labelAxis);\n const labelMatch = unlabeledAxes.findIndex((axisId) => matchAxisId(axisId, labelAxisId));\n if (labelMatch !== -1) {\n const axisId = unlabeledAxes[labelMatch];\n const dataDomainLen = Object.keys(axisId.domain ?? {}).length;\n const labelDomainLen = Object.keys(labelAxis.domain ?? {}).length;\n if (dataDomainLen > labelDomainLen) {\n labelColumns.push({\n id: colId(labelColumn.id, axisId.domain),\n spec: {\n ...labelColumn.spec,\n axesSpec: [{ ...axisId, annotations: labelAxis.annotations }],\n },\n data: labelColumn.data,\n });\n } else {\n labelColumns.push(labelColumn);\n }\n unlabeledAxes.splice(labelMatch, 1);\n }\n }\n return labelColumns;\n}\n\n/** Check if all columns are computed */\nexport function allColumnsComputed(\n columns: PColumn<PColumnValues | TreeNodeAccessor | DataInfo<TreeNodeAccessor>>[],\n): boolean {\n type Data = typeof columns[number]['data'];\n const isValues = (d: Data): d is PColumnValues => Array.isArray(d);\n const isAccessor = (d: Data): d is TreeNodeAccessor => d instanceof TreeNodeAccessor;\n const isDataInfo = (d: Data): d is DataInfo<TreeNodeAccessor> =>\n typeof d === 'object' && 'type' in d;\n\n return columns\n .map((c) => c.data)\n .every((d): boolean => {\n if (isValues(d)) {\n return true;\n } else if (isAccessor(d)) {\n return d.getIsReadyOrError();\n } else if (isDataInfo(d)) {\n const type = d.type;\n switch (type) {\n case 'Json':\n return true;\n case 'JsonPartitioned':\n return Object.values(d.parts).every((p) => p.getIsReadyOrError());\n case 'BinaryPartitioned':\n return Object.values(d.parts)\n .every((p) => p.index.getIsReadyOrError() && p.values.getIsReadyOrError());\n case 'ParquetPartitioned':\n return Object.values(d.parts)\n .every((p) => p.getIsReadyOrError());\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw Error(`unsupported column data type: ${d satisfies never}`);\n }\n });\n}\n\nfunction createPTableDef(params: {\n columns: PColumn<PColumnDataUniversal>[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n coreJoinType: 'inner' | 'full';\n partitionFilters: PTableRecordSingleValueFilterV2[];\n filters: PTableRecordSingleValueFilterV2[];\n sorting: PTableSorting[];\n coreColumnPredicate?: ((spec: PColumnSpec) => boolean);\n}): PTableDef<PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>> {\n let coreColumns = params.columns;\n const secondaryColumns: typeof params.columns = [];\n\n if (params.coreColumnPredicate) {\n coreColumns = [];\n for (const c of params.columns)\n if (params.coreColumnPredicate(c.spec)) coreColumns.push(c);\n else secondaryColumns.push(c);\n }\n\n secondaryColumns.push(...params.labelColumns);\n\n return {\n src: {\n type: 'outer',\n primary: {\n type: params.coreJoinType,\n entries: coreColumns.map((c) => ({ type: 'column', column: c })),\n },\n secondary: secondaryColumns.map((c) => ({ type: 'column', column: c })),\n },\n partitionFilters: params.partitionFilters,\n filters: params.filters,\n sorting: params.sorting,\n };\n}\n\n/** PlAgDataTable model */\nexport type PlDataTableModel = {\n /** DataSource identifier for state management */\n sourceId: string | null;\n /** p-table including all columns, used to show the full specification of the table */\n fullTableHandle: PTableHandle;\n /** p-table including only visible columns, used to get the data */\n visibleTableHandle: PTableHandle;\n};\n\n/** Check if column should be omitted from the table */\nexport function isColumnHidden(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === 'hidden';\n}\n\n/** Check if column is hidden by default */\nexport function isColumnOptional(spec: { annotations?: Annotation }): boolean {\n return readAnnotation(spec, Annotation.Table.Visibility) === 'optional';\n}\n\n/**\n * Create p-table spec and handle given ui table state\n *\n * @param ctx context\n * @param columns column list\n * @param tableState table ui state\n * @returns PlAgDataTableV2 table source\n */\nexport function createPlDataTableV2<A, U>(\n ctx: RenderCtx<A, U>,\n inputColumns: PColumn<TreeNodeAccessor | PColumnValues | DataInfo<TreeNodeAccessor>>[],\n tableState: PlDataTableStateV2 | undefined,\n ops?: CreatePlDataTableOps,\n): PlDataTableModel | undefined {\n if (inputColumns.length === 0) return undefined;\n const columns = inputColumns.filter((c) => isLinkerColumn(c.spec) || !isColumnHidden(c.spec));\n\n const tableStateNormalized = upgradePlDataTableStateV2(tableState);\n\n const allLabelColumns = getAllLabelColumns(ctx.resultPool);\n if (!allLabelColumns) return undefined;\n\n const fullLabelColumns = getMatchingLabelColumns(columns.map(getColumnIdAndSpec), allLabelColumns);\n const fullColumns = [...columns, ...fullLabelColumns];\n\n const fullColumnsAxes = uniqueBy(\n [...fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a)))],\n (a) => canonicalizeJson<AxisId>(a),\n );\n const fullColumnsIds: PTableColumnId[] = [\n ...fullColumnsAxes.map((a) => ({ type: 'axis', id: a } satisfies PTableColumnIdAxis)),\n ...fullColumns.map((c) => ({ type: 'column', id: c.id } satisfies PTableColumnIdColumn)),\n ];\n const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n const isValidColumnId = (id: PTableColumnId): boolean => fullColumnsIdsSet.has(canonicalizeJson<PTableColumnId>(id));\n\n const coreJoinType = ops?.coreJoinType ?? 'full';\n const partitionFilters: PTableRecordSingleValueFilterV2[]\n = tableStateNormalized.pTableParams.partitionFilters\n .filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const filters: PTableRecordSingleValueFilterV2[]\n = uniqueBy(\n [...(ops?.filters ?? []), ...tableStateNormalized.pTableParams.filters],\n (f) => canonicalizeJson<PTableColumnId>(f.column),\n ).filter((f) => {\n const valid = isValidColumnId(f.column);\n if (!valid) ctx.logWarn(`Filter ${JSON.stringify(f)} does not match provided columns, skipping`);\n return valid;\n });\n const sorting: PTableSorting[]\n = uniqueBy(\n [...(ops?.sorting ?? []), ...tableStateNormalized.pTableParams.sorting],\n (s) => canonicalizeJson<PTableColumnId>(s.column),\n ).filter((s) => {\n const valid = isValidColumnId(s.column);\n if (!valid) ctx.logWarn(`Sorting ${JSON.stringify(s)} does not match provided columns, skipping`);\n return valid;\n });\n\n const fullDef = createPTableDef({\n columns,\n labelColumns: fullLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const fullHandle = ctx.createPTable(fullDef);\n\n const hiddenColumns = new Set<PObjectId>(((): PObjectId[] => {\n // Inner join works as a filter - all columns must be present\n if (coreJoinType === 'inner') return [];\n\n const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;\n if (hiddenColIds) return hiddenColIds;\n\n return columns\n .filter((c) => isColumnOptional(c.spec))\n .map((c) => c.id);\n })());\n\n // Preserve linker columns\n columns\n .filter((c) => isLinkerColumn(c.spec))\n .forEach((c) => hiddenColumns.delete(c.id));\n\n // Preserve core columns as they change the shape of join.\n if (ops?.coreColumnPredicate) {\n const coreColumns = columns.flatMap((c) => ops?.coreColumnPredicate?.(c.spec) ? [c.id] : []);\n coreColumns.forEach((c) => hiddenColumns.delete(c));\n }\n\n // Filters decrease the number of result rows, sorting changes the order of result rows\n [...partitionFilters.map((f) => f.column), ...filters.map((f) => f.column), ...sorting.map((s) => s.column)]\n .filter((c): c is PTableColumnIdColumn => c.type === 'column')\n .forEach((c) => hiddenColumns.delete(c.id));\n\n const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));\n const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);\n\n // if at least one column is not yet computed, we can't show the table\n if (!allColumnsComputed([...visibleColumns, ...visibleLabelColumns])) return undefined;\n\n const visibleDef = createPTableDef({\n columns: visibleColumns,\n labelColumns: visibleLabelColumns,\n coreJoinType,\n partitionFilters,\n filters,\n sorting,\n coreColumnPredicate: ops?.coreColumnPredicate,\n });\n const visibleHandle = ctx.createPTable(visibleDef);\n\n return {\n sourceId: tableStateNormalized.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n visibleTableHandle: visibleHandle,\n } satisfies PlDataTableModel;\n}\n\n/** Create sheet entries for PlDataTable */\nexport function createPlDataTableSheet<A, U>(\n ctx: RenderCtx<A, U>,\n axis: AxisSpec,\n values: (string | number)[],\n): PlDataTableSheet {\n const labels = ctx.resultPool.findLabels(axis);\n return {\n axis,\n options: values.map((v) => ({\n value: v,\n label: labels?.[v] ?? v.toString(),\n })),\n defaultValue: values[0],\n };\n}\n"],"names":["isLabelColumn","column","PColumnName"],"mappings":";;;;;;AA6dM,SAAUA,EAAcC,GAAmB;AAC/C,SAAOA,EAAO,SAAS,WAAW,KAAKA,EAAO,SAASC,EAAY;AACrE;","x_google_ignoreList":[0]}
@@ -11,8 +11,8 @@ const F = p.object({
11
11
  id: p.string().optional(),
12
12
  label: p.string()
13
13
  }), J = p.array(F), P = 1e-3, W = "__LABEL__", j = "__LABEL__@1";
14
- function C(d, M, s = {}) {
15
- const g = /* @__PURE__ */ new Map(), _ = s.forceTraceElements !== void 0 && s.forceTraceElements.length > 0 ? new Set(s.forceTraceElements) : void 0, b = /* @__PURE__ */ new Map(), x = d.map((e) => {
14
+ function C(d, M, l = {}) {
15
+ const g = /* @__PURE__ */ new Map(), _ = l.forceTraceElements !== void 0 && l.forceTraceElements.length > 0 ? new Set(l.forceTraceElements) : void 0, b = /* @__PURE__ */ new Map(), x = d.map((e) => {
16
16
  const n = M(e);
17
17
  let t, a, i;
18
18
  "spec" in n && typeof n.spec == "object" ? (t = n.spec, a = n.prefixTrace, i = n.suffixTrace) : t = n;
@@ -23,7 +23,7 @@ function C(d, M, s = {}) {
23
23
  ];
24
24
  if (c !== void 0) {
25
25
  const o = { label: c, type: W, importance: -2 };
26
- s.addLabelAsSuffix ? r.push(o) : r.splice(0, 0, o);
26
+ l.addLabelAsSuffix ? r.push(o) : r.splice(0, 0, o);
27
27
  }
28
28
  const y = [], N = /* @__PURE__ */ new Map();
29
29
  for (let o = r.length - 1; o >= 0; --o) {
@@ -38,10 +38,10 @@ function C(d, M, s = {}) {
38
38
  label: c,
39
39
  fullTrace: y
40
40
  };
41
- }), l = [], T = [], A = [...g];
41
+ }), s = [], T = [], A = [...g];
42
42
  A.sort(([, e], [, n]) => n - e);
43
43
  for (const [e] of A)
44
- e.endsWith("@1") || b.get(e) === d.length ? l.push(e) : T.push(e);
44
+ e.endsWith("@1") || b.get(e) === d.length ? s.push(e) : T.push(e);
45
45
  const v = (e, n = !1) => {
46
46
  const t = [];
47
47
  for (let a = 0; a < x.length; a++) {
@@ -54,7 +54,7 @@ function C(d, M, s = {}) {
54
54
  });
55
55
  else
56
56
  return;
57
- const h = c.map((r) => r.label), w = s.separator ?? " / ";
57
+ const h = c.map((r) => r.label), w = l.separator ?? " / ";
58
58
  t.push({
59
59
  label: h.join(w),
60
60
  value: i.value
@@ -62,24 +62,24 @@ function C(d, M, s = {}) {
62
62
  }
63
63
  return t;
64
64
  };
65
- if (l.length === 0) {
65
+ if (s.length === 0) {
66
66
  if (T.length !== 0)
67
67
  throw new Error("Non-empty secondary types list while main types list is empty.");
68
68
  return v(new Set(j), !0);
69
69
  }
70
70
  let m = 0, f = -1;
71
- for (; m < l.length; ) {
71
+ for (; m < s.length; ) {
72
72
  const e = /* @__PURE__ */ new Set();
73
- s.includeNativeLabel && e.add(j);
73
+ l.includeNativeLabel && e.add(j);
74
74
  for (let t = 0; t < m; ++t)
75
- e.add(l[t]);
76
- f >= 0 && e.add(l[f]);
75
+ e.add(s[t]);
76
+ f >= 0 && e.add(s[f]);
77
77
  const n = v(e);
78
78
  if (n !== void 0 && new Set(n.map((t) => t.label)).size === d.length)
79
79
  return n;
80
- f++, f >= l.length && (m++, f = m);
80
+ f++, f >= s.length && (m++, f = m);
81
81
  }
82
- return v(/* @__PURE__ */ new Set([...l, ...T]), !0);
82
+ return v(/* @__PURE__ */ new Set([...s, ...T]), !0);
83
83
  }
84
84
  export {
85
85
  J as Trace,