@platforma-sdk/model 1.24.9 → 1.24.11

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 (66) hide show
  1. package/dist/bconfig/container.d.ts.map +1 -1
  2. package/dist/bconfig/lambdas.d.ts +1 -1
  3. package/dist/bconfig/lambdas.d.ts.map +1 -1
  4. package/dist/bconfig/normalization.d.ts.map +1 -1
  5. package/dist/bconfig/types.d.ts.map +1 -1
  6. package/dist/bconfig/utils.d.ts.map +1 -1
  7. package/dist/bconfig/v3.d.ts.map +1 -1
  8. package/dist/block_api.d.ts.map +1 -1
  9. package/dist/block_state_patch.d.ts.map +1 -1
  10. package/dist/block_state_util.d.ts.map +1 -1
  11. package/dist/builder.d.ts.map +1 -1
  12. package/dist/components/PFrameForGraphs.d.ts.map +1 -1
  13. package/dist/config/actions.d.ts.map +1 -1
  14. package/dist/config/actions_kinds.d.ts.map +1 -1
  15. package/dist/config/model.d.ts.map +1 -1
  16. package/dist/config/type_engine.d.ts.map +1 -1
  17. package/dist/config/type_util.d.ts.map +1 -1
  18. package/dist/index.js +1 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +2 -1
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/internal.d.ts.map +1 -1
  23. package/dist/pframe.d.ts.map +1 -1
  24. package/dist/platforma.d.ts.map +1 -1
  25. package/dist/raw_globals.d.ts.map +1 -1
  26. package/dist/ref_util.d.ts.map +1 -1
  27. package/dist/render/accessor.d.ts.map +1 -1
  28. package/dist/render/api.d.ts +2 -2
  29. package/dist/render/api.d.ts.map +1 -1
  30. package/dist/render/future.d.ts +2 -2
  31. package/dist/render/future.d.ts.map +1 -1
  32. package/dist/render/internal.d.ts +2 -2
  33. package/dist/render/internal.d.ts.map +1 -1
  34. package/dist/render/util/label.d.ts.map +1 -1
  35. package/dist/render/util/resource_map.d.ts.map +1 -1
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.d.ts.map +1 -1
  38. package/package.json +5 -4
  39. package/src/bconfig/container.ts +3 -3
  40. package/src/bconfig/lambdas.ts +2 -2
  41. package/src/bconfig/normalization.ts +26 -25
  42. package/src/bconfig/types.ts +3 -3
  43. package/src/bconfig/utils.ts +1 -1
  44. package/src/bconfig/v3.ts +4 -4
  45. package/src/block_api.ts +3 -3
  46. package/src/block_state_patch.ts +3 -3
  47. package/src/block_state_util.ts +4 -4
  48. package/src/builder.ts +50 -44
  49. package/src/components/PFrameForGraphs.ts +171 -169
  50. package/src/config/actions.ts +71 -71
  51. package/src/config/actions_kinds.ts +9 -9
  52. package/src/config/model.ts +3 -1
  53. package/src/config/type_engine.ts +3 -2
  54. package/src/config/type_util.ts +1 -1
  55. package/src/internal.ts +4 -4
  56. package/src/pframe.ts +3 -3
  57. package/src/platforma.ts +7 -7
  58. package/src/raw_globals.ts +1 -1
  59. package/src/ref_util.ts +4 -3
  60. package/src/render/accessor.ts +30 -28
  61. package/src/render/api.ts +10 -6
  62. package/src/render/future.ts +3 -3
  63. package/src/render/internal.ts +8 -8
  64. package/src/render/util/label.ts +7 -7
  65. package/src/render/util/resource_map.ts +6 -7
  66. package/src/sdk_info.ts +1 -1
package/src/builder.ts CHANGED
@@ -1,10 +1,12 @@
1
- import { BlockRenderingMode, BlockSection, ValueOrErrors } from '@milaboratories/pl-model-common';
2
- import { Checked, ConfigResult, getImmediate, PlResourceEntry, TypedConfig } from './config';
1
+ import type { BlockRenderingMode, BlockSection, ValueOrErrors, AnyFunction } from '@milaboratories/pl-model-common';
2
+ import type { Checked, ConfigResult, TypedConfig } from './config';
3
+ import { getImmediate } from './config';
3
4
  import { getPlatformaInstance, isInUI, tryRegisterCallback } from './internal';
4
- import { Platforma } from './platforma';
5
- import { InferRenderFunctionReturn, RenderCtx, RenderFunction } from './render';
5
+ import type { Platforma } from './platforma';
6
+ import type { InferRenderFunctionReturn, RenderFunction } from './render';
7
+ import { RenderCtx } from './render';
6
8
  import { PlatformaSDKVersion } from './version';
7
- import {
9
+ import type {
8
10
  TypedConfigOrConfigLambda,
9
11
  ConfigRenderLambda,
10
12
  StdCtxArgsOnly,
@@ -12,8 +14,10 @@ import {
12
14
  ResolveCfgType,
13
15
  ExtractFunctionHandleReturn,
14
16
  BlockConfigContainer,
17
+ ConfigRenderLambdaFlags,
18
+ } from './bconfig';
19
+ import {
15
20
  downgradeCfgOrLambda,
16
- ConfigRenderLambdaFlags
17
21
  } from './bconfig';
18
22
 
19
23
  type SectionsExpectedType = readonly BlockSection[];
@@ -23,10 +27,11 @@ type SectionsCfgChecked<Cfg extends TypedConfig, Args, UiState> = Checked<
23
27
  ConfigResult<Cfg, StdCtxArgsOnly<Args, UiState>> extends SectionsExpectedType ? true : false
24
28
  >;
25
29
 
26
- type SectionsRFChecked<RF extends Function> = Checked<
27
- RF,
28
- InferRenderFunctionReturn<RF> extends SectionsExpectedType ? true : false
29
- >;
30
+ // TODO (Unused type in code)
31
+ // type SectionsRFChecked<RF extends Function> = Checked<
32
+ // RF,
33
+ // InferRenderFunctionReturn<RF> extends SectionsExpectedType ? true : false
34
+ // >;
30
35
 
31
36
  type InputsValidExpectedType = boolean;
32
37
 
@@ -35,10 +40,11 @@ type InputsValidCfgChecked<Cfg extends TypedConfig, Args, UiState> = Checked<
35
40
  ConfigResult<Cfg, StdCtxArgsOnly<Args, UiState>> extends InputsValidExpectedType ? true : false
36
41
  >;
37
42
 
38
- type InputsValidRFChecked<RF extends Function> = Checked<
39
- RF,
40
- InferRenderFunctionReturn<RF> extends InputsValidExpectedType ? true : false
41
- >;
43
+ // TODO (Unused type in code)
44
+ // type InputsValidRFChecked<RF extends Function> = Checked<
45
+ // RF,
46
+ // InferRenderFunctionReturn<RF> extends InputsValidExpectedType ? true : false
47
+ // >;
42
48
 
43
49
  type NoOb = Record<string, never>;
44
50
 
@@ -49,7 +55,7 @@ export class BlockModel<
49
55
  Args,
50
56
  OutputsCfg extends Record<string, TypedConfigOrConfigLambda>,
51
57
  UiState,
52
- Href extends `/${string}` = '/'
58
+ Href extends `/${string}` = '/',
53
59
  > {
54
60
  private constructor(
55
61
  private readonly _renderingMode: BlockRenderingMode,
@@ -58,7 +64,7 @@ export class BlockModel<
58
64
  private readonly _outputs: OutputsCfg,
59
65
  private readonly _inputsValid: TypedConfigOrConfigLambda,
60
66
  private readonly _sections: TypedConfigOrConfigLambda,
61
- private readonly _title: ConfigRenderLambda | undefined
67
+ private readonly _title: ConfigRenderLambda | undefined,
62
68
  ) {}
63
69
 
64
70
  /** Initiates configuration builder */
@@ -83,7 +89,7 @@ export class BlockModel<
83
89
  {},
84
90
  getImmediate(true),
85
91
  getImmediate([]),
86
- undefined
92
+ undefined,
87
93
  );
88
94
  }
89
95
 
@@ -119,8 +125,8 @@ export class BlockModel<
119
125
  >;
120
126
  public output(
121
127
  key: string,
122
- cfgOrRf: TypedConfig | Function,
123
- flags: ConfigRenderLambdaFlags = {}
128
+ cfgOrRf: TypedConfig | AnyFunction,
129
+ flags: ConfigRenderLambdaFlags = {},
124
130
  ): BlockModel<Args, OutputsCfg, UiState, Href> {
125
131
  if (typeof cfgOrRf === 'function') {
126
132
  const handle = `output#${key}`;
@@ -134,12 +140,12 @@ export class BlockModel<
134
140
  [key]: {
135
141
  __renderLambda: true,
136
142
  handle,
137
- ...flags
138
- } satisfies ConfigRenderLambda
143
+ ...flags,
144
+ } satisfies ConfigRenderLambda,
139
145
  },
140
146
  this._inputsValid,
141
147
  this._sections,
142
- this._title
148
+ this._title,
143
149
  );
144
150
  } else
145
151
  return new BlockModel(
@@ -148,24 +154,24 @@ export class BlockModel<
148
154
  this._initialUiState,
149
155
  {
150
156
  ...this._outputs,
151
- [key]: cfgOrRf
157
+ [key]: cfgOrRf,
152
158
  },
153
159
  this._inputsValid,
154
160
  this._sections,
155
- this._title
161
+ this._title,
156
162
  );
157
163
  }
158
164
 
159
165
  /** Shortcut for {@link output} with retentive flag set to true. */
160
166
  public retentiveOutput<const Key extends string, const RF extends RenderFunction<Args, UiState>>(
161
167
  key: Key,
162
- rf: RF
168
+ rf: RF,
163
169
  ): BlockModel<
164
- Args,
170
+ Args,
165
171
  OutputsCfg & { [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> },
166
172
  UiState,
167
173
  Href
168
- > {
174
+ > {
169
175
  return this.output(key, rf, { retentive: true });
170
176
  }
171
177
 
@@ -179,7 +185,7 @@ export class BlockModel<
179
185
  rf: RF
180
186
  ): BlockModel<Args, OutputsCfg, UiState, Href>;
181
187
  public argsValid(
182
- cfgOrRf: TypedConfig | Function
188
+ cfgOrRf: TypedConfig | AnyFunction,
183
189
  ): BlockModel<Args, OutputsCfg, UiState, `/${string}`> {
184
190
  if (typeof cfgOrRf === 'function') {
185
191
  tryRegisterCallback('inputsValid', () => cfgOrRf(new RenderCtx()));
@@ -190,10 +196,10 @@ export class BlockModel<
190
196
  this._outputs,
191
197
  {
192
198
  __renderLambda: true,
193
- handle: 'inputsValid'
199
+ handle: 'inputsValid',
194
200
  } satisfies ConfigRenderLambda,
195
201
  this._sections,
196
- this._title
202
+ this._title,
197
203
  );
198
204
  } else
199
205
  return new BlockModel<Args, OutputsCfg, UiState>(
@@ -203,7 +209,7 @@ export class BlockModel<
203
209
  this._outputs,
204
210
  cfgOrRf,
205
211
  this._sections,
206
- this._title
212
+ this._title,
207
213
  );
208
214
  }
209
215
 
@@ -215,7 +221,7 @@ export class BlockModel<
215
221
  /** Sets the config to generate list of section in the left block overviews panel */
216
222
  public sections<
217
223
  const Ret extends SectionsExpectedType,
218
- const RF extends RenderFunction<Args, UiState, Ret>
224
+ const RF extends RenderFunction<Args, UiState, Ret>,
219
225
  >(rf: RF): BlockModel<Args, OutputsCfg, UiState, DeriveHref<ReturnType<RF>>>;
220
226
  public sections<const Cfg extends TypedConfig>(
221
227
  cfg: Cfg & SectionsCfgChecked<Cfg, Args, UiState>
@@ -226,7 +232,7 @@ export class BlockModel<
226
232
  DeriveHref<ConfigResult<Cfg, StdCtxArgsOnly<Args, UiState>>>
227
233
  >;
228
234
  public sections(
229
- arrOrCfgOrRf: SectionsExpectedType | TypedConfig | Function
235
+ arrOrCfgOrRf: SectionsExpectedType | TypedConfig | AnyFunction,
230
236
  ): BlockModel<Args, OutputsCfg, UiState, `/${string}`> {
231
237
  if (Array.isArray(arrOrCfgOrRf)) {
232
238
  return this.sections(getImmediate(arrOrCfgOrRf));
@@ -239,7 +245,7 @@ export class BlockModel<
239
245
  this._outputs,
240
246
  this._inputsValid,
241
247
  { __renderLambda: true, handle: 'sections' } as ConfigRenderLambda,
242
- this._title
248
+ this._title,
243
249
  );
244
250
  } else
245
251
  return new BlockModel<Args, OutputsCfg, UiState>(
@@ -249,13 +255,13 @@ export class BlockModel<
249
255
  this._outputs,
250
256
  this._inputsValid,
251
257
  arrOrCfgOrRf as TypedConfig,
252
- this._title
258
+ this._title,
253
259
  );
254
260
  }
255
261
 
256
262
  /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */
257
263
  public title(
258
- rf: RenderFunction<Args, UiState, string>
264
+ rf: RenderFunction<Args, UiState, string>,
259
265
  ): BlockModel<Args, OutputsCfg, UiState, Href> {
260
266
  tryRegisterCallback('title', () => rf(new RenderCtx()));
261
267
  return new BlockModel<Args, OutputsCfg, UiState, Href>(
@@ -265,7 +271,7 @@ export class BlockModel<
265
271
  this._outputs,
266
272
  this._inputsValid,
267
273
  this._sections,
268
- { __renderLambda: true, handle: 'title' } as ConfigRenderLambda
274
+ { __renderLambda: true, handle: 'title' } as ConfigRenderLambda,
269
275
  );
270
276
  }
271
277
 
@@ -281,7 +287,7 @@ export class BlockModel<
281
287
  this._outputs,
282
288
  this._inputsValid,
283
289
  this._sections,
284
- this._title
290
+ this._title,
285
291
  );
286
292
  }
287
293
 
@@ -294,7 +300,7 @@ export class BlockModel<
294
300
  this._outputs,
295
301
  this._inputsValid,
296
302
  this._sections,
297
- this._title
303
+ this._title,
298
304
  );
299
305
  }
300
306
 
@@ -307,7 +313,7 @@ export class BlockModel<
307
313
  this._outputs,
308
314
  this._inputsValid,
309
315
  this._sections,
310
- this._title
316
+ this._title,
311
317
  );
312
318
  }
313
319
 
@@ -331,7 +337,7 @@ export class BlockModel<
331
337
  inputsValid: this._inputsValid,
332
338
  sections: this._sections,
333
339
  title: this._title,
334
- outputs: this._outputs
340
+ outputs: this._outputs,
335
341
  },
336
342
 
337
343
  // fields below are added to allow previous desktop versions read generated configs
@@ -341,8 +347,8 @@ export class BlockModel<
341
347
  inputsValid: downgradeCfgOrLambda(this._inputsValid),
342
348
  sections: downgradeCfgOrLambda(this._sections),
343
349
  outputs: Object.fromEntries(
344
- Object.entries(this._outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)])
345
- )
350
+ Object.entries(this._outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)]),
351
+ ),
346
352
  };
347
353
 
348
354
  if (!isInUI())
@@ -362,7 +368,7 @@ export type InferOutputType<CfgOrFH, Args, UiState> = CfgOrFH extends TypedConfi
362
368
  type InferOutputsFromConfigs<
363
369
  Args,
364
370
  OutputsCfg extends Record<string, TypedConfigOrConfigLambda>,
365
- UiState
371
+ UiState,
366
372
  > = {
367
373
  [Key in keyof OutputsCfg]: ValueOrErrors<InferOutputType<OutputsCfg[Key], Args, UiState>>;
368
374
  };
@@ -1,64 +1,66 @@
1
+ import type {
2
+ AxisId,
3
+ PColumn,
4
+ PColumnValues,
5
+ PFrameHandle,
6
+ PObjectId,
7
+ ValueType } from '@milaboratories/pl-model-common';
1
8
  import {
2
- AxisId,
3
- getAxisId,
4
- isPColumn,
5
- matchAxisId,
6
- PColumn,
7
- PColumnValues,
8
- PFrameHandle,
9
- PObjectId,
10
- ValueType,
9
+ getAxisId,
10
+ isPColumn,
11
+ matchAxisId,
11
12
  } from '@milaboratories/pl-model-common';
12
- import {RenderCtx, TreeNodeAccessor} from '../render';
13
+ import type { RenderCtx } from '../render';
14
+ import { TreeNodeAccessor } from '../render';
13
15
 
14
16
  /** Create id for column copy with added keys in axes domains */
15
17
  const colId = (id: PObjectId, domains: (Record<string, string> | undefined)[]) => {
16
- let wid = id.toString();
17
- domains?.forEach(domain => {
18
- if (domain) {
19
- for (const [k, v] of Object.entries(domain)) {
20
- wid += k;
21
- wid += v;
22
- }
23
- }
24
- });
25
- return wid;
18
+ let wid = id.toString();
19
+ domains?.forEach((domain) => {
20
+ if (domain) {
21
+ for (const [k, v] of Object.entries(domain)) {
22
+ wid += k;
23
+ wid += v;
24
+ }
25
+ }
26
+ });
27
+ return wid;
26
28
  };
27
29
 
28
30
  /** All combinations with 1 key from each list */
29
31
  function getKeysCombinations(idsLists: AxisId[][]) {
30
- if (!idsLists.length) {
31
- return [];
32
- }
33
- let result: AxisId[][] = [[]];
34
- idsLists.forEach(list => {
35
- const nextResult: AxisId[][] = [];
36
- list.forEach(key => {
37
- nextResult.push(...result.map(resultItem => [...resultItem, key]));
38
- });
39
- result = nextResult;
32
+ if (!idsLists.length) {
33
+ return [];
34
+ }
35
+ let result: AxisId[][] = [[]];
36
+ idsLists.forEach((list) => {
37
+ const nextResult: AxisId[][] = [];
38
+ list.forEach((key) => {
39
+ nextResult.push(...result.map((resultItem) => [...resultItem, key]));
40
40
  });
41
- return result;
41
+ result = nextResult;
42
+ });
43
+ return result;
42
44
  }
43
45
 
44
46
  /** Check if axes of secondary column are exactly in axes of main column */
45
47
  function checkFullCompatibility(
46
- mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
47
- secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>
48
+ mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
49
+ secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>,
48
50
  ): boolean {
49
- const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
50
- const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
51
- return secondaryAxesIds.every(id => mainAxesIds.some(mainId => matchAxisId(mainId, id) && matchAxisId(id, mainId)));
51
+ const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
52
+ const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
53
+ return secondaryAxesIds.every((id) => mainAxesIds.some((mainId) => matchAxisId(mainId, id) && matchAxisId(id, mainId)));
52
54
  }
53
55
 
54
56
  /** Check if axes of secondary column are in axes of main column, but they can have compatible difference in domains */
55
57
  function checkCompatibility(
56
- mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
57
- secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>
58
+ mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
59
+ secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>,
58
60
  ): boolean {
59
- const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
60
- const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
61
- return secondaryAxesIds.every(id => mainAxesIds.some(mainId => matchAxisId(mainId, id)));
61
+ const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
62
+ const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
63
+ return secondaryAxesIds.every((id) => mainAxesIds.some((mainId) => matchAxisId(mainId, id)));
62
64
  }
63
65
 
64
66
  export const IS_VIRTUAL_COLUMN = 'pl7.app/graph/isVirtual'; // annotation for column duplicates with extended domains
@@ -67,157 +69,157 @@ export const LABEL_ANNOTATION = 'pl7.app/label';
67
69
  /** Main column can have additional domains, if secondary column (meta-column) has all axes match main column axes
68
70
  we can add its copy with missed domain fields for compatibility */
69
71
  function getAdditionalColumnsForPair(
70
- mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
71
- secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>
72
+ mainColumn: PColumn<TreeNodeAccessor | PColumnValues>,
73
+ secondaryColumn: PColumn<TreeNodeAccessor | PColumnValues>,
72
74
  ): PColumn<TreeNodeAccessor | PColumnValues>[] {
73
- const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
74
- const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
75
-
76
- const isFullCompatible = checkFullCompatibility(mainColumn, secondaryColumn);
77
- if (isFullCompatible) { // in this case it isn't necessary to add more columns
78
- return [];
79
- }
80
- const isCompatible = checkCompatibility(mainColumn, secondaryColumn);
81
- if (!isCompatible) { // in this case it is impossible to add some compatible column
82
- return [];
83
- }
84
- // options with different possible domains for every axis of secondary column
85
- const secondaryIdsOptions = secondaryAxesIds.map(id => {
86
- return mainAxesIds.filter(mainId => matchAxisId(mainId, id));
87
- });
75
+ const mainAxesIds = mainColumn.spec.axesSpec.map(getAxisId);
76
+ const secondaryAxesIds = secondaryColumn.spec.axesSpec.map(getAxisId);
77
+
78
+ const isFullCompatible = checkFullCompatibility(mainColumn, secondaryColumn);
79
+ if (isFullCompatible) { // in this case it isn't necessary to add more columns
80
+ return [];
81
+ }
82
+ const isCompatible = checkCompatibility(mainColumn, secondaryColumn);
83
+ if (!isCompatible) { // in this case it is impossible to add some compatible column
84
+ return [];
85
+ }
86
+ // options with different possible domains for every axis of secondary column
87
+ const secondaryIdsOptions = secondaryAxesIds.map((id) => {
88
+ return mainAxesIds.filter((mainId) => matchAxisId(mainId, id));
89
+ });
88
90
  // all possible combinations of axes with added domains
89
- const secondaryIdsVariants = getKeysCombinations(secondaryIdsOptions);
90
-
91
- // sets of added to column domain fields
92
- const allAddedDomainValues = new Set<string>();
93
- const addedNotToAllVariantsDomainValues = new Set<string>();
94
- const addedByVariantsDomainValues = secondaryIdsVariants.map(idsList => {
95
- const addedSet = new Set<string>();
96
- idsList.map((axisId, idx) => {
97
- const d1 = secondaryColumn.spec.axesSpec[idx].domain;
98
- const d2 = axisId.domain;
99
- Object.entries(d2 ?? {}).forEach(([key, value]) => {
100
- if (d1?.[key] === undefined) {
101
- const item = JSON.stringify([key, value]);
102
- addedSet.add(item);
103
- allAddedDomainValues.add(item);
104
- }
105
- });
106
- return ({
107
- ...axisId,
108
- annotations: secondaryColumn.spec.axesSpec[idx].annotations
109
- })
110
- });
111
- return addedSet;
112
- });
113
- [...allAddedDomainValues].forEach(addedPart => {
114
- if (addedByVariantsDomainValues.some(s => !s.has(addedPart))) {
115
- addedNotToAllVariantsDomainValues.add(addedPart);
91
+ const secondaryIdsVariants = getKeysCombinations(secondaryIdsOptions);
92
+
93
+ // sets of added to column domain fields
94
+ const allAddedDomainValues = new Set<string>();
95
+ const addedNotToAllVariantsDomainValues = new Set<string>();
96
+ const addedByVariantsDomainValues = secondaryIdsVariants.map((idsList) => {
97
+ const addedSet = new Set<string>();
98
+ idsList.map((axisId, idx) => {
99
+ const d1 = secondaryColumn.spec.axesSpec[idx].domain;
100
+ const d2 = axisId.domain;
101
+ Object.entries(d2 ?? {}).forEach(([key, value]) => {
102
+ if (d1?.[key] === undefined) {
103
+ const item = JSON.stringify([key, value]);
104
+ addedSet.add(item);
105
+ allAddedDomainValues.add(item);
116
106
  }
117
- })
118
-
119
- return secondaryIdsVariants.map((idsList, idx) => {
120
- const id = colId(secondaryColumn.id, idsList.map(id => id.domain));
121
-
122
- const label = secondaryColumn.spec.annotations?.[LABEL_ANNOTATION] ?? '';
123
- const labelDomainPart = ([...addedByVariantsDomainValues[idx]])
124
- .filter(str => addedNotToAllVariantsDomainValues.has(str))
125
- .sort()
126
- .map((v) => JSON.parse(v)?.[1]) // use in labels only domain values, but sort them by key to save the same order in all column variants
127
- .join(' / ');
128
-
129
- const annotations:Record<string, string> = {
130
- ...secondaryColumn.spec.annotations,
131
- [IS_VIRTUAL_COLUMN]: 'true'
132
- }
133
- if (label || labelDomainPart) {
134
- annotations[LABEL_ANNOTATION] = label && labelDomainPart ? label + ' / ' + labelDomainPart : label + labelDomainPart;
135
- }
136
-
137
- return {
138
- id: id as PObjectId,
139
- spec: {
140
- ...secondaryColumn.spec,
141
- axesSpec: idsList.map((axisId, idx) => ({
142
- ...axisId,
143
- annotations: secondaryColumn.spec.axesSpec[idx].annotations
144
- })),
145
- annotations
146
- },
147
- data: secondaryColumn.data
148
- };
107
+ });
108
+ return ({
109
+ ...axisId,
110
+ annotations: secondaryColumn.spec.axesSpec[idx].annotations,
111
+ });
149
112
  });
113
+ return addedSet;
114
+ });
115
+ [...allAddedDomainValues].forEach((addedPart) => {
116
+ if (addedByVariantsDomainValues.some((s) => !s.has(addedPart))) {
117
+ addedNotToAllVariantsDomainValues.add(addedPart);
118
+ }
119
+ });
120
+
121
+ return secondaryIdsVariants.map((idsList, idx) => {
122
+ const id = colId(secondaryColumn.id, idsList.map((id) => id.domain));
123
+
124
+ const label = secondaryColumn.spec.annotations?.[LABEL_ANNOTATION] ?? '';
125
+ const labelDomainPart = ([...addedByVariantsDomainValues[idx]])
126
+ .filter((str) => addedNotToAllVariantsDomainValues.has(str))
127
+ .sort()
128
+ .map((v) => JSON.parse(v)?.[1]) // use in labels only domain values, but sort them by key to save the same order in all column variants
129
+ .join(' / ');
130
+
131
+ const annotations: Record<string, string> = {
132
+ ...secondaryColumn.spec.annotations,
133
+ [IS_VIRTUAL_COLUMN]: 'true',
134
+ };
135
+ if (label || labelDomainPart) {
136
+ annotations[LABEL_ANNOTATION] = label && labelDomainPart ? label + ' / ' + labelDomainPart : label + labelDomainPart;
137
+ }
138
+
139
+ return {
140
+ id: id as PObjectId,
141
+ spec: {
142
+ ...secondaryColumn.spec,
143
+ axesSpec: idsList.map((axisId, idx) => ({
144
+ ...axisId,
145
+ annotations: secondaryColumn.spec.axesSpec[idx].annotations,
146
+ })),
147
+ annotations,
148
+ },
149
+ data: secondaryColumn.data,
150
+ };
151
+ });
150
152
  }
151
153
 
152
154
  export function getAdditionalColumns(columns: PColumn<TreeNodeAccessor | PColumnValues>[]): PColumn<TreeNodeAccessor | PColumnValues>[] {
153
- const additionalColumns: PColumn<TreeNodeAccessor | PColumnValues>[] = [];
154
- for (let i = 0; i < columns.length; i++) {
155
- for (let j = i + 1; j < columns.length; j++) {
156
- const column1 = columns[i];
157
- const column2 = columns[j];
158
-
159
- // check if column 1 is meta for column 2 or backward
160
- additionalColumns.push(
161
- ...getAdditionalColumnsForPair(column1, column2),
162
- ...getAdditionalColumnsForPair(column2, column1)
163
- );
164
- }
155
+ const additionalColumns: PColumn<TreeNodeAccessor | PColumnValues>[] = [];
156
+ for (let i = 0; i < columns.length; i++) {
157
+ for (let j = i + 1; j < columns.length; j++) {
158
+ const column1 = columns[i];
159
+ const column2 = columns[j];
160
+
161
+ // check if column 1 is meta for column 2 or backward
162
+ additionalColumns.push(
163
+ ...getAdditionalColumnsForPair(column1, column2),
164
+ ...getAdditionalColumnsForPair(column2, column1),
165
+ );
165
166
  }
166
- return additionalColumns;
167
+ }
168
+ return additionalColumns;
167
169
  }
168
170
 
169
171
  export function enrichColumnsWithCompatible(
170
- mainColumns: PColumn<TreeNodeAccessor | PColumnValues>[],
171
- secondaryColumns: PColumn<TreeNodeAccessor | PColumnValues>[]
172
+ mainColumns: PColumn<TreeNodeAccessor | PColumnValues>[],
173
+ secondaryColumns: PColumn<TreeNodeAccessor | PColumnValues>[],
172
174
  ): PColumn<TreeNodeAccessor | PColumnValues>[] {
173
- const result = [...mainColumns];
174
- for (const secondaryColumn of secondaryColumns) {
175
- for (const mainColumn of mainColumns) {
176
- if (mainColumn.id === secondaryColumn.id) {
177
- break;
178
- }
179
- if (checkCompatibility(mainColumn, secondaryColumn)) {
180
- result.push(secondaryColumn);
181
- break;
182
- }
183
- }
175
+ const result = [...mainColumns];
176
+ for (const secondaryColumn of secondaryColumns) {
177
+ for (const mainColumn of mainColumns) {
178
+ if (mainColumn.id === secondaryColumn.id) {
179
+ break;
180
+ }
181
+ if (checkCompatibility(mainColumn, secondaryColumn)) {
182
+ result.push(secondaryColumn);
183
+ break;
184
+ }
184
185
  }
185
- return result;
186
+ }
187
+ return result;
186
188
  }
187
189
 
188
190
  const VALUE_TYPES: ValueType[] = [
189
- 'Int',
190
- 'Long',
191
- 'Float',
192
- 'Double',
193
- 'String',
194
- 'Bytes'
191
+ 'Int',
192
+ 'Long',
193
+ 'Float',
194
+ 'Double',
195
+ 'String',
196
+ 'Bytes',
195
197
  ];
196
198
 
197
199
  export function createPFrameForGraphs<A, U>(
198
- ctx: RenderCtx<A, U>,
199
- blockColumns?: PColumn<TreeNodeAccessor | PColumnValues>[]
200
+ ctx: RenderCtx<A, U>,
201
+ blockColumns?: PColumn<TreeNodeAccessor | PColumnValues>[],
200
202
  ): PFrameHandle | undefined {
201
- if (blockColumns === undefined) return undefined;
203
+ if (blockColumns === undefined) return undefined;
202
204
 
203
- const upstreamColumns = ctx.resultPool
204
- .getData()
205
- .entries.map((v) => v.obj)
206
- .filter(isPColumn)
207
- .filter((column) => VALUE_TYPES.includes(column.spec.valueType));
205
+ const upstreamColumns = ctx.resultPool
206
+ .getData()
207
+ .entries.map((v) => v.obj)
208
+ .filter(isPColumn)
209
+ .filter((column) => VALUE_TYPES.includes(column.spec.valueType));
208
210
 
209
- const columnsWithCompatibleFromUpstream = enrichColumnsWithCompatible(blockColumns, upstreamColumns);
211
+ const columnsWithCompatibleFromUpstream = enrichColumnsWithCompatible(blockColumns, upstreamColumns);
210
212
 
211
- // additional columns are duplicates with extra fields in domains for compatibility in all possible pairs of columns set
212
- const extendedColumns = [...columnsWithCompatibleFromUpstream, ...getAdditionalColumns(columnsWithCompatibleFromUpstream)];
213
+ // additional columns are duplicates with extra fields in domains for compatibility in all possible pairs of columns set
214
+ const extendedColumns = [...columnsWithCompatibleFromUpstream, ...getAdditionalColumns(columnsWithCompatibleFromUpstream)];
213
215
 
214
- // if at least one column is not yet ready, we can't show the table
215
- if (
216
- extendedColumns.some(
217
- (a) => a.data instanceof TreeNodeAccessor && !a.data.getIsReadyOrError()
218
- )
216
+ // if at least one column is not yet ready, we can't show the table
217
+ if (
218
+ extendedColumns.some(
219
+ (a) => a.data instanceof TreeNodeAccessor && !a.data.getIsReadyOrError(),
219
220
  )
220
- return undefined;
221
+ )
222
+ return undefined;
221
223
 
222
- return ctx.createPFrame(extendedColumns);
223
- }
224
+ return ctx.createPFrame(extendedColumns);
225
+ }