@milaboratories/milaboratories.ui-examples.model 1.4.9 → 1.4.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.
- package/.oxfmtrc.json +4 -0
- package/.oxlintrc.json +3 -0
- package/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-formatter$colon$check.log +12 -0
- package/.turbo/turbo-linter$colon$check.log +10 -0
- package/.turbo/{turbo-type-check.log → turbo-types$colon$check.log} +2 -2
- package/CHANGELOG.md +15 -0
- package/dist/bundle.js +596 -566
- package/dist/bundle.js.map +1 -1
- package/dist/index.cjs +96 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -100
- package/dist/index.js.map +1 -1
- package/dist/model.json +1 -1
- package/package.json +10 -9
- package/src/index.ts +100 -108
- package/tsconfig.json +3 -10
- package/.turbo/turbo-lint.log +0 -5
- package/eslint.config.mjs +0 -7
package/dist/bundle.js
CHANGED
|
@@ -21,28 +21,28 @@
|
|
|
21
21
|
* Discriminator key for BlockStorage format detection.
|
|
22
22
|
* This unique hash-based key identifies data as BlockStorage vs legacy formats.
|
|
23
23
|
*/
|
|
24
|
-
const BLOCK_STORAGE_KEY =
|
|
24
|
+
const BLOCK_STORAGE_KEY = "__pl_a7f3e2b9__";
|
|
25
25
|
/**
|
|
26
26
|
* Current BlockStorage schema version.
|
|
27
27
|
* Increment this when the storage structure itself changes (not block state migrations).
|
|
28
28
|
*/
|
|
29
|
-
const BLOCK_STORAGE_SCHEMA_VERSION =
|
|
29
|
+
const BLOCK_STORAGE_SCHEMA_VERSION = "v1";
|
|
30
30
|
/**
|
|
31
31
|
* Default data version for new blocks without migrations.
|
|
32
32
|
* Unique identifier ensures blocks are created via DataModel API.
|
|
33
33
|
*/
|
|
34
|
-
const DATA_MODEL_DEFAULT_VERSION =
|
|
34
|
+
const DATA_MODEL_DEFAULT_VERSION = "__pl_v1_d4e8f2a1__";
|
|
35
35
|
/**
|
|
36
36
|
* Type guard to check if a value is a valid BlockStorage object.
|
|
37
37
|
* Checks for the discriminator key and valid schema version.
|
|
38
38
|
*/
|
|
39
39
|
function isBlockStorage(value) {
|
|
40
|
-
if (value === null || typeof value !==
|
|
40
|
+
if (value === null || typeof value !== "object")
|
|
41
41
|
return false;
|
|
42
42
|
const obj = value;
|
|
43
43
|
const schemaVersion = obj[BLOCK_STORAGE_KEY];
|
|
44
44
|
// Currently only 'v1' is valid, but this allows future versions
|
|
45
|
-
return schemaVersion ===
|
|
45
|
+
return schemaVersion === "v1"; // Add more versions as schema evolves
|
|
46
46
|
}
|
|
47
47
|
// =============================================================================
|
|
48
48
|
// Factory Functions
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
return {
|
|
76
76
|
...storage,
|
|
77
77
|
// Fix for early released version where __dataVersion was a number
|
|
78
|
-
__dataVersion: typeof storage.__dataVersion ===
|
|
78
|
+
__dataVersion: typeof storage.__dataVersion === "number"
|
|
79
79
|
? DATA_MODEL_DEFAULT_VERSION
|
|
80
80
|
: storage.__dataVersion,
|
|
81
81
|
};
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
*/
|
|
105
105
|
function updateStorageData(storage, payload) {
|
|
106
106
|
switch (payload.operation) {
|
|
107
|
-
case
|
|
107
|
+
case "update-data":
|
|
108
108
|
return { ...storage, __data: payload.value };
|
|
109
109
|
default:
|
|
110
110
|
throw new Error(`Unknown storage operation: ${payload.operation}`);
|
|
@@ -118,33 +118,33 @@
|
|
|
118
118
|
// Json
|
|
119
119
|
//
|
|
120
120
|
function getImmediate(value) {
|
|
121
|
-
return { type:
|
|
121
|
+
return { type: "Immediate", value };
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/** Utility code helping to identify whether the code is running in actual UI environment */
|
|
125
125
|
function isInUI() {
|
|
126
|
-
return (typeof globalThis.getPlatforma !==
|
|
126
|
+
return (typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined");
|
|
127
127
|
}
|
|
128
128
|
/** Utility code helping to retrieve a platforma instance form the environment */
|
|
129
129
|
function getPlatformaInstance(config) {
|
|
130
|
-
if (config && typeof globalThis.getPlatforma ===
|
|
130
|
+
if (config && typeof globalThis.getPlatforma === "function")
|
|
131
131
|
return globalThis.getPlatforma(config);
|
|
132
|
-
else if (typeof globalThis.platforma !==
|
|
132
|
+
else if (typeof globalThis.platforma !== "undefined")
|
|
133
133
|
return globalThis.platforma;
|
|
134
134
|
else
|
|
135
|
-
throw new Error(
|
|
135
|
+
throw new Error("Can't get platforma instance.");
|
|
136
136
|
}
|
|
137
137
|
function tryGetCfgRenderCtx() {
|
|
138
|
-
if (typeof globalThis.cfgRenderCtx !==
|
|
138
|
+
if (typeof globalThis.cfgRenderCtx !== "undefined")
|
|
139
139
|
return globalThis.cfgRenderCtx;
|
|
140
140
|
else
|
|
141
141
|
return undefined;
|
|
142
142
|
}
|
|
143
143
|
function getCfgRenderCtx() {
|
|
144
|
-
if (typeof globalThis.cfgRenderCtx !==
|
|
144
|
+
if (typeof globalThis.cfgRenderCtx !== "undefined")
|
|
145
145
|
return globalThis.cfgRenderCtx;
|
|
146
146
|
else
|
|
147
|
-
throw new Error(
|
|
147
|
+
throw new Error("Not in config rendering context");
|
|
148
148
|
}
|
|
149
149
|
function tryRegisterCallback(key, callback) {
|
|
150
150
|
const ctx = tryGetCfgRenderCtx();
|
|
@@ -4401,7 +4401,7 @@
|
|
|
4401
4401
|
});
|
|
4402
4402
|
|
|
4403
4403
|
z.object({
|
|
4404
|
-
type: z.literal(
|
|
4404
|
+
type: z.literal("plain"),
|
|
4405
4405
|
content: z.string(),
|
|
4406
4406
|
});
|
|
4407
4407
|
|
|
@@ -4414,7 +4414,7 @@
|
|
|
4414
4414
|
});
|
|
4415
4415
|
|
|
4416
4416
|
function assertNever(x) {
|
|
4417
|
-
throw new Error(
|
|
4417
|
+
throw new Error("Unexpected object: " + x); // This is ok, because this is a possible runtime error
|
|
4418
4418
|
}
|
|
4419
4419
|
/**
|
|
4420
4420
|
* Return unique entries of the array by the provided id
|
|
@@ -4431,24 +4431,24 @@
|
|
|
4431
4431
|
* @returns True if the value is a valid DataInfo, false otherwise
|
|
4432
4432
|
*/
|
|
4433
4433
|
function isDataInfo(value) {
|
|
4434
|
-
if (!value || typeof value !==
|
|
4434
|
+
if (!value || typeof value !== "object") {
|
|
4435
4435
|
return false;
|
|
4436
4436
|
}
|
|
4437
4437
|
const data = value;
|
|
4438
|
-
if (!(
|
|
4438
|
+
if (!("type" in data)) {
|
|
4439
4439
|
return false;
|
|
4440
4440
|
}
|
|
4441
4441
|
switch (data.type) {
|
|
4442
|
-
case
|
|
4443
|
-
return (typeof data.keyLength ===
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
case
|
|
4447
|
-
case
|
|
4448
|
-
case
|
|
4449
|
-
return (typeof data.partitionKeyLength ===
|
|
4450
|
-
|
|
4451
|
-
|
|
4442
|
+
case "Json":
|
|
4443
|
+
return (typeof data.keyLength === "number" &&
|
|
4444
|
+
data.data !== undefined &&
|
|
4445
|
+
typeof data.data === "object");
|
|
4446
|
+
case "JsonPartitioned":
|
|
4447
|
+
case "BinaryPartitioned":
|
|
4448
|
+
case "ParquetPartitioned":
|
|
4449
|
+
return (typeof data.partitionKeyLength === "number" &&
|
|
4450
|
+
data.parts !== undefined &&
|
|
4451
|
+
typeof data.parts === "object");
|
|
4452
4452
|
default:
|
|
4453
4453
|
return false;
|
|
4454
4454
|
}
|
|
@@ -4458,10 +4458,10 @@
|
|
|
4458
4458
|
return undefined;
|
|
4459
4459
|
}
|
|
4460
4460
|
switch (dataInfo.type) {
|
|
4461
|
-
case
|
|
4461
|
+
case "Json":
|
|
4462
4462
|
// Json type doesn't contain blobs, so return as is
|
|
4463
4463
|
return dataInfo;
|
|
4464
|
-
case
|
|
4464
|
+
case "JsonPartitioned": {
|
|
4465
4465
|
// Map each blob in parts
|
|
4466
4466
|
const newParts = {};
|
|
4467
4467
|
for (const [key, blob] of Object.entries(dataInfo.parts)) {
|
|
@@ -4472,7 +4472,7 @@
|
|
|
4472
4472
|
parts: newParts,
|
|
4473
4473
|
};
|
|
4474
4474
|
}
|
|
4475
|
-
case
|
|
4475
|
+
case "BinaryPartitioned": {
|
|
4476
4476
|
// Map each index and values blob in parts
|
|
4477
4477
|
const newParts = {};
|
|
4478
4478
|
for (const [key, chunk] of Object.entries(dataInfo.parts)) {
|
|
@@ -4486,7 +4486,7 @@
|
|
|
4486
4486
|
parts: newParts,
|
|
4487
4487
|
};
|
|
4488
4488
|
}
|
|
4489
|
-
case
|
|
4489
|
+
case "ParquetPartitioned": {
|
|
4490
4490
|
// Map each blob in parts
|
|
4491
4491
|
const newParts = {};
|
|
4492
4492
|
for (const [key, blob] of Object.entries(dataInfo.parts)) {
|
|
@@ -4506,15 +4506,15 @@
|
|
|
4506
4506
|
*/
|
|
4507
4507
|
function visitDataInfo(dataInfo, cb) {
|
|
4508
4508
|
switch (dataInfo.type) {
|
|
4509
|
-
case
|
|
4509
|
+
case "Json":
|
|
4510
4510
|
// Json type doesn't contain blobs, so return as is
|
|
4511
4511
|
break;
|
|
4512
|
-
case
|
|
4512
|
+
case "JsonPartitioned": {
|
|
4513
4513
|
// Visit each blob in parts
|
|
4514
4514
|
Object.values(dataInfo.parts).forEach(cb);
|
|
4515
4515
|
break;
|
|
4516
4516
|
}
|
|
4517
|
-
case
|
|
4517
|
+
case "BinaryPartitioned": {
|
|
4518
4518
|
// Visit each index and values blob in parts
|
|
4519
4519
|
Object.values(dataInfo.parts).forEach((chunk) => {
|
|
4520
4520
|
cb(chunk.index);
|
|
@@ -4522,7 +4522,7 @@
|
|
|
4522
4522
|
});
|
|
4523
4523
|
break;
|
|
4524
4524
|
}
|
|
4525
|
-
case
|
|
4525
|
+
case "ParquetPartitioned": {
|
|
4526
4526
|
// Visit each blob in parts
|
|
4527
4527
|
Object.values(dataInfo.parts).forEach(cb);
|
|
4528
4528
|
break;
|
|
@@ -4536,22 +4536,20 @@
|
|
|
4536
4536
|
* @returns True if the value is a valid DataInfoEntries, false otherwise
|
|
4537
4537
|
*/
|
|
4538
4538
|
function isDataInfoEntries(value) {
|
|
4539
|
-
if (!value || typeof value !==
|
|
4539
|
+
if (!value || typeof value !== "object") {
|
|
4540
4540
|
return false;
|
|
4541
4541
|
}
|
|
4542
4542
|
const data = value;
|
|
4543
|
-
if (!(
|
|
4543
|
+
if (!("type" in data)) {
|
|
4544
4544
|
return false;
|
|
4545
4545
|
}
|
|
4546
4546
|
switch (data.type) {
|
|
4547
|
-
case
|
|
4548
|
-
return
|
|
4549
|
-
|
|
4550
|
-
case
|
|
4551
|
-
case
|
|
4552
|
-
|
|
4553
|
-
return (typeof data.partitionKeyLength === 'number'
|
|
4554
|
-
&& Array.isArray(data.parts));
|
|
4547
|
+
case "Json":
|
|
4548
|
+
return typeof data.keyLength === "number" && Array.isArray(data.data);
|
|
4549
|
+
case "JsonPartitioned":
|
|
4550
|
+
case "BinaryPartitioned":
|
|
4551
|
+
case "ParquetPartitioned":
|
|
4552
|
+
return typeof data.partitionKeyLength === "number" && Array.isArray(data.parts);
|
|
4555
4553
|
default:
|
|
4556
4554
|
return false;
|
|
4557
4555
|
}
|
|
@@ -4567,9 +4565,9 @@
|
|
|
4567
4565
|
if (!isDataInfoEntries(value))
|
|
4568
4566
|
return false;
|
|
4569
4567
|
switch (value.type) {
|
|
4570
|
-
case
|
|
4571
|
-
case
|
|
4572
|
-
case
|
|
4568
|
+
case "JsonPartitioned":
|
|
4569
|
+
case "BinaryPartitioned":
|
|
4570
|
+
case "ParquetPartitioned":
|
|
4573
4571
|
return true;
|
|
4574
4572
|
default:
|
|
4575
4573
|
return false;
|
|
@@ -4583,38 +4581,42 @@
|
|
|
4583
4581
|
*/
|
|
4584
4582
|
function dataInfoToEntries(dataInfo) {
|
|
4585
4583
|
switch (dataInfo.type) {
|
|
4586
|
-
case
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4584
|
+
case "Json":
|
|
4585
|
+
return {
|
|
4586
|
+
type: "Json",
|
|
4587
|
+
keyLength: dataInfo.keyLength,
|
|
4588
|
+
data: Object.entries(dataInfo.data).map(([keyStr, value]) => {
|
|
4589
|
+
const key = JSON.parse(keyStr);
|
|
4590
|
+
return { key, value };
|
|
4591
|
+
}),
|
|
4592
|
+
};
|
|
4593
|
+
case "JsonPartitioned":
|
|
4594
|
+
return {
|
|
4595
|
+
type: "JsonPartitioned",
|
|
4596
|
+
partitionKeyLength: dataInfo.partitionKeyLength,
|
|
4597
|
+
parts: Object.entries(dataInfo.parts).map(([keyStr, blob]) => {
|
|
4598
|
+
const key = JSON.parse(keyStr);
|
|
4599
|
+
return { key, value: blob };
|
|
4600
|
+
}),
|
|
4601
|
+
};
|
|
4602
|
+
case "BinaryPartitioned":
|
|
4603
|
+
return {
|
|
4604
|
+
type: "BinaryPartitioned",
|
|
4605
|
+
partitionKeyLength: dataInfo.partitionKeyLength,
|
|
4606
|
+
parts: Object.entries(dataInfo.parts).map(([keyStr, chunk]) => {
|
|
4607
|
+
const key = JSON.parse(keyStr);
|
|
4608
|
+
return { key, value: chunk };
|
|
4609
|
+
}),
|
|
4610
|
+
};
|
|
4611
|
+
case "ParquetPartitioned":
|
|
4612
|
+
return {
|
|
4613
|
+
type: "ParquetPartitioned",
|
|
4614
|
+
partitionKeyLength: dataInfo.partitionKeyLength,
|
|
4615
|
+
parts: Object.entries(dataInfo.parts).map(([keyStr, blob]) => {
|
|
4616
|
+
const key = JSON.parse(keyStr);
|
|
4617
|
+
return { key, value: blob };
|
|
4618
|
+
}),
|
|
4619
|
+
};
|
|
4618
4620
|
default:
|
|
4619
4621
|
assertNever(dataInfo);
|
|
4620
4622
|
}
|
|
@@ -4627,26 +4629,30 @@
|
|
|
4627
4629
|
*/
|
|
4628
4630
|
function entriesToDataInfo(dataInfoEntries) {
|
|
4629
4631
|
switch (dataInfoEntries.type) {
|
|
4630
|
-
case
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4632
|
+
case "Json":
|
|
4633
|
+
return {
|
|
4634
|
+
type: "Json",
|
|
4635
|
+
keyLength: dataInfoEntries.keyLength,
|
|
4636
|
+
data: Object.fromEntries(dataInfoEntries.data.map(({ key, value }) => [JSON.stringify(key), value])),
|
|
4637
|
+
};
|
|
4638
|
+
case "JsonPartitioned":
|
|
4639
|
+
return {
|
|
4640
|
+
type: "JsonPartitioned",
|
|
4641
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength,
|
|
4642
|
+
parts: Object.fromEntries(dataInfoEntries.parts.map(({ key, value }) => [JSON.stringify(key), value])),
|
|
4643
|
+
};
|
|
4644
|
+
case "BinaryPartitioned":
|
|
4645
|
+
return {
|
|
4646
|
+
type: "BinaryPartitioned",
|
|
4647
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength,
|
|
4648
|
+
parts: Object.fromEntries(dataInfoEntries.parts.map(({ key, value }) => [JSON.stringify(key), value])),
|
|
4649
|
+
};
|
|
4650
|
+
case "ParquetPartitioned":
|
|
4651
|
+
return {
|
|
4652
|
+
type: "ParquetPartitioned",
|
|
4653
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength,
|
|
4654
|
+
parts: Object.fromEntries(dataInfoEntries.parts.map(({ key, value }) => [JSON.stringify(key), value])),
|
|
4655
|
+
};
|
|
4650
4656
|
default:
|
|
4651
4657
|
assertNever(dataInfoEntries);
|
|
4652
4658
|
}
|
|
@@ -4656,10 +4662,10 @@
|
|
|
4656
4662
|
* Just for convenience, usually it is an Error with name 'AbortError'
|
|
4657
4663
|
*/
|
|
4658
4664
|
function stringifyValue(value) {
|
|
4659
|
-
if (typeof value ===
|
|
4665
|
+
if (typeof value === "string") {
|
|
4660
4666
|
return `String value was thrown: ${value}`;
|
|
4661
4667
|
}
|
|
4662
|
-
if (value && typeof value ===
|
|
4668
|
+
if (value && typeof value === "object") {
|
|
4663
4669
|
try {
|
|
4664
4670
|
return `Plain object was thrown: ${JSON.stringify(value)}`;
|
|
4665
4671
|
}
|
|
@@ -4743,13 +4749,13 @@
|
|
|
4743
4749
|
}
|
|
4744
4750
|
|
|
4745
4751
|
const ValueType = {
|
|
4746
|
-
Int:
|
|
4747
|
-
Float:
|
|
4748
|
-
String:
|
|
4752
|
+
Int: "Int",
|
|
4753
|
+
Float: "Float",
|
|
4754
|
+
String: "String"};
|
|
4749
4755
|
function readMetadata(metadata, key) {
|
|
4750
4756
|
return metadata?.[key];
|
|
4751
4757
|
}
|
|
4752
|
-
function readMetadataJsonOrThrow(metadata, metadataJson, key, methodNameInError =
|
|
4758
|
+
function readMetadataJsonOrThrow(metadata, metadataJson, key, methodNameInError = "readMetadataJsonOrThrow") {
|
|
4753
4759
|
const json = readMetadata(metadata, key);
|
|
4754
4760
|
if (json === undefined)
|
|
4755
4761
|
return undefined;
|
|
@@ -4759,10 +4765,10 @@
|
|
|
4759
4765
|
return schema.parse(value);
|
|
4760
4766
|
}
|
|
4761
4767
|
catch (error) {
|
|
4762
|
-
throw new Error(`${methodNameInError} failed, `
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4768
|
+
throw new Error(`${methodNameInError} failed, ` +
|
|
4769
|
+
`key: ${String(key)}, ` +
|
|
4770
|
+
`value: ${json}, ` +
|
|
4771
|
+
`error: ${ensureError(error)}`);
|
|
4766
4772
|
}
|
|
4767
4773
|
}
|
|
4768
4774
|
function readMetadataJson(metadata, metadataJson, key) {
|
|
@@ -4775,47 +4781,47 @@
|
|
|
4775
4781
|
}
|
|
4776
4782
|
/// Well-known annotations
|
|
4777
4783
|
const Annotation = {
|
|
4778
|
-
Description:
|
|
4779
|
-
DiscreteValues:
|
|
4784
|
+
Description: "pl7.app/description",
|
|
4785
|
+
DiscreteValues: "pl7.app/discreteValues",
|
|
4780
4786
|
Graph: {
|
|
4781
4787
|
Axis: {
|
|
4782
|
-
HighCardinality:
|
|
4783
|
-
LowerLimit:
|
|
4784
|
-
SymmetricRange:
|
|
4785
|
-
UpperLimit:
|
|
4788
|
+
HighCardinality: "pl7.app/graph/axis/highCardinality",
|
|
4789
|
+
LowerLimit: "pl7.app/graph/axis/lowerLimit",
|
|
4790
|
+
SymmetricRange: "pl7.app/graph/axis/symmetricRange",
|
|
4791
|
+
UpperLimit: "pl7.app/graph/axis/upperLimit",
|
|
4786
4792
|
},
|
|
4787
|
-
IsDenseAxis:
|
|
4788
|
-
IsVirtual:
|
|
4789
|
-
Palette:
|
|
4790
|
-
Thresholds:
|
|
4791
|
-
TreatAbsentValuesAs:
|
|
4793
|
+
IsDenseAxis: "pl7.app/graph/isDenseAxis",
|
|
4794
|
+
IsVirtual: "pl7.app/graph/isVirtual",
|
|
4795
|
+
Palette: "pl7.app/graph/palette",
|
|
4796
|
+
Thresholds: "pl7.app/graph/thresholds",
|
|
4797
|
+
TreatAbsentValuesAs: "pl7.app/graph/treatAbsentValuesAs",
|
|
4792
4798
|
},
|
|
4793
|
-
HideDataFromUi:
|
|
4794
|
-
HideDataFromGraphs:
|
|
4795
|
-
IsDiscreteFilter:
|
|
4796
|
-
IsLinkerColumn:
|
|
4797
|
-
IsSubset:
|
|
4798
|
-
Label:
|
|
4799
|
-
Max:
|
|
4800
|
-
Min:
|
|
4801
|
-
MultipliesBy:
|
|
4802
|
-
Parents:
|
|
4799
|
+
HideDataFromUi: "pl7.app/hideDataFromUi",
|
|
4800
|
+
HideDataFromGraphs: "pl7.app/hideDataFromGraphs",
|
|
4801
|
+
IsDiscreteFilter: "pl7.app/isDiscreteFilter",
|
|
4802
|
+
IsLinkerColumn: "pl7.app/isLinkerColumn",
|
|
4803
|
+
IsSubset: "pl7.app/isSubset",
|
|
4804
|
+
Label: "pl7.app/label",
|
|
4805
|
+
Max: "pl7.app/max",
|
|
4806
|
+
Min: "pl7.app/min",
|
|
4807
|
+
MultipliesBy: "pl7.app/multipliesBy",
|
|
4808
|
+
Parents: "pl7.app/parents",
|
|
4803
4809
|
Sequence: {
|
|
4804
4810
|
Annotation: {
|
|
4805
|
-
Mapping:
|
|
4811
|
+
Mapping: "pl7.app/sequence/annotation/mapping",
|
|
4806
4812
|
},
|
|
4807
|
-
IsAnnotation:
|
|
4813
|
+
IsAnnotation: "pl7.app/sequence/isAnnotation",
|
|
4808
4814
|
},
|
|
4809
4815
|
Table: {
|
|
4810
|
-
OrderPriority:
|
|
4811
|
-
Visibility:
|
|
4816
|
+
OrderPriority: "pl7.app/table/orderPriority",
|
|
4817
|
+
Visibility: "pl7.app/table/visibility",
|
|
4812
4818
|
},
|
|
4813
|
-
Trace:
|
|
4819
|
+
Trace: "pl7.app/trace",
|
|
4814
4820
|
VDJ: {
|
|
4815
|
-
IsAssemblingFeature:
|
|
4821
|
+
IsAssemblingFeature: "pl7.app/vdj/isAssemblingFeature",
|
|
4816
4822
|
},
|
|
4817
4823
|
};
|
|
4818
|
-
const ValueTypeSchema = z.enum([
|
|
4824
|
+
const ValueTypeSchema = z.enum(["Int", "Long", "Float", "Double", "String"]);
|
|
4819
4825
|
const AnnotationJson = {
|
|
4820
4826
|
[Annotation.DiscreteValues]: z.array(z.string()).or(z.array(z.number())),
|
|
4821
4827
|
[Annotation.Graph.Axis.HighCardinality]: z.boolean(),
|
|
@@ -4963,16 +4969,21 @@
|
|
|
4963
4969
|
});
|
|
4964
4970
|
axes.forEach((axis, idx) => {
|
|
4965
4971
|
const modifiedAxis = modifiedAxes[idx];
|
|
4966
|
-
if (axis.parentAxes) {
|
|
4972
|
+
if (axis.parentAxes) {
|
|
4973
|
+
// if we have parents by indexes then take from the list
|
|
4967
4974
|
modifiedAxis.parentAxesSpec = axis.parentAxes.map((idx) => modifiedAxes[idx]);
|
|
4968
4975
|
}
|
|
4969
|
-
else {
|
|
4976
|
+
else {
|
|
4977
|
+
// else try to parse from annotation name
|
|
4970
4978
|
const parents = parseParentsFromAnnotations(axis).map((name) => modifiedAxes.find((axis) => axis.name === name));
|
|
4971
|
-
modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined)
|
|
4979
|
+
modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined)
|
|
4980
|
+
? []
|
|
4981
|
+
: parents;
|
|
4972
4982
|
delete modifiedAxis.annotations?.[Annotation.Parents];
|
|
4973
4983
|
}
|
|
4974
4984
|
});
|
|
4975
|
-
if (modifiedAxes.some(hasCycleOfParents)) {
|
|
4985
|
+
if (modifiedAxes.some(hasCycleOfParents)) {
|
|
4986
|
+
// Axes list is broken
|
|
4976
4987
|
modifiedAxes.forEach((axis) => {
|
|
4977
4988
|
axis.parentAxesSpec = [];
|
|
4978
4989
|
});
|
|
@@ -4986,7 +4997,7 @@
|
|
|
4986
4997
|
}
|
|
4987
4998
|
/// Well-known column names
|
|
4988
4999
|
const PColumnName = {
|
|
4989
|
-
Label:
|
|
5000
|
+
Label: "pl7.app/label"};
|
|
4990
5001
|
function isLabelColumn(column) {
|
|
4991
5002
|
return column.axesSpec.length === 1 && column.name === PColumnName.Label;
|
|
4992
5003
|
}
|
|
@@ -5036,36 +5047,36 @@
|
|
|
5036
5047
|
}
|
|
5037
5048
|
function mapJoinEntry(entry, cb) {
|
|
5038
5049
|
switch (entry.type) {
|
|
5039
|
-
case
|
|
5050
|
+
case "column":
|
|
5040
5051
|
return {
|
|
5041
|
-
type:
|
|
5052
|
+
type: "column",
|
|
5042
5053
|
column: cb(entry.column),
|
|
5043
5054
|
};
|
|
5044
|
-
case
|
|
5055
|
+
case "slicedColumn":
|
|
5045
5056
|
return {
|
|
5046
|
-
type:
|
|
5057
|
+
type: "slicedColumn",
|
|
5047
5058
|
column: cb(entry.column),
|
|
5048
5059
|
newId: entry.newId,
|
|
5049
5060
|
axisFilters: entry.axisFilters,
|
|
5050
5061
|
};
|
|
5051
|
-
case
|
|
5062
|
+
case "artificialColumn":
|
|
5052
5063
|
return {
|
|
5053
|
-
type:
|
|
5064
|
+
type: "artificialColumn",
|
|
5054
5065
|
column: cb(entry.column),
|
|
5055
5066
|
newId: entry.newId,
|
|
5056
5067
|
axesIndices: entry.axesIndices,
|
|
5057
5068
|
};
|
|
5058
|
-
case
|
|
5069
|
+
case "inlineColumn":
|
|
5059
5070
|
return entry;
|
|
5060
|
-
case
|
|
5061
|
-
case
|
|
5071
|
+
case "inner":
|
|
5072
|
+
case "full":
|
|
5062
5073
|
return {
|
|
5063
5074
|
type: entry.type,
|
|
5064
5075
|
entries: entry.entries.map((col) => mapJoinEntry(col, cb)),
|
|
5065
5076
|
};
|
|
5066
|
-
case
|
|
5077
|
+
case "outer":
|
|
5067
5078
|
return {
|
|
5068
|
-
type:
|
|
5079
|
+
type: "outer",
|
|
5069
5080
|
primary: mapJoinEntry(entry.primary, cb),
|
|
5070
5081
|
secondary: entry.secondary.map((col) => mapJoinEntry(col, cb)),
|
|
5071
5082
|
};
|
|
@@ -5187,7 +5198,7 @@
|
|
|
5187
5198
|
for (const filter of axisFilters) {
|
|
5188
5199
|
const [axisIdOrIndex, value] = filter;
|
|
5189
5200
|
// If it's already a numeric index, validate it
|
|
5190
|
-
if (typeof axisIdOrIndex ===
|
|
5201
|
+
if (typeof axisIdOrIndex === "number") {
|
|
5191
5202
|
if (axisIdOrIndex < 0 || axisIdOrIndex >= spec.axesSpec.length) {
|
|
5192
5203
|
throw new Error(`Axis index ${axisIdOrIndex} is out of bounds (0-${spec.axesSpec.length - 1})`);
|
|
5193
5204
|
}
|
|
@@ -5242,7 +5253,7 @@
|
|
|
5242
5253
|
if (result.domain) {
|
|
5243
5254
|
const resolvedDomain = {};
|
|
5244
5255
|
for (const [key, value] of Object.entries(result.domain)) {
|
|
5245
|
-
if (typeof value ===
|
|
5256
|
+
if (typeof value === "string") {
|
|
5246
5257
|
resolvedDomain[key] = value;
|
|
5247
5258
|
}
|
|
5248
5259
|
else {
|
|
@@ -5275,13 +5286,13 @@
|
|
|
5275
5286
|
const anchorSpec = anchors[anchorId];
|
|
5276
5287
|
if (!anchorSpec)
|
|
5277
5288
|
throw new Error(`Anchor "${anchorId}" not found for axis reference`);
|
|
5278
|
-
if (
|
|
5289
|
+
if ("idx" in axisRef) {
|
|
5279
5290
|
// AnchorAxisRefByIdx
|
|
5280
5291
|
if (axisRef.idx < 0 || axisRef.idx >= anchorSpec.axesSpec.length)
|
|
5281
5292
|
throw new Error(`Axis index ${axisRef.idx} out of bounds for anchor "${anchorId}"`);
|
|
5282
5293
|
return anchorSpec.axesSpec[axisRef.idx];
|
|
5283
5294
|
}
|
|
5284
|
-
else if (
|
|
5295
|
+
else if ("name" in axisRef) {
|
|
5285
5296
|
// AnchorAxisRefByName
|
|
5286
5297
|
const matches = anchorSpec.axesSpec.filter((axis) => axis.name === axisRef.name);
|
|
5287
5298
|
if (matches.length > 1)
|
|
@@ -5290,7 +5301,7 @@
|
|
|
5290
5301
|
throw new Error(`Axis with name "${axisRef.name}" not found in anchor "${anchorId}"`);
|
|
5291
5302
|
return matches[0];
|
|
5292
5303
|
}
|
|
5293
|
-
else if (
|
|
5304
|
+
else if ("id" in axisRef) {
|
|
5294
5305
|
// AnchorAxisRefByMatcher
|
|
5295
5306
|
const matches = anchorSpec.axesSpec.filter((axis) => matchAxisId(axisRef.id, getAxisId(axis)));
|
|
5296
5307
|
if (matches.length > 1)
|
|
@@ -5305,11 +5316,11 @@
|
|
|
5305
5316
|
* Type guard to check if a value is an anchored axis reference
|
|
5306
5317
|
*/
|
|
5307
5318
|
function isAnchorAxisRef(value) {
|
|
5308
|
-
return typeof value ===
|
|
5319
|
+
return typeof value === "object" && "anchor" in value;
|
|
5309
5320
|
}
|
|
5310
5321
|
|
|
5311
5322
|
function isPColumnSpec(spec) {
|
|
5312
|
-
return spec.kind ===
|
|
5323
|
+
return spec.kind === "PColumn";
|
|
5313
5324
|
}
|
|
5314
5325
|
function isPColumn(obj) {
|
|
5315
5326
|
return isPColumnSpec(obj.spec);
|
|
@@ -5324,30 +5335,30 @@
|
|
|
5324
5335
|
? undefined
|
|
5325
5336
|
: {
|
|
5326
5337
|
...pObj,
|
|
5327
|
-
data: cb(typeof pObj.data ===
|
|
5338
|
+
data: cb(typeof pObj.data === "function" ? pObj.data() : pObj.data),
|
|
5328
5339
|
};
|
|
5329
5340
|
}
|
|
5330
5341
|
function extractAllColumns(entry) {
|
|
5331
5342
|
const columns = new Map();
|
|
5332
5343
|
const addAllColumns = (entry) => {
|
|
5333
5344
|
switch (entry.type) {
|
|
5334
|
-
case
|
|
5345
|
+
case "column":
|
|
5335
5346
|
columns.set(entry.column.id, entry.column);
|
|
5336
5347
|
return;
|
|
5337
|
-
case
|
|
5348
|
+
case "slicedColumn":
|
|
5338
5349
|
columns.set(entry.column.id, entry.column);
|
|
5339
5350
|
return;
|
|
5340
|
-
case
|
|
5351
|
+
case "artificialColumn":
|
|
5341
5352
|
columns.set(entry.column.id, entry.column);
|
|
5342
5353
|
return;
|
|
5343
|
-
case
|
|
5354
|
+
case "inlineColumn":
|
|
5344
5355
|
return;
|
|
5345
|
-
case
|
|
5346
|
-
case
|
|
5356
|
+
case "full":
|
|
5357
|
+
case "inner":
|
|
5347
5358
|
for (const e of entry.entries)
|
|
5348
5359
|
addAllColumns(e);
|
|
5349
5360
|
return;
|
|
5350
|
-
case
|
|
5361
|
+
case "outer":
|
|
5351
5362
|
addAllColumns(entry.primary);
|
|
5352
5363
|
for (const e of entry.secondary)
|
|
5353
5364
|
addAllColumns(e);
|
|
@@ -5604,7 +5615,9 @@
|
|
|
5604
5615
|
.flatMap((targetKey) => {
|
|
5605
5616
|
const linkers = startKeys
|
|
5606
5617
|
.map((startKey) => this.searchLinkerPath(startKey, targetKey))
|
|
5607
|
-
.reduce((shortestPath, path) => (shortestPath.length && shortestPath.length < path.length) || !path.length
|
|
5618
|
+
.reduce((shortestPath, path) => (shortestPath.length && shortestPath.length < path.length) || !path.length
|
|
5619
|
+
? shortestPath
|
|
5620
|
+
: path, [])
|
|
5608
5621
|
.map((linker) => [linker.columnId, linker]);
|
|
5609
5622
|
if (!linkers.length && throwWhenNoLinkExists) {
|
|
5610
5623
|
throw Error(`Unable to find linker column for ${targetKey}`);
|
|
@@ -5614,7 +5627,8 @@
|
|
|
5614
5627
|
}
|
|
5615
5628
|
/** Get list of axisSpecs from keys of linker columns map */
|
|
5616
5629
|
getAxesListFromKeysList(keys) {
|
|
5617
|
-
return Array.from(new Map(keys
|
|
5630
|
+
return Array.from(new Map(keys
|
|
5631
|
+
.flatMap((key) => this.data.get(key)?.keyAxesSpec ?? [])
|
|
5618
5632
|
.map((axis) => [canonicalizeJson(getAxisId(axis)), axis])).values());
|
|
5619
5633
|
}
|
|
5620
5634
|
/** Get axes of target axes that are impossible to be linked to source axes with current linker map */
|
|
@@ -5627,7 +5641,10 @@
|
|
|
5627
5641
|
const targetKey = targetKeys[idx];
|
|
5628
5642
|
return !startKeys.some((startKey) => this.searchLinkerPath(startKey, targetKey).length);
|
|
5629
5643
|
})
|
|
5630
|
-
.flatMap((axis) => getArrayFromAxisTree(getAxesTree(axis)).map((axis) => [
|
|
5644
|
+
.flatMap((axis) => getArrayFromAxisTree(getAxesTree(axis)).map((axis) => [
|
|
5645
|
+
canonicalizeJson(getAxisId(axis)),
|
|
5646
|
+
axis,
|
|
5647
|
+
]))).values());
|
|
5631
5648
|
return axes;
|
|
5632
5649
|
}
|
|
5633
5650
|
/** Get all axes that can be connected to sourceAxes by linkers */
|
|
@@ -5658,8 +5675,10 @@
|
|
|
5658
5675
|
There are no order inside every group. */
|
|
5659
5676
|
static getAxesGroups(axesSpec) {
|
|
5660
5677
|
switch (axesSpec.length) {
|
|
5661
|
-
case 0:
|
|
5662
|
-
|
|
5678
|
+
case 0:
|
|
5679
|
+
return [];
|
|
5680
|
+
case 1:
|
|
5681
|
+
return [[axesSpec[0]]];
|
|
5663
5682
|
}
|
|
5664
5683
|
const axisKeys = axesSpec.map((spec) => canonicalizeJson(getAxisId(spec)));
|
|
5665
5684
|
const axisParentsIdxs = axesSpec.map((spec) => new Set(spec.parentAxesSpec
|
|
@@ -5715,24 +5734,24 @@
|
|
|
5715
5734
|
.string()
|
|
5716
5735
|
.length(PlIdLength)
|
|
5717
5736
|
.regex(/[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]/) // RFC4648
|
|
5718
|
-
.brand(
|
|
5737
|
+
.brand("PlId");
|
|
5719
5738
|
|
|
5720
5739
|
z
|
|
5721
5740
|
.object({
|
|
5722
5741
|
__isRef: z
|
|
5723
5742
|
.literal(true)
|
|
5724
|
-
.describe(
|
|
5725
|
-
blockId: z.string()
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
.
|
|
5729
|
-
|
|
5730
|
-
.describe(
|
|
5731
|
-
|
|
5743
|
+
.describe("Crucial marker for the block dependency tree reconstruction"),
|
|
5744
|
+
blockId: z.string().describe("Upstream block id"),
|
|
5745
|
+
name: z.string().describe("Name of the output provided to the upstream block's output context"),
|
|
5746
|
+
requireEnrichments: z
|
|
5747
|
+
.literal(true)
|
|
5748
|
+
.optional()
|
|
5749
|
+
.describe("True if current block that stores this reference in its args, may need enrichments " +
|
|
5750
|
+
"for the references value originating from the blocks in between current and referenced block"),
|
|
5732
5751
|
})
|
|
5733
|
-
.describe(
|
|
5734
|
-
|
|
5735
|
-
|
|
5752
|
+
.describe("Universal reference type, allowing to set block connections. It is crucial that " +
|
|
5753
|
+
"{@link __isRef} is present and equal to true, internal logic relies on this marker " +
|
|
5754
|
+
"to build block dependency trees.")
|
|
5736
5755
|
.readonly();
|
|
5737
5756
|
/**
|
|
5738
5757
|
* Type guard to check if a value is a PlRef.
|
|
@@ -5741,12 +5760,12 @@
|
|
|
5741
5760
|
* @returns True if the value is a PlRef, false otherwise.
|
|
5742
5761
|
*/
|
|
5743
5762
|
function isPlRef(value) {
|
|
5744
|
-
return (typeof value ===
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5763
|
+
return (typeof value === "object" &&
|
|
5764
|
+
value !== null &&
|
|
5765
|
+
"__isRef" in value &&
|
|
5766
|
+
value.__isRef === true &&
|
|
5767
|
+
"blockId" in value &&
|
|
5768
|
+
"name" in value);
|
|
5750
5769
|
}
|
|
5751
5770
|
/**
|
|
5752
5771
|
* Creates a new PlRef based on an existing one, explicitly setting (default) or removing the
|
|
@@ -5815,22 +5834,22 @@
|
|
|
5815
5834
|
}
|
|
5816
5835
|
resolve(...steps) {
|
|
5817
5836
|
const transformedSteps = steps.map((s) => ({
|
|
5818
|
-
assertFieldType:
|
|
5819
|
-
...(typeof s ===
|
|
5837
|
+
assertFieldType: "Input",
|
|
5838
|
+
...(typeof s === "string" ? { field: s } : s),
|
|
5820
5839
|
}));
|
|
5821
5840
|
return this.resolveWithCommon({}, ...transformedSteps);
|
|
5822
5841
|
}
|
|
5823
5842
|
resolveOutput(...steps) {
|
|
5824
5843
|
const transformedSteps = steps.map((s) => ({
|
|
5825
|
-
assertFieldType:
|
|
5826
|
-
...(typeof s ===
|
|
5844
|
+
assertFieldType: "Output",
|
|
5845
|
+
...(typeof s === "string" ? { field: s } : s),
|
|
5827
5846
|
}));
|
|
5828
5847
|
return this.resolveWithCommon({}, ...transformedSteps);
|
|
5829
5848
|
}
|
|
5830
5849
|
resolveInput(...steps) {
|
|
5831
5850
|
const transformedSteps = steps.map((s) => ({
|
|
5832
|
-
assertFieldType:
|
|
5833
|
-
...(typeof s ===
|
|
5851
|
+
assertFieldType: "Input",
|
|
5852
|
+
...(typeof s === "string" ? { field: s } : s),
|
|
5834
5853
|
}));
|
|
5835
5854
|
return this.resolveWithCommon({}, ...transformedSteps);
|
|
5836
5855
|
}
|
|
@@ -5840,7 +5859,7 @@
|
|
|
5840
5859
|
resolveWithCommon(commonOptions, ...steps) {
|
|
5841
5860
|
const resolvePath = [
|
|
5842
5861
|
...this.resolvePath,
|
|
5843
|
-
...steps.map((step) => typeof step ===
|
|
5862
|
+
...steps.map((step) => (typeof step === "string" ? step : step.field)),
|
|
5844
5863
|
];
|
|
5845
5864
|
return ifDef(getCfgRenderCtx().resolveWithCommon(this.handle, commonOptions, ...steps), (accessor) => new TreeNodeAccessor(accessor, resolvePath));
|
|
5846
5865
|
}
|
|
@@ -5860,7 +5879,7 @@
|
|
|
5860
5879
|
return getCfgRenderCtx().getIsFinal(this.handle);
|
|
5861
5880
|
}
|
|
5862
5881
|
getError() {
|
|
5863
|
-
const resolvePath = [...this.resolvePath,
|
|
5882
|
+
const resolvePath = [...this.resolvePath, "error"];
|
|
5864
5883
|
return ifDef(getCfgRenderCtx().getError(this.handle), (accsessor) => new TreeNodeAccessor(accsessor, resolvePath));
|
|
5865
5884
|
}
|
|
5866
5885
|
listInputFields() {
|
|
@@ -5881,7 +5900,7 @@
|
|
|
5881
5900
|
getKeyValueAsJson(key) {
|
|
5882
5901
|
const content = this.getKeyValueAsString(key);
|
|
5883
5902
|
if (content == undefined)
|
|
5884
|
-
throw new Error(
|
|
5903
|
+
throw new Error("Resource has no content.");
|
|
5885
5904
|
return JSON.parse(content);
|
|
5886
5905
|
}
|
|
5887
5906
|
getDataBase64() {
|
|
@@ -5893,13 +5912,13 @@
|
|
|
5893
5912
|
getDataAsJson() {
|
|
5894
5913
|
const content = this.getDataAsString();
|
|
5895
5914
|
if (content == undefined)
|
|
5896
|
-
throw new Error(
|
|
5915
|
+
throw new Error("Resource has no content.");
|
|
5897
5916
|
return JSON.parse(content);
|
|
5898
5917
|
}
|
|
5899
5918
|
/**
|
|
5900
5919
|
*
|
|
5901
5920
|
*/
|
|
5902
|
-
getPColumns(errorOnUnknownField = false, prefix =
|
|
5921
|
+
getPColumns(errorOnUnknownField = false, prefix = "") {
|
|
5903
5922
|
const result = this.parsePObjectCollection(errorOnUnknownField, prefix);
|
|
5904
5923
|
if (result === undefined)
|
|
5905
5924
|
return undefined;
|
|
@@ -5913,7 +5932,7 @@
|
|
|
5913
5932
|
/**
|
|
5914
5933
|
*
|
|
5915
5934
|
*/
|
|
5916
|
-
parsePObjectCollection(errorOnUnknownField = false, prefix =
|
|
5935
|
+
parsePObjectCollection(errorOnUnknownField = false, prefix = "") {
|
|
5917
5936
|
const pObjects = getCfgRenderCtx().parsePObjectCollection(this.handle, errorOnUnknownField, prefix, ...this.resolvePath);
|
|
5918
5937
|
if (pObjects === undefined)
|
|
5919
5938
|
return undefined;
|
|
@@ -5990,33 +6009,33 @@
|
|
|
5990
6009
|
getLogHandle() {
|
|
5991
6010
|
return new FutureRef(getCfgRenderCtx().getLogHandle(this.handle));
|
|
5992
6011
|
}
|
|
5993
|
-
allFieldsResolved(fieldType =
|
|
6012
|
+
allFieldsResolved(fieldType = "Input") {
|
|
5994
6013
|
switch (fieldType) {
|
|
5995
|
-
case
|
|
5996
|
-
return (this.getInputsLocked()
|
|
5997
|
-
|
|
5998
|
-
case
|
|
5999
|
-
return (this.getOutputsLocked()
|
|
6000
|
-
|
|
6014
|
+
case "Input":
|
|
6015
|
+
return (this.getInputsLocked() &&
|
|
6016
|
+
this.listInputFields().every((field) => this.resolve({ field, assertFieldType: "Input" }) !== undefined));
|
|
6017
|
+
case "Output":
|
|
6018
|
+
return (this.getOutputsLocked() &&
|
|
6019
|
+
this.listOutputFields().every((field) => this.resolve({ field, assertFieldType: "Output" }) !== undefined));
|
|
6001
6020
|
}
|
|
6002
6021
|
}
|
|
6003
6022
|
mapFields(_mapping, _ops) {
|
|
6004
6023
|
const { fieldType, requireLocked, skipUnresolved } = {
|
|
6005
|
-
fieldType:
|
|
6024
|
+
fieldType: "Input",
|
|
6006
6025
|
requireLocked: true,
|
|
6007
6026
|
skipUnresolved: false,
|
|
6008
6027
|
..._ops,
|
|
6009
6028
|
};
|
|
6010
6029
|
const mapping = _mapping;
|
|
6011
6030
|
if (requireLocked) {
|
|
6012
|
-
if (fieldType ===
|
|
6031
|
+
if (fieldType === "Input" && !this.getInputsLocked())
|
|
6013
6032
|
return undefined;
|
|
6014
|
-
if (fieldType ===
|
|
6033
|
+
if (fieldType === "Output" && !this.getOutputsLocked())
|
|
6015
6034
|
return undefined;
|
|
6016
6035
|
}
|
|
6017
|
-
const fieldList = fieldType ===
|
|
6036
|
+
const fieldList = fieldType === "Input"
|
|
6018
6037
|
? this.listInputFields()
|
|
6019
|
-
: fieldType ===
|
|
6038
|
+
: fieldType === "Output"
|
|
6020
6039
|
? this.listOutputFields()
|
|
6021
6040
|
: this.listDynamicFields();
|
|
6022
6041
|
let fieldEntries = fieldList.map((field) => [field, this.resolve({ field, assertFieldType: fieldType })]);
|
|
@@ -6026,8 +6045,8 @@
|
|
|
6026
6045
|
}
|
|
6027
6046
|
}
|
|
6028
6047
|
|
|
6029
|
-
const StagingAccessorName =
|
|
6030
|
-
const MainAccessorName =
|
|
6048
|
+
const StagingAccessorName = "staging";
|
|
6049
|
+
const MainAccessorName = "main";
|
|
6031
6050
|
|
|
6032
6051
|
function filterDataInfoEntries(dataInfoEntries, axisFilters) {
|
|
6033
6052
|
// Sort filters by axis index in descending order to safely remove elements from arrays
|
|
@@ -6035,16 +6054,16 @@
|
|
|
6035
6054
|
// Check for invalid filter axes
|
|
6036
6055
|
const { type } = dataInfoEntries;
|
|
6037
6056
|
switch (type) {
|
|
6038
|
-
case
|
|
6057
|
+
case "Json": {
|
|
6039
6058
|
const { keyLength } = dataInfoEntries;
|
|
6040
6059
|
for (const [axisIdx] of axisFilters)
|
|
6041
6060
|
if (axisIdx >= keyLength)
|
|
6042
6061
|
throw new Error(`Can't filter on non-data axis ${axisIdx}. Must be >= ${keyLength}`);
|
|
6043
6062
|
break;
|
|
6044
6063
|
}
|
|
6045
|
-
case
|
|
6046
|
-
case
|
|
6047
|
-
case
|
|
6064
|
+
case "JsonPartitioned":
|
|
6065
|
+
case "BinaryPartitioned":
|
|
6066
|
+
case "ParquetPartitioned": {
|
|
6048
6067
|
const { partitionKeyLength } = dataInfoEntries;
|
|
6049
6068
|
for (const [axisIdx] of axisFilters)
|
|
6050
6069
|
if (axisIdx >= partitionKeyLength)
|
|
@@ -6069,46 +6088,50 @@
|
|
|
6069
6088
|
return newKey;
|
|
6070
6089
|
};
|
|
6071
6090
|
switch (dataInfoEntries.type) {
|
|
6072
|
-
case
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
.
|
|
6087
|
-
.
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
.
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6091
|
+
case "Json":
|
|
6092
|
+
return {
|
|
6093
|
+
type: "Json",
|
|
6094
|
+
keyLength: dataInfoEntries.keyLength - axisFilters.length,
|
|
6095
|
+
data: dataInfoEntries.data
|
|
6096
|
+
.filter((entry) => keyMatchesFilters(entry.key))
|
|
6097
|
+
.map((entry) => ({
|
|
6098
|
+
key: removeFilteredAxes(entry.key),
|
|
6099
|
+
value: entry.value,
|
|
6100
|
+
})),
|
|
6101
|
+
};
|
|
6102
|
+
case "JsonPartitioned":
|
|
6103
|
+
return {
|
|
6104
|
+
type: "JsonPartitioned",
|
|
6105
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength - axisFilters.length,
|
|
6106
|
+
parts: dataInfoEntries.parts
|
|
6107
|
+
.filter((entry) => keyMatchesFilters(entry.key))
|
|
6108
|
+
.map((entry) => ({
|
|
6109
|
+
key: removeFilteredAxes(entry.key),
|
|
6110
|
+
value: entry.value,
|
|
6111
|
+
})),
|
|
6112
|
+
};
|
|
6113
|
+
case "BinaryPartitioned":
|
|
6114
|
+
return {
|
|
6115
|
+
type: "BinaryPartitioned",
|
|
6116
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength - axisFilters.length,
|
|
6117
|
+
parts: dataInfoEntries.parts
|
|
6118
|
+
.filter((entry) => keyMatchesFilters(entry.key))
|
|
6119
|
+
.map((entry) => ({
|
|
6120
|
+
key: removeFilteredAxes(entry.key),
|
|
6121
|
+
value: entry.value,
|
|
6122
|
+
})),
|
|
6123
|
+
};
|
|
6124
|
+
case "ParquetPartitioned":
|
|
6125
|
+
return {
|
|
6126
|
+
type: "ParquetPartitioned",
|
|
6127
|
+
partitionKeyLength: dataInfoEntries.partitionKeyLength - axisFilters.length,
|
|
6128
|
+
parts: dataInfoEntries.parts
|
|
6129
|
+
.filter((entry) => keyMatchesFilters(entry.key))
|
|
6130
|
+
.map((entry) => ({
|
|
6131
|
+
key: removeFilteredAxes(entry.key),
|
|
6132
|
+
value: entry.value,
|
|
6133
|
+
})),
|
|
6134
|
+
};
|
|
6112
6135
|
}
|
|
6113
6136
|
}
|
|
6114
6137
|
|
|
@@ -6120,11 +6143,11 @@
|
|
|
6120
6143
|
});
|
|
6121
6144
|
const Trace = z.array(TraceEntry);
|
|
6122
6145
|
const DistancePenalty = 0.001;
|
|
6123
|
-
const LabelType =
|
|
6124
|
-
const LabelTypeFull =
|
|
6146
|
+
const LabelType = "__LABEL__";
|
|
6147
|
+
const LabelTypeFull = "__LABEL__@1";
|
|
6125
6148
|
function deriveLabels(values, specExtractor, ops = {}) {
|
|
6126
6149
|
const importances = new Map();
|
|
6127
|
-
const forceTraceElements =
|
|
6150
|
+
const forceTraceElements = ops.forceTraceElements !== undefined && ops.forceTraceElements.length > 0
|
|
6128
6151
|
? new Set(ops.forceTraceElements)
|
|
6129
6152
|
: undefined;
|
|
6130
6153
|
// number of times certain type occurred among all of the
|
|
@@ -6135,7 +6158,7 @@
|
|
|
6135
6158
|
let prefixTrace;
|
|
6136
6159
|
let suffixTrace;
|
|
6137
6160
|
// Check if the result is the new structure or just PObjectSpec
|
|
6138
|
-
if (
|
|
6161
|
+
if ("spec" in extractorResult && typeof extractorResult.spec === "object") {
|
|
6139
6162
|
// It's the new structure { spec, prefixTrace?, suffixTrace? }
|
|
6140
6163
|
spec = extractorResult.spec;
|
|
6141
6164
|
prefixTrace = extractorResult.prefixTrace;
|
|
@@ -6148,11 +6171,7 @@
|
|
|
6148
6171
|
const label = readAnnotation(spec, Annotation.Label);
|
|
6149
6172
|
const traceStr = readAnnotation(spec, Annotation.Trace);
|
|
6150
6173
|
const baseTrace = (traceStr ? Trace.safeParse(parseJson(traceStr)).data : undefined) ?? [];
|
|
6151
|
-
const trace = [
|
|
6152
|
-
...(prefixTrace ?? []),
|
|
6153
|
-
...baseTrace,
|
|
6154
|
-
...(suffixTrace ?? []),
|
|
6155
|
-
];
|
|
6174
|
+
const trace = [...(prefixTrace ?? []), ...baseTrace, ...(suffixTrace ?? [])];
|
|
6156
6175
|
if (label !== undefined) {
|
|
6157
6176
|
const labelEntry = { label, type: LabelType, importance: -2 };
|
|
6158
6177
|
if (ops.addLabelAsSuffix)
|
|
@@ -6188,7 +6207,7 @@
|
|
|
6188
6207
|
// sorting: most important types go first
|
|
6189
6208
|
allTypeRecords.sort(([, i1], [, i2]) => i2 - i1);
|
|
6190
6209
|
for (const [typeName] of allTypeRecords) {
|
|
6191
|
-
if (typeName.endsWith(
|
|
6210
|
+
if (typeName.endsWith("@1") || numberOfRecordsWithType.get(typeName) === values.length)
|
|
6192
6211
|
mainTypes.push(typeName);
|
|
6193
6212
|
else
|
|
6194
6213
|
secondaryTypes.push(typeName);
|
|
@@ -6197,21 +6216,18 @@
|
|
|
6197
6216
|
const result = [];
|
|
6198
6217
|
for (let i = 0; i < enrichedRecords.length; i++) {
|
|
6199
6218
|
const r = enrichedRecords[i];
|
|
6200
|
-
const includedTrace = r.fullTrace
|
|
6201
|
-
.filter((fm) => includedTypes.has(fm.fullType)
|
|
6202
|
-
|| (forceTraceElements && forceTraceElements.has(fm.type)));
|
|
6219
|
+
const includedTrace = r.fullTrace.filter((fm) => includedTypes.has(fm.fullType) || (forceTraceElements && forceTraceElements.has(fm.type)));
|
|
6203
6220
|
if (includedTrace.length === 0) {
|
|
6204
6221
|
if (force)
|
|
6205
6222
|
result.push({
|
|
6206
|
-
label:
|
|
6223
|
+
label: "Unlabeled",
|
|
6207
6224
|
value: r.value,
|
|
6208
6225
|
});
|
|
6209
6226
|
else
|
|
6210
6227
|
return undefined;
|
|
6211
6228
|
}
|
|
6212
|
-
const labelSet = includedTrace
|
|
6213
|
-
|
|
6214
|
-
const sep = ops.separator ?? ' / ';
|
|
6229
|
+
const labelSet = includedTrace.map((fm) => fm.label);
|
|
6230
|
+
const sep = ops.separator ?? " / ";
|
|
6215
6231
|
result.push({
|
|
6216
6232
|
label: labelSet.join(sep),
|
|
6217
6233
|
value: r.value,
|
|
@@ -6230,14 +6246,15 @@
|
|
|
6230
6246
|
const currentCardinality = countUniqueLabels(initialResult);
|
|
6231
6247
|
// Get types sorted by importance ascending (lowest first), excluding forced elements
|
|
6232
6248
|
const removableSorted = [...typeSet]
|
|
6233
|
-
.filter((t) => !forceTraceElements?.has(t.split(
|
|
6234
|
-
|
|
6249
|
+
.filter((t) => !forceTraceElements?.has(t.split("@")[0]) &&
|
|
6250
|
+
!(ops.includeNativeLabel && t === LabelTypeFull))
|
|
6235
6251
|
.sort((a, b) => (importances.get(a) ?? 0) - (importances.get(b) ?? 0));
|
|
6236
6252
|
for (const typeToRemove of removableSorted) {
|
|
6237
6253
|
const reducedSet = new Set(typeSet);
|
|
6238
6254
|
reducedSet.delete(typeToRemove);
|
|
6239
6255
|
const candidateResult = calculate(reducedSet);
|
|
6240
|
-
if (candidateResult !== undefined &&
|
|
6256
|
+
if (candidateResult !== undefined &&
|
|
6257
|
+
countUniqueLabels(candidateResult) >= currentCardinality) {
|
|
6241
6258
|
typeSet.delete(typeToRemove);
|
|
6242
6259
|
}
|
|
6243
6260
|
}
|
|
@@ -6245,7 +6262,7 @@
|
|
|
6245
6262
|
};
|
|
6246
6263
|
if (mainTypes.length === 0) {
|
|
6247
6264
|
if (secondaryTypes.length !== 0)
|
|
6248
|
-
throw new Error(
|
|
6265
|
+
throw new Error("Non-empty secondary types list while main types list is empty.");
|
|
6249
6266
|
return calculate(new Set(LabelTypeFull), true);
|
|
6250
6267
|
}
|
|
6251
6268
|
//
|
|
@@ -6284,22 +6301,22 @@
|
|
|
6284
6301
|
return calculate(fallbackSet, true);
|
|
6285
6302
|
}
|
|
6286
6303
|
|
|
6287
|
-
const PCD_PREFIX =
|
|
6288
|
-
const RT_RESOURCE_MAP = PCD_PREFIX +
|
|
6289
|
-
const RT_RESOURCE_MAP_PARTITIONED = PCD_PREFIX +
|
|
6290
|
-
const RT_JSON_PARTITIONED = PCD_PREFIX +
|
|
6291
|
-
const RT_BINARY_PARTITIONED = PCD_PREFIX +
|
|
6292
|
-
const RT_PARQUET_PARTITIONED = PCD_PREFIX +
|
|
6293
|
-
const PCD_SUP_PREFIX = PCD_PREFIX +
|
|
6294
|
-
const RT_JSON_SUPER_PARTITIONED = PCD_SUP_PREFIX +
|
|
6295
|
-
const RT_BINARY_SUPER_PARTITIONED = PCD_SUP_PREFIX +
|
|
6296
|
-
const RT_PARQUET_SUPER_PARTITIONED = PCD_SUP_PREFIX +
|
|
6304
|
+
const PCD_PREFIX = "PColumnData/";
|
|
6305
|
+
const RT_RESOURCE_MAP = PCD_PREFIX + "ResourceMap";
|
|
6306
|
+
const RT_RESOURCE_MAP_PARTITIONED = PCD_PREFIX + "Partitioned/ResourceMap";
|
|
6307
|
+
const RT_JSON_PARTITIONED = PCD_PREFIX + "JsonPartitioned";
|
|
6308
|
+
const RT_BINARY_PARTITIONED = PCD_PREFIX + "BinaryPartitioned";
|
|
6309
|
+
const RT_PARQUET_PARTITIONED = PCD_PREFIX + "ParquetPartitioned";
|
|
6310
|
+
const PCD_SUP_PREFIX = PCD_PREFIX + "Partitioned/";
|
|
6311
|
+
const RT_JSON_SUPER_PARTITIONED = PCD_SUP_PREFIX + "JsonPartitioned";
|
|
6312
|
+
const RT_BINARY_SUPER_PARTITIONED = PCD_SUP_PREFIX + "BinaryPartitioned";
|
|
6313
|
+
const RT_PARQUET_SUPER_PARTITIONED = PCD_SUP_PREFIX + "ParquetPartitioned";
|
|
6297
6314
|
const removeIndexSuffix = (keyStr) => {
|
|
6298
|
-
if (keyStr.endsWith(
|
|
6299
|
-
return { baseKey: keyStr.substring(0, keyStr.length - 6), type:
|
|
6315
|
+
if (keyStr.endsWith(".index")) {
|
|
6316
|
+
return { baseKey: keyStr.substring(0, keyStr.length - 6), type: "index" };
|
|
6300
6317
|
}
|
|
6301
|
-
else if (keyStr.endsWith(
|
|
6302
|
-
return { baseKey: keyStr.substring(0, keyStr.length - 7), type:
|
|
6318
|
+
else if (keyStr.endsWith(".values")) {
|
|
6319
|
+
return { baseKey: keyStr.substring(0, keyStr.length - 7), type: "values" };
|
|
6303
6320
|
}
|
|
6304
6321
|
else {
|
|
6305
6322
|
throw new Error(`key must ends on .index/.values for binary p-column, got: ${keyStr}`);
|
|
@@ -6317,20 +6334,20 @@
|
|
|
6317
6334
|
// @TODO validate meta shape
|
|
6318
6335
|
switch (rt) {
|
|
6319
6336
|
case RT_RESOURCE_MAP:
|
|
6320
|
-
keyLength = meta[
|
|
6337
|
+
keyLength = meta["keyLength"];
|
|
6321
6338
|
break;
|
|
6322
6339
|
case RT_RESOURCE_MAP_PARTITIONED:
|
|
6323
|
-
keyLength = meta[
|
|
6340
|
+
keyLength = meta["partitionKeyLength"] + meta["keyLength"];
|
|
6324
6341
|
break;
|
|
6325
6342
|
case RT_JSON_PARTITIONED:
|
|
6326
6343
|
case RT_BINARY_PARTITIONED:
|
|
6327
6344
|
case RT_PARQUET_PARTITIONED:
|
|
6328
|
-
keyLength = meta[
|
|
6345
|
+
keyLength = meta["partitionKeyLength"];
|
|
6329
6346
|
break;
|
|
6330
6347
|
case RT_BINARY_SUPER_PARTITIONED:
|
|
6331
6348
|
case RT_JSON_SUPER_PARTITIONED:
|
|
6332
6349
|
case RT_PARQUET_SUPER_PARTITIONED:
|
|
6333
|
-
keyLength = meta[
|
|
6350
|
+
keyLength = meta["superPartitionKeyLength"] + meta["partitionKeyLength"];
|
|
6334
6351
|
break;
|
|
6335
6352
|
}
|
|
6336
6353
|
switch (rt) {
|
|
@@ -6352,7 +6369,7 @@
|
|
|
6352
6369
|
case RT_PARQUET_SUPER_PARTITIONED:
|
|
6353
6370
|
for (const supKeyStr of acc.listInputFields()) {
|
|
6354
6371
|
const keyPrefix = [...JSON.parse(supKeyStr)];
|
|
6355
|
-
const value = acc.resolve({ field: supKeyStr, assertFieldType:
|
|
6372
|
+
const value = acc.resolve({ field: supKeyStr, assertFieldType: "Input" });
|
|
6356
6373
|
if (value !== undefined) {
|
|
6357
6374
|
for (let keyStr of value.listInputFields()) {
|
|
6358
6375
|
if (rt === RT_BINARY_SUPER_PARTITIONED) {
|
|
@@ -6368,7 +6385,9 @@
|
|
|
6368
6385
|
return { data, keyLength };
|
|
6369
6386
|
}
|
|
6370
6387
|
function getUniquePartitionKeysForDataEntries(list) {
|
|
6371
|
-
if (list.type !==
|
|
6388
|
+
if (list.type !== "JsonPartitioned" &&
|
|
6389
|
+
list.type !== "BinaryPartitioned" &&
|
|
6390
|
+
list.type !== "ParquetPartitioned")
|
|
6372
6391
|
throw new Error(`Splitting requires Partitioned DataInfoEntries, got ${list.type}`);
|
|
6373
6392
|
const { parts, partitionKeyLength } = list;
|
|
6374
6393
|
const result = [];
|
|
@@ -6401,7 +6420,7 @@
|
|
|
6401
6420
|
}
|
|
6402
6421
|
for (const l of data) {
|
|
6403
6422
|
if (l.length !== keyLength) {
|
|
6404
|
-
throw new Error(
|
|
6423
|
+
throw new Error("key length does not match partition length");
|
|
6405
6424
|
}
|
|
6406
6425
|
for (let i = 0; i < keyLength; ++i) {
|
|
6407
6426
|
result[i].add(l[i]);
|
|
@@ -6426,10 +6445,10 @@
|
|
|
6426
6445
|
const resourceType = acc.resourceType.name;
|
|
6427
6446
|
const meta = acc.getDataAsJson();
|
|
6428
6447
|
// Prevent recursive super-partitioned resources
|
|
6429
|
-
if (keyPrefix.length > 0
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6448
|
+
if (keyPrefix.length > 0 &&
|
|
6449
|
+
(resourceType === RT_JSON_SUPER_PARTITIONED ||
|
|
6450
|
+
resourceType === RT_BINARY_SUPER_PARTITIONED ||
|
|
6451
|
+
resourceType === RT_PARQUET_SUPER_PARTITIONED)) {
|
|
6433
6452
|
throw new Error(`Unexpected nested super-partitioned resource: ${resourceType}`);
|
|
6434
6453
|
}
|
|
6435
6454
|
switch (resourceType) {
|
|
@@ -6437,25 +6456,25 @@
|
|
|
6437
6456
|
case RT_RESOURCE_MAP_PARTITIONED:
|
|
6438
6457
|
throw new Error(`Only data columns are supported, got: ${resourceType}`);
|
|
6439
6458
|
case RT_JSON_PARTITIONED: {
|
|
6440
|
-
if (typeof meta?.partitionKeyLength !==
|
|
6459
|
+
if (typeof meta?.partitionKeyLength !== "number") {
|
|
6441
6460
|
throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);
|
|
6442
6461
|
}
|
|
6443
6462
|
const parts = [];
|
|
6444
6463
|
for (const keyStr of acc.listInputFields()) {
|
|
6445
|
-
const value = acc.resolve({ field: keyStr, assertFieldType:
|
|
6464
|
+
const value = acc.resolve({ field: keyStr, assertFieldType: "Input" });
|
|
6446
6465
|
if (value === undefined)
|
|
6447
6466
|
return undefined;
|
|
6448
6467
|
const key = [...keyPrefix, ...JSON.parse(keyStr)];
|
|
6449
6468
|
parts.push({ key, value });
|
|
6450
6469
|
}
|
|
6451
6470
|
return {
|
|
6452
|
-
type:
|
|
6471
|
+
type: "JsonPartitioned",
|
|
6453
6472
|
partitionKeyLength: meta.partitionKeyLength,
|
|
6454
6473
|
parts,
|
|
6455
6474
|
};
|
|
6456
6475
|
}
|
|
6457
6476
|
case RT_BINARY_PARTITIONED: {
|
|
6458
|
-
if (typeof meta?.partitionKeyLength !==
|
|
6477
|
+
if (typeof meta?.partitionKeyLength !== "number") {
|
|
6459
6478
|
throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);
|
|
6460
6479
|
}
|
|
6461
6480
|
const parts = [];
|
|
@@ -6463,7 +6482,7 @@
|
|
|
6463
6482
|
// Group fields by base key (without .index/.values suffix)
|
|
6464
6483
|
for (const keyStr of acc.listInputFields()) {
|
|
6465
6484
|
const suffix = removeIndexSuffix(keyStr);
|
|
6466
|
-
const value = acc.resolve({ field: keyStr, assertFieldType:
|
|
6485
|
+
const value = acc.resolve({ field: keyStr, assertFieldType: "Input" });
|
|
6467
6486
|
if (value === undefined)
|
|
6468
6487
|
return undefined;
|
|
6469
6488
|
let entry = baseKeys.get(suffix.baseKey);
|
|
@@ -6471,7 +6490,7 @@
|
|
|
6471
6490
|
entry = {};
|
|
6472
6491
|
baseKeys.set(suffix.baseKey, entry);
|
|
6473
6492
|
}
|
|
6474
|
-
if (suffix.type ===
|
|
6493
|
+
if (suffix.type === "index") {
|
|
6475
6494
|
entry.index = value;
|
|
6476
6495
|
}
|
|
6477
6496
|
else {
|
|
@@ -6492,39 +6511,39 @@
|
|
|
6492
6511
|
});
|
|
6493
6512
|
}
|
|
6494
6513
|
return {
|
|
6495
|
-
type:
|
|
6514
|
+
type: "BinaryPartitioned",
|
|
6496
6515
|
partitionKeyLength: meta.partitionKeyLength,
|
|
6497
6516
|
parts,
|
|
6498
6517
|
};
|
|
6499
6518
|
}
|
|
6500
6519
|
case RT_PARQUET_PARTITIONED: {
|
|
6501
|
-
if (typeof meta?.partitionKeyLength !==
|
|
6520
|
+
if (typeof meta?.partitionKeyLength !== "number") {
|
|
6502
6521
|
throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);
|
|
6503
6522
|
}
|
|
6504
6523
|
const parts = [];
|
|
6505
6524
|
for (const keyStr of acc.listInputFields()) {
|
|
6506
|
-
const value = acc.resolve({ field: keyStr, assertFieldType:
|
|
6525
|
+
const value = acc.resolve({ field: keyStr, assertFieldType: "Input" });
|
|
6507
6526
|
if (value === undefined)
|
|
6508
6527
|
return undefined;
|
|
6509
6528
|
const key = [...keyPrefix, ...JSON.parse(keyStr)];
|
|
6510
6529
|
parts.push({ key, value });
|
|
6511
6530
|
}
|
|
6512
6531
|
return {
|
|
6513
|
-
type:
|
|
6532
|
+
type: "ParquetPartitioned",
|
|
6514
6533
|
partitionKeyLength: meta.partitionKeyLength,
|
|
6515
6534
|
parts,
|
|
6516
6535
|
};
|
|
6517
6536
|
}
|
|
6518
6537
|
case RT_JSON_SUPER_PARTITIONED: {
|
|
6519
|
-
if (typeof meta?.superPartitionKeyLength !==
|
|
6520
|
-
|
|
6538
|
+
if (typeof meta?.superPartitionKeyLength !== "number" ||
|
|
6539
|
+
typeof meta?.partitionKeyLength !== "number") {
|
|
6521
6540
|
throw new Error(`Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`);
|
|
6522
6541
|
}
|
|
6523
6542
|
const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;
|
|
6524
6543
|
const parts = [];
|
|
6525
6544
|
// Process all super partitions
|
|
6526
6545
|
for (const supKeyStr of acc.listInputFields()) {
|
|
6527
|
-
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType:
|
|
6546
|
+
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: "Input" });
|
|
6528
6547
|
if (superPartition === undefined)
|
|
6529
6548
|
return undefined;
|
|
6530
6549
|
// Validate inner type
|
|
@@ -6534,26 +6553,26 @@
|
|
|
6534
6553
|
const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr));
|
|
6535
6554
|
if (innerResult === undefined)
|
|
6536
6555
|
return undefined;
|
|
6537
|
-
if (innerResult.type !==
|
|
6556
|
+
if (innerResult.type !== "JsonPartitioned")
|
|
6538
6557
|
throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);
|
|
6539
6558
|
parts.push(...innerResult.parts);
|
|
6540
6559
|
}
|
|
6541
6560
|
return {
|
|
6542
|
-
type:
|
|
6561
|
+
type: "JsonPartitioned",
|
|
6543
6562
|
partitionKeyLength: totalKeyLength,
|
|
6544
6563
|
parts,
|
|
6545
6564
|
};
|
|
6546
6565
|
}
|
|
6547
6566
|
case RT_BINARY_SUPER_PARTITIONED: {
|
|
6548
|
-
if (typeof meta?.superPartitionKeyLength !==
|
|
6549
|
-
|
|
6567
|
+
if (typeof meta?.superPartitionKeyLength !== "number" ||
|
|
6568
|
+
typeof meta?.partitionKeyLength !== "number") {
|
|
6550
6569
|
throw new Error(`Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`);
|
|
6551
6570
|
}
|
|
6552
6571
|
const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;
|
|
6553
6572
|
const parts = [];
|
|
6554
6573
|
// Process all super partitions
|
|
6555
6574
|
for (const supKeyStr of acc.listInputFields()) {
|
|
6556
|
-
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType:
|
|
6575
|
+
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: "Input" });
|
|
6557
6576
|
if (superPartition === undefined)
|
|
6558
6577
|
return undefined;
|
|
6559
6578
|
// Validate inner type
|
|
@@ -6563,26 +6582,26 @@
|
|
|
6563
6582
|
const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr));
|
|
6564
6583
|
if (innerResult === undefined)
|
|
6565
6584
|
return undefined;
|
|
6566
|
-
if (innerResult.type !==
|
|
6585
|
+
if (innerResult.type !== "BinaryPartitioned")
|
|
6567
6586
|
throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);
|
|
6568
6587
|
parts.push(...innerResult.parts);
|
|
6569
6588
|
}
|
|
6570
6589
|
return {
|
|
6571
|
-
type:
|
|
6590
|
+
type: "BinaryPartitioned",
|
|
6572
6591
|
partitionKeyLength: totalKeyLength,
|
|
6573
6592
|
parts,
|
|
6574
6593
|
};
|
|
6575
6594
|
}
|
|
6576
6595
|
case RT_PARQUET_SUPER_PARTITIONED: {
|
|
6577
|
-
if (typeof meta?.superPartitionKeyLength !==
|
|
6578
|
-
|
|
6596
|
+
if (typeof meta?.superPartitionKeyLength !== "number" ||
|
|
6597
|
+
typeof meta?.partitionKeyLength !== "number") {
|
|
6579
6598
|
throw new Error(`Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`);
|
|
6580
6599
|
}
|
|
6581
6600
|
const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;
|
|
6582
6601
|
const parts = [];
|
|
6583
6602
|
// Process all super partitions
|
|
6584
6603
|
for (const supKeyStr of acc.listInputFields()) {
|
|
6585
|
-
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType:
|
|
6604
|
+
const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: "Input" });
|
|
6586
6605
|
if (superPartition === undefined)
|
|
6587
6606
|
return undefined;
|
|
6588
6607
|
// Validate inner type
|
|
@@ -6592,12 +6611,12 @@
|
|
|
6592
6611
|
const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr));
|
|
6593
6612
|
if (innerResult === undefined)
|
|
6594
6613
|
return undefined;
|
|
6595
|
-
if (innerResult.type !==
|
|
6614
|
+
if (innerResult.type !== "ParquetPartitioned")
|
|
6596
6615
|
throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);
|
|
6597
6616
|
parts.push(...innerResult.parts);
|
|
6598
6617
|
}
|
|
6599
6618
|
return {
|
|
6600
|
-
type:
|
|
6619
|
+
type: "ParquetPartitioned",
|
|
6601
6620
|
partitionKeyLength: totalKeyLength,
|
|
6602
6621
|
parts,
|
|
6603
6622
|
};
|
|
@@ -6627,7 +6646,7 @@
|
|
|
6627
6646
|
const isValues = (d) => Array.isArray(d);
|
|
6628
6647
|
const isAccessor = (d) => d instanceof TreeNodeAccessor;
|
|
6629
6648
|
let ready = true;
|
|
6630
|
-
const data = typeof c.data ===
|
|
6649
|
+
const data = typeof c.data === "function" ? c.data() : c.data;
|
|
6631
6650
|
if (data == null) {
|
|
6632
6651
|
return false;
|
|
6633
6652
|
}
|
|
@@ -6635,7 +6654,7 @@
|
|
|
6635
6654
|
ready &&= data.getIsReadyOrError();
|
|
6636
6655
|
}
|
|
6637
6656
|
else if (isDataInfo(data)) {
|
|
6638
|
-
visitDataInfo(data, (v) => ready &&= v.getIsReadyOrError());
|
|
6657
|
+
visitDataInfo(data, (v) => (ready &&= v.getIsReadyOrError()));
|
|
6639
6658
|
}
|
|
6640
6659
|
else if (!isValues(data)) {
|
|
6641
6660
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
@@ -6653,7 +6672,7 @@
|
|
|
6653
6672
|
if (value.length === 0)
|
|
6654
6673
|
return true;
|
|
6655
6674
|
const first = value[0];
|
|
6656
|
-
return typeof first ===
|
|
6675
|
+
return typeof first === "object" && first !== null && "key" in first && "val" in first;
|
|
6657
6676
|
}
|
|
6658
6677
|
/**
|
|
6659
6678
|
* A simple implementation of {@link ColumnProvider} backed by a pre-defined array of columns.
|
|
@@ -6664,7 +6683,7 @@
|
|
|
6664
6683
|
this.columns = columns;
|
|
6665
6684
|
}
|
|
6666
6685
|
selectColumns(selectors) {
|
|
6667
|
-
const predicate = typeof selectors ===
|
|
6686
|
+
const predicate = typeof selectors === "function" ? selectors : selectorsToPredicate(selectors);
|
|
6668
6687
|
// Filter based on spec, ignoring data type for now
|
|
6669
6688
|
return this.columns.filter((column) => predicate(column.spec));
|
|
6670
6689
|
}
|
|
@@ -6691,33 +6710,39 @@
|
|
|
6691
6710
|
}
|
|
6692
6711
|
/** Checks if a selector object uses any anchor properties */
|
|
6693
6712
|
function hasAnchors(selector) {
|
|
6694
|
-
if (!selector || typeof selector !==
|
|
6713
|
+
if (!selector || typeof selector !== "object")
|
|
6695
6714
|
return false;
|
|
6696
6715
|
const potentialAnchored = selector;
|
|
6697
|
-
const domainHasAnchors = potentialAnchored[
|
|
6698
|
-
|
|
6699
|
-
|
|
6716
|
+
const domainHasAnchors = potentialAnchored["domain"] &&
|
|
6717
|
+
typeof potentialAnchored["domain"] === "object" &&
|
|
6718
|
+
Object.values(potentialAnchored["domain"]).some((v) => typeof v === "object" && v !== null && "anchor" in v);
|
|
6719
|
+
const axesHaveAnchors = potentialAnchored["axes"] &&
|
|
6720
|
+
Array.isArray(potentialAnchored["axes"]) &&
|
|
6721
|
+
potentialAnchored["axes"].some((a) => typeof a === "object" && a !== null && "anchor" in a);
|
|
6722
|
+
return !!potentialAnchored["domainAnchor"] || domainHasAnchors || axesHaveAnchors;
|
|
6700
6723
|
}
|
|
6701
6724
|
/**
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6725
|
+
* Derives the indices of axes marked for splitting based on the selector.
|
|
6726
|
+
* Throws an error if splitting is requested alongside `partialAxesMatch`.
|
|
6727
|
+
*/
|
|
6705
6728
|
function getSplitAxisIndices(selector) {
|
|
6706
|
-
if (typeof selector !==
|
|
6729
|
+
if (typeof selector !== "object" || !("axes" in selector) || selector.axes === undefined) {
|
|
6707
6730
|
return []; // No axes specified or not an object selector, no splitting
|
|
6708
6731
|
}
|
|
6709
6732
|
const splitIndices = selector.axes
|
|
6710
|
-
.map((axis, index) =>
|
|
6733
|
+
.map((axis, index) => typeof axis === "object" && "split" in axis && axis.split === true ? index : -1)
|
|
6711
6734
|
.filter((index) => index !== -1);
|
|
6712
6735
|
if (splitIndices.length > 0 && selector.partialAxesMatch !== undefined) {
|
|
6713
|
-
throw new Error(
|
|
6736
|
+
throw new Error("Axis splitting is not supported when `partialAxesMatch` is defined.");
|
|
6714
6737
|
}
|
|
6715
6738
|
splitIndices.sort((a, b) => a - b);
|
|
6716
6739
|
return splitIndices;
|
|
6717
6740
|
}
|
|
6718
6741
|
class PColumnCollection {
|
|
6719
6742
|
defaultProviderStore = [];
|
|
6720
|
-
providers = [
|
|
6743
|
+
providers = [
|
|
6744
|
+
new ArrayColumnProvider(this.defaultProviderStore),
|
|
6745
|
+
];
|
|
6721
6746
|
axisLabelProviders = [];
|
|
6722
6747
|
constructor() { }
|
|
6723
6748
|
addColumnProvider(provider) {
|
|
@@ -6746,18 +6771,19 @@
|
|
|
6746
6771
|
return undefined;
|
|
6747
6772
|
}
|
|
6748
6773
|
getUniversalEntries(predicateOrSelectors, opts) {
|
|
6749
|
-
const { anchorCtx, labelOps: rawLabelOps, dontWaitAllData = false, overrideLabelAnnotation = false, exclude, enrichByLinkers = false } = opts ?? {};
|
|
6774
|
+
const { anchorCtx, labelOps: rawLabelOps, dontWaitAllData = false, overrideLabelAnnotation = false, exclude, enrichByLinkers = false, } = opts ?? {};
|
|
6750
6775
|
const labelOps = {
|
|
6751
|
-
...(overrideLabelAnnotation && rawLabelOps?.includeNativeLabel !== false
|
|
6752
|
-
|
|
6776
|
+
...(overrideLabelAnnotation && rawLabelOps?.includeNativeLabel !== false
|
|
6777
|
+
? { includeNativeLabel: true }
|
|
6778
|
+
: {}),
|
|
6779
|
+
...rawLabelOps,
|
|
6753
6780
|
};
|
|
6754
6781
|
let excludePredicate = () => false;
|
|
6755
6782
|
if (exclude) {
|
|
6756
|
-
const excludePredicartes = (Array.isArray(exclude) ? exclude : [exclude])
|
|
6757
|
-
.map((selector) => {
|
|
6783
|
+
const excludePredicartes = (Array.isArray(exclude) ? exclude : [exclude]).map((selector) => {
|
|
6758
6784
|
if (hasAnchors(selector)) {
|
|
6759
6785
|
if (!anchorCtx)
|
|
6760
|
-
throw new Error(
|
|
6786
|
+
throw new Error("Anchored selectors in exclude require an AnchoredIdDeriver to be provided in options.");
|
|
6761
6787
|
return selectorsToPredicate(resolveAnchors(anchorCtx.anchors, selector, opts));
|
|
6762
6788
|
}
|
|
6763
6789
|
else
|
|
@@ -6765,7 +6791,7 @@
|
|
|
6765
6791
|
});
|
|
6766
6792
|
excludePredicate = (spec) => excludePredicartes.some((predicate) => predicate(spec));
|
|
6767
6793
|
}
|
|
6768
|
-
const selectorsArray = typeof predicateOrSelectors ===
|
|
6794
|
+
const selectorsArray = typeof predicateOrSelectors === "function"
|
|
6769
6795
|
? [predicateOrSelectors]
|
|
6770
6796
|
: Array.isArray(predicateOrSelectors)
|
|
6771
6797
|
? predicateOrSelectors
|
|
@@ -6777,7 +6803,7 @@
|
|
|
6777
6803
|
let currentSelector;
|
|
6778
6804
|
if (usesAnchors) {
|
|
6779
6805
|
if (!anchorCtx)
|
|
6780
|
-
throw new Error(
|
|
6806
|
+
throw new Error("Anchored selectors require an AnchoredIdDeriver to be provided in options.");
|
|
6781
6807
|
currentSelector = resolveAnchors(anchorCtx.anchors, rawSelector, opts);
|
|
6782
6808
|
}
|
|
6783
6809
|
else
|
|
@@ -6822,14 +6848,13 @@
|
|
|
6822
6848
|
const maxSplitIdx = splitAxisIdxs[splitAxisIdxs.length - 1];
|
|
6823
6849
|
if (maxSplitIdx >= dataEntries.partitionKeyLength)
|
|
6824
6850
|
throw new Error(`Not enough partition keys (${dataEntries.partitionKeyLength}) for requested split axes (max index ${maxSplitIdx}) in column ${originalSpec.name}`);
|
|
6825
|
-
const axesLabels = splitAxisIdxs
|
|
6826
|
-
.map((idx) => this.findLabels(getAxisId(originalSpec.axesSpec[idx])));
|
|
6851
|
+
const axesLabels = splitAxisIdxs.map((idx) => this.findLabels(getAxisId(originalSpec.axesSpec[idx])));
|
|
6827
6852
|
const keyCombinations = [];
|
|
6828
6853
|
const generateCombinations = (currentCombo, sAxisIdx) => {
|
|
6829
6854
|
if (sAxisIdx >= splitAxisIdxs.length) {
|
|
6830
6855
|
keyCombinations.push([...currentCombo]);
|
|
6831
6856
|
if (keyCombinations.length > 10000)
|
|
6832
|
-
throw new Error(
|
|
6857
|
+
throw new Error("Too many key combinations, aborting.");
|
|
6833
6858
|
return;
|
|
6834
6859
|
}
|
|
6835
6860
|
const axisIdx = splitAxisIdxs[sAxisIdx];
|
|
@@ -6865,7 +6890,7 @@
|
|
|
6865
6890
|
return { axisIdx, axisId, value: value, label };
|
|
6866
6891
|
});
|
|
6867
6892
|
intermediateResults.push({
|
|
6868
|
-
type:
|
|
6893
|
+
type: "split",
|
|
6869
6894
|
originalColumn: column,
|
|
6870
6895
|
spec: originalSpec,
|
|
6871
6896
|
adjustedSpec,
|
|
@@ -6876,7 +6901,7 @@
|
|
|
6876
6901
|
}
|
|
6877
6902
|
else {
|
|
6878
6903
|
intermediateResults.push({
|
|
6879
|
-
type:
|
|
6904
|
+
type: "direct",
|
|
6880
6905
|
originalColumn: column,
|
|
6881
6906
|
spec: originalSpec,
|
|
6882
6907
|
adjustedSpec: originalSpec,
|
|
@@ -6888,12 +6913,12 @@
|
|
|
6888
6913
|
return [];
|
|
6889
6914
|
const labeledResults = deriveLabels(intermediateResults, (entry) => ({
|
|
6890
6915
|
spec: entry.spec,
|
|
6891
|
-
suffixTrace: entry.type ===
|
|
6916
|
+
suffixTrace: entry.type === "split" ? splitFiltersToTrace(entry.axisFilters) : undefined,
|
|
6892
6917
|
}), labelOps);
|
|
6893
6918
|
const result = [];
|
|
6894
6919
|
for (const { value: entry, label } of labeledResults) {
|
|
6895
6920
|
const { originalColumn, spec: originalSpec } = entry;
|
|
6896
|
-
const axisFilters = entry.type ===
|
|
6921
|
+
const axisFilters = entry.type === "split" ? entry.axisFilters : undefined;
|
|
6897
6922
|
const axisFiltersTuple = splitFiltersToAxisFilter(axisFilters);
|
|
6898
6923
|
let finalId;
|
|
6899
6924
|
if (anchorCtx)
|
|
@@ -6905,7 +6930,7 @@
|
|
|
6905
6930
|
finalSpec = {
|
|
6906
6931
|
...finalSpec,
|
|
6907
6932
|
annotations: {
|
|
6908
|
-
...
|
|
6933
|
+
...finalSpec.annotations,
|
|
6909
6934
|
[Annotation.Label]: label,
|
|
6910
6935
|
},
|
|
6911
6936
|
};
|
|
@@ -6913,7 +6938,7 @@
|
|
|
6913
6938
|
result.push({
|
|
6914
6939
|
id: finalId,
|
|
6915
6940
|
spec: finalSpec,
|
|
6916
|
-
data: () => entry.type ===
|
|
6941
|
+
data: () => entry.type === "split"
|
|
6917
6942
|
? entriesToDataInfo(filterDataInfoEntries(entry.dataEntries, axisFiltersTuple))
|
|
6918
6943
|
: entry.originalColumn.data,
|
|
6919
6944
|
label: label,
|
|
@@ -6934,10 +6959,11 @@
|
|
|
6934
6959
|
// search all axes that can be reached by linkers from anchor axes; anchor axes are not in this list;
|
|
6935
6960
|
const availableByLinkersAxes = linkerMap.getReachableByLinkersAxesFromAxes(anchorAxes, matchAxisIdFn);
|
|
6936
6961
|
// search all columns that includes at least one of additional axes;
|
|
6937
|
-
const availableByLinkersColumns = this.getUniversalEntries((spec) => !isLinkerColumn(spec) &&
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6962
|
+
const availableByLinkersColumns = this.getUniversalEntries((spec) => !isLinkerColumn(spec) &&
|
|
6963
|
+
spec.axesSpec.some((columnAxisSpec) => {
|
|
6964
|
+
const columnAxisId = getAxisId(columnAxisSpec);
|
|
6965
|
+
return availableByLinkersAxes.some((axis) => matchAxisIdFn(getAxisId(axis), columnAxisId));
|
|
6966
|
+
}), { anchorCtx, labelOps, dontWaitAllData, overrideLabelAnnotation, exclude });
|
|
6941
6967
|
if (availableByLinkersColumns) {
|
|
6942
6968
|
result.push(...availableByLinkersColumns.filter((entry) => !ids.has(entry.id)));
|
|
6943
6969
|
}
|
|
@@ -6947,7 +6973,7 @@
|
|
|
6947
6973
|
getColumns(predicateOrSelectors, opts) {
|
|
6948
6974
|
const entries = this.getUniversalEntries(predicateOrSelectors, {
|
|
6949
6975
|
overrideLabelAnnotation: true, // default for getColumns
|
|
6950
|
-
...
|
|
6976
|
+
...opts,
|
|
6951
6977
|
});
|
|
6952
6978
|
if (!entries)
|
|
6953
6979
|
return undefined;
|
|
@@ -6971,12 +6997,12 @@
|
|
|
6971
6997
|
|
|
6972
6998
|
function patchInSetFilters(filters) {
|
|
6973
6999
|
const inSetToOrEqual = (predicate) => {
|
|
6974
|
-
if (predicate.operator !==
|
|
7000
|
+
if (predicate.operator !== "InSet")
|
|
6975
7001
|
return predicate;
|
|
6976
7002
|
return {
|
|
6977
|
-
operator:
|
|
7003
|
+
operator: "Or",
|
|
6978
7004
|
operands: predicate.references.map((reference) => ({
|
|
6979
|
-
operator:
|
|
7005
|
+
operator: "Equal",
|
|
6980
7006
|
reference,
|
|
6981
7007
|
})),
|
|
6982
7008
|
};
|
|
@@ -6984,17 +7010,17 @@
|
|
|
6984
7010
|
const mapSingleValuePredicate = (filter, cb) => {
|
|
6985
7011
|
const operator = filter.operator;
|
|
6986
7012
|
switch (operator) {
|
|
6987
|
-
case
|
|
7013
|
+
case "And":
|
|
6988
7014
|
return {
|
|
6989
7015
|
...filter,
|
|
6990
7016
|
operands: filter.operands.map((operand) => mapSingleValuePredicate(operand, cb)),
|
|
6991
7017
|
};
|
|
6992
|
-
case
|
|
7018
|
+
case "Or":
|
|
6993
7019
|
return {
|
|
6994
7020
|
...filter,
|
|
6995
7021
|
operands: filter.operands.map((operand) => mapSingleValuePredicate(operand, cb)),
|
|
6996
7022
|
};
|
|
6997
|
-
case
|
|
7023
|
+
case "Not":
|
|
6998
7024
|
return {
|
|
6999
7025
|
...filter,
|
|
7000
7026
|
operand: mapSingleValuePredicate(filter.operand, cb),
|
|
@@ -7056,18 +7082,18 @@
|
|
|
7056
7082
|
return this.ctx.calculateOptions(predicate);
|
|
7057
7083
|
}
|
|
7058
7084
|
getOptions(predicateOrSelector, opts) {
|
|
7059
|
-
const predicate = typeof predicateOrSelector ===
|
|
7085
|
+
const predicate = typeof predicateOrSelector === "function"
|
|
7060
7086
|
? predicateOrSelector
|
|
7061
7087
|
: selectorsToPredicate(predicateOrSelector);
|
|
7062
7088
|
const filtered = this.getSpecs().entries.filter((s) => predicate(s.obj));
|
|
7063
7089
|
let labelOps = {};
|
|
7064
7090
|
let refsWithEnrichments = false;
|
|
7065
|
-
if (typeof opts !==
|
|
7066
|
-
if (typeof opts ===
|
|
7091
|
+
if (typeof opts !== "undefined") {
|
|
7092
|
+
if (typeof opts === "function") {
|
|
7067
7093
|
labelOps = opts;
|
|
7068
7094
|
}
|
|
7069
|
-
else if (typeof opts ===
|
|
7070
|
-
if (
|
|
7095
|
+
else if (typeof opts === "object") {
|
|
7096
|
+
if ("includeNativeLabel" in opts || "separator" in opts || "addLabelAsSuffix" in opts) {
|
|
7071
7097
|
labelOps = opts;
|
|
7072
7098
|
}
|
|
7073
7099
|
else {
|
|
@@ -7077,7 +7103,7 @@
|
|
|
7077
7103
|
}
|
|
7078
7104
|
}
|
|
7079
7105
|
}
|
|
7080
|
-
if (typeof labelOps ===
|
|
7106
|
+
if (typeof labelOps === "object")
|
|
7081
7107
|
return deriveLabels(filtered, (o) => o.obj, labelOps ?? {}).map(({ value: { ref }, label }) => ({
|
|
7082
7108
|
ref: withEnrichments(ref, refsWithEnrichments),
|
|
7083
7109
|
label,
|
|
@@ -7225,7 +7251,7 @@
|
|
|
7225
7251
|
*/
|
|
7226
7252
|
getDataByRef(ref) {
|
|
7227
7253
|
// @TODO remove after 1 Jan 2025; forward compatibility
|
|
7228
|
-
if (typeof this.ctx.getDataFromResultPoolByRef ===
|
|
7254
|
+
if (typeof this.ctx.getDataFromResultPoolByRef === "undefined")
|
|
7229
7255
|
return this.getData().entries.find((f) => f.ref.blockId === ref.blockId && f.ref.name === ref.name)?.obj;
|
|
7230
7256
|
const data = this.ctx.getDataFromResultPoolByRef(ref.blockId, ref.name); // Keep original call
|
|
7231
7257
|
// Need to handle undefined case before mapping
|
|
@@ -7315,12 +7341,12 @@
|
|
|
7315
7341
|
if (!isPColumn(column.obj))
|
|
7316
7342
|
continue;
|
|
7317
7343
|
const spec = column.obj.spec;
|
|
7318
|
-
if (spec.name === PColumnName.Label
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
if (column.obj.data.resourceType.name !==
|
|
7344
|
+
if (spec.name === PColumnName.Label &&
|
|
7345
|
+
spec.axesSpec.length === 1 &&
|
|
7346
|
+
spec.axesSpec[0].name === axis.name &&
|
|
7347
|
+
spec.axesSpec[0].type === axis.type &&
|
|
7348
|
+
matchDomain(axis.domain, spec.axesSpec[0].domain)) {
|
|
7349
|
+
if (column.obj.data.resourceType.name !== "PColumnData/Json") {
|
|
7324
7350
|
throw Error(`Expected JSON column for labels, got: ${column.obj.data.resourceType.name}`);
|
|
7325
7351
|
}
|
|
7326
7352
|
const labels = Object.fromEntries(Object.entries(column.obj.data.getDataAsJson().data).map((e) => [JSON.parse(e[0])[0], e[1]]));
|
|
@@ -7337,7 +7363,7 @@
|
|
|
7337
7363
|
* @returns An array of PColumn objects matching the selectors. Data is loaded on first access.
|
|
7338
7364
|
*/
|
|
7339
7365
|
selectColumns(selectors) {
|
|
7340
|
-
const predicate = typeof selectors ===
|
|
7366
|
+
const predicate = typeof selectors === "function" ? selectors : selectorsToPredicate(selectors);
|
|
7341
7367
|
const matchedSpecs = this.getSpecs().entries.filter(({ obj: spec }) => {
|
|
7342
7368
|
if (!isPColumnSpec(spec))
|
|
7343
7369
|
return false;
|
|
@@ -7375,7 +7401,7 @@
|
|
|
7375
7401
|
if (axisKeys !== undefined) {
|
|
7376
7402
|
const keys = JSON.parse(axisKeys);
|
|
7377
7403
|
return Object.fromEntries(keys.map((key) => {
|
|
7378
|
-
return [key, labels[key] ??
|
|
7404
|
+
return [key, labels[key] ?? "Unlabelled"];
|
|
7379
7405
|
}));
|
|
7380
7406
|
}
|
|
7381
7407
|
else {
|
|
@@ -7393,7 +7419,7 @@
|
|
|
7393
7419
|
get data() {
|
|
7394
7420
|
if (this._dataCache === undefined) {
|
|
7395
7421
|
const raw = this.ctx.data;
|
|
7396
|
-
const value = typeof raw ===
|
|
7422
|
+
const value = typeof raw === "function" ? raw() : raw;
|
|
7397
7423
|
this._dataCache = { v: value ? JSON.parse(value) : {} };
|
|
7398
7424
|
}
|
|
7399
7425
|
return this._dataCache.v;
|
|
@@ -7407,7 +7433,7 @@
|
|
|
7407
7433
|
get activeArgs() {
|
|
7408
7434
|
if (this._activeArgsCache === undefined) {
|
|
7409
7435
|
const raw = this.ctx.activeArgs;
|
|
7410
|
-
const value = typeof raw ===
|
|
7436
|
+
const value = typeof raw === "function" ? raw() : raw;
|
|
7411
7437
|
this._activeArgsCache = {
|
|
7412
7438
|
v: value ? JSON.parse(value) : undefined,
|
|
7413
7439
|
};
|
|
@@ -7470,11 +7496,11 @@
|
|
|
7470
7496
|
}
|
|
7471
7497
|
createPTable(def) {
|
|
7472
7498
|
let rawDef;
|
|
7473
|
-
if (
|
|
7499
|
+
if ("columns" in def) {
|
|
7474
7500
|
rawDef = this.patchPTableDef({
|
|
7475
7501
|
src: {
|
|
7476
|
-
type:
|
|
7477
|
-
entries: def.columns.map((c) => ({ type:
|
|
7502
|
+
type: "full",
|
|
7503
|
+
entries: def.columns.map((c) => ({ type: "column", column: c })),
|
|
7478
7504
|
},
|
|
7479
7505
|
partitionFilters: def.filters ?? [],
|
|
7480
7506
|
filters: [],
|
|
@@ -7513,7 +7539,7 @@
|
|
|
7513
7539
|
get args() {
|
|
7514
7540
|
if (this._argsCache === undefined) {
|
|
7515
7541
|
const raw = this.ctx.args;
|
|
7516
|
-
const value = typeof raw ===
|
|
7542
|
+
const value = typeof raw === "function" ? raw() : raw;
|
|
7517
7543
|
this._argsCache = { v: JSON.parse(value) };
|
|
7518
7544
|
}
|
|
7519
7545
|
return this._argsCache.v;
|
|
@@ -7522,14 +7548,14 @@
|
|
|
7522
7548
|
get uiState() {
|
|
7523
7549
|
if (this._uiStateCache === undefined) {
|
|
7524
7550
|
const raw = this.ctx.uiState;
|
|
7525
|
-
const value = typeof raw ===
|
|
7551
|
+
const value = typeof raw === "function" ? raw() : raw;
|
|
7526
7552
|
this._uiStateCache = { v: value ? JSON.parse(value) : {} };
|
|
7527
7553
|
}
|
|
7528
7554
|
return this._uiStateCache.v;
|
|
7529
7555
|
}
|
|
7530
7556
|
}
|
|
7531
7557
|
|
|
7532
|
-
var version = "1.53.
|
|
7558
|
+
var version = "1.53.13";
|
|
7533
7559
|
|
|
7534
7560
|
const PlatformaSDKVersion = version;
|
|
7535
7561
|
|
|
@@ -7560,7 +7586,7 @@
|
|
|
7560
7586
|
requiresModelAPIVersion: 1,
|
|
7561
7587
|
};
|
|
7562
7588
|
}
|
|
7563
|
-
static create(renderingMode =
|
|
7589
|
+
static create(renderingMode = "Heavy") {
|
|
7564
7590
|
return new BlockModel({
|
|
7565
7591
|
renderingMode,
|
|
7566
7592
|
initialUiState: {},
|
|
@@ -7571,7 +7597,7 @@
|
|
|
7571
7597
|
});
|
|
7572
7598
|
}
|
|
7573
7599
|
output(key, cfgOrRf, flags = {}) {
|
|
7574
|
-
if (typeof cfgOrRf ===
|
|
7600
|
+
if (typeof cfgOrRf === "function") {
|
|
7575
7601
|
const handle = `output#${key}`;
|
|
7576
7602
|
tryRegisterCallback(handle, () => cfgOrRf(new RenderCtxLegacy()));
|
|
7577
7603
|
return new BlockModel({
|
|
@@ -7609,13 +7635,13 @@
|
|
|
7609
7635
|
return this.output(key, rf, { retentive: true, withStatus: true });
|
|
7610
7636
|
}
|
|
7611
7637
|
argsValid(cfgOrRf) {
|
|
7612
|
-
if (typeof cfgOrRf ===
|
|
7613
|
-
tryRegisterCallback(
|
|
7638
|
+
if (typeof cfgOrRf === "function") {
|
|
7639
|
+
tryRegisterCallback("inputsValid", () => cfgOrRf(new RenderCtxLegacy()));
|
|
7614
7640
|
return new BlockModel({
|
|
7615
7641
|
...this.config,
|
|
7616
7642
|
inputsValid: {
|
|
7617
7643
|
__renderLambda: true,
|
|
7618
|
-
handle:
|
|
7644
|
+
handle: "inputsValid",
|
|
7619
7645
|
},
|
|
7620
7646
|
});
|
|
7621
7647
|
}
|
|
@@ -7630,13 +7656,13 @@
|
|
|
7630
7656
|
if (Array.isArray(arrOrCfgOrRf)) {
|
|
7631
7657
|
return this.sections(getImmediate(arrOrCfgOrRf));
|
|
7632
7658
|
}
|
|
7633
|
-
else if (typeof arrOrCfgOrRf ===
|
|
7634
|
-
tryRegisterCallback(
|
|
7659
|
+
else if (typeof arrOrCfgOrRf === "function") {
|
|
7660
|
+
tryRegisterCallback("sections", () => arrOrCfgOrRf(new RenderCtxLegacy()));
|
|
7635
7661
|
return new BlockModel({
|
|
7636
7662
|
...this.config,
|
|
7637
7663
|
sections: {
|
|
7638
7664
|
__renderLambda: true,
|
|
7639
|
-
handle:
|
|
7665
|
+
handle: "sections",
|
|
7640
7666
|
},
|
|
7641
7667
|
});
|
|
7642
7668
|
}
|
|
@@ -7649,32 +7675,32 @@
|
|
|
7649
7675
|
}
|
|
7650
7676
|
/** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */
|
|
7651
7677
|
title(rf) {
|
|
7652
|
-
tryRegisterCallback(
|
|
7678
|
+
tryRegisterCallback("title", () => rf(new RenderCtxLegacy()));
|
|
7653
7679
|
return new BlockModel({
|
|
7654
7680
|
...this.config,
|
|
7655
7681
|
title: {
|
|
7656
7682
|
__renderLambda: true,
|
|
7657
|
-
handle:
|
|
7683
|
+
handle: "title",
|
|
7658
7684
|
},
|
|
7659
7685
|
});
|
|
7660
7686
|
}
|
|
7661
7687
|
subtitle(rf) {
|
|
7662
|
-
tryRegisterCallback(
|
|
7688
|
+
tryRegisterCallback("subtitle", () => rf(new RenderCtxLegacy()));
|
|
7663
7689
|
return new BlockModel({
|
|
7664
7690
|
...this.config,
|
|
7665
7691
|
subtitle: {
|
|
7666
7692
|
__renderLambda: true,
|
|
7667
|
-
handle:
|
|
7693
|
+
handle: "subtitle",
|
|
7668
7694
|
},
|
|
7669
7695
|
});
|
|
7670
7696
|
}
|
|
7671
7697
|
tags(rf) {
|
|
7672
|
-
tryRegisterCallback(
|
|
7698
|
+
tryRegisterCallback("tags", () => rf(new RenderCtxLegacy()));
|
|
7673
7699
|
return new BlockModel({
|
|
7674
7700
|
...this.config,
|
|
7675
7701
|
tags: {
|
|
7676
7702
|
__renderLambda: true,
|
|
7677
|
-
handle:
|
|
7703
|
+
handle: "tags",
|
|
7678
7704
|
},
|
|
7679
7705
|
});
|
|
7680
7706
|
}
|
|
@@ -7714,12 +7740,12 @@
|
|
|
7714
7740
|
* Influences dependency graph construction.
|
|
7715
7741
|
*/
|
|
7716
7742
|
enriches(lambda) {
|
|
7717
|
-
tryRegisterCallback(
|
|
7743
|
+
tryRegisterCallback("enrichmentTargets", lambda);
|
|
7718
7744
|
return new BlockModel({
|
|
7719
7745
|
...this.config,
|
|
7720
7746
|
enrichmentTargets: {
|
|
7721
7747
|
__renderLambda: true,
|
|
7722
|
-
handle:
|
|
7748
|
+
handle: "enrichmentTargets",
|
|
7723
7749
|
},
|
|
7724
7750
|
});
|
|
7725
7751
|
}
|
|
@@ -7734,7 +7760,7 @@
|
|
|
7734
7760
|
}
|
|
7735
7761
|
#done() {
|
|
7736
7762
|
if (this.config.initialArgs === undefined)
|
|
7737
|
-
throw new Error(
|
|
7763
|
+
throw new Error("Initial arguments not set.");
|
|
7738
7764
|
const config = {
|
|
7739
7765
|
v4: undefined,
|
|
7740
7766
|
v3: {
|
|
@@ -7759,21 +7785,30 @@
|
|
|
7759
7785
|
initialArgs: this.config.initialArgs,
|
|
7760
7786
|
inputsValid: downgradeCfgOrLambda(this.config.inputsValid),
|
|
7761
7787
|
sections: downgradeCfgOrLambda(this.config.sections),
|
|
7762
|
-
outputs: Object.fromEntries(Object.entries(this.config.outputs).map(([key, value]) => [
|
|
7788
|
+
outputs: Object.fromEntries(Object.entries(this.config.outputs).map(([key, value]) => [
|
|
7789
|
+
key,
|
|
7790
|
+
downgradeCfgOrLambda(value),
|
|
7791
|
+
])),
|
|
7763
7792
|
};
|
|
7764
|
-
globalThis.platformaApiVersion = this.config.featureFlags
|
|
7793
|
+
globalThis.platformaApiVersion = this.config.featureFlags
|
|
7794
|
+
.requiresUIAPIVersion;
|
|
7765
7795
|
if (!isInUI())
|
|
7766
7796
|
// we are in the configuration rendering routine, not in actual UI
|
|
7767
7797
|
return { config };
|
|
7768
7798
|
// normal operation inside the UI
|
|
7769
7799
|
else
|
|
7770
7800
|
return {
|
|
7771
|
-
...getPlatformaInstance({
|
|
7801
|
+
...getPlatformaInstance({
|
|
7802
|
+
sdkVersion: PlatformaSDKVersion,
|
|
7803
|
+
apiVersion: platformaApiVersion,
|
|
7804
|
+
}),
|
|
7772
7805
|
blockModelInfo: {
|
|
7773
|
-
outputs: Object.fromEntries(Object.entries(this.config.outputs)
|
|
7774
|
-
|
|
7806
|
+
outputs: Object.fromEntries(Object.entries(this.config.outputs).map(([key, value]) => [
|
|
7807
|
+
key,
|
|
7808
|
+
{
|
|
7775
7809
|
withStatus: Boolean(isConfigLambda(value) && value.withStatus),
|
|
7776
|
-
}
|
|
7810
|
+
},
|
|
7811
|
+
])),
|
|
7777
7812
|
},
|
|
7778
7813
|
};
|
|
7779
7814
|
}
|
|
@@ -7819,7 +7854,7 @@
|
|
|
7819
7854
|
}
|
|
7820
7855
|
// Parse JSON string if needed
|
|
7821
7856
|
let parsed = rawStorage;
|
|
7822
|
-
if (typeof rawStorage ===
|
|
7857
|
+
if (typeof rawStorage === "string") {
|
|
7823
7858
|
try {
|
|
7824
7859
|
parsed = JSON.parse(rawStorage);
|
|
7825
7860
|
}
|
|
@@ -7863,18 +7898,18 @@
|
|
|
7863
7898
|
* Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.
|
|
7864
7899
|
*/
|
|
7865
7900
|
function isLegacyModelV1ApiFormat(data) {
|
|
7866
|
-
if (data === null || typeof data !==
|
|
7901
|
+
if (data === null || typeof data !== "object")
|
|
7867
7902
|
return false;
|
|
7868
7903
|
if (isBlockStorage(data))
|
|
7869
7904
|
return false;
|
|
7870
7905
|
const obj = data;
|
|
7871
|
-
return
|
|
7906
|
+
return "args" in obj;
|
|
7872
7907
|
}
|
|
7873
7908
|
// =============================================================================
|
|
7874
7909
|
// Auto-register internal callbacks when module is loaded in VM
|
|
7875
7910
|
// =============================================================================
|
|
7876
7911
|
// Register apply update callback (requires existing storage)
|
|
7877
|
-
tryRegisterCallback(
|
|
7912
|
+
tryRegisterCallback("__pl_storage_applyUpdate", (currentStorageJson, payload) => {
|
|
7878
7913
|
return applyStorageUpdate(currentStorageJson, payload);
|
|
7879
7914
|
});
|
|
7880
7915
|
/**
|
|
@@ -7893,7 +7928,7 @@
|
|
|
7893
7928
|
return stringifyJson(debugView);
|
|
7894
7929
|
}
|
|
7895
7930
|
// Register debug view callback
|
|
7896
|
-
tryRegisterCallback(
|
|
7931
|
+
tryRegisterCallback("__pl_storage_debugView", (rawStorage) => {
|
|
7897
7932
|
return getStorageDebugView(rawStorage);
|
|
7898
7933
|
});
|
|
7899
7934
|
/**
|
|
@@ -7911,7 +7946,7 @@
|
|
|
7911
7946
|
// Get the callback registry context
|
|
7912
7947
|
const ctx = tryGetCfgRenderCtx();
|
|
7913
7948
|
if (ctx === undefined) {
|
|
7914
|
-
return { error:
|
|
7949
|
+
return { error: "Not in config rendering context" };
|
|
7915
7950
|
}
|
|
7916
7951
|
// Normalize storage to get current data and version
|
|
7917
7952
|
const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);
|
|
@@ -7925,9 +7960,9 @@
|
|
|
7925
7960
|
});
|
|
7926
7961
|
};
|
|
7927
7962
|
// Get the migrate callback (registered by DataModel.registerCallbacks())
|
|
7928
|
-
const migrateCallback = ctx.callbackRegistry[
|
|
7929
|
-
if (typeof migrateCallback !==
|
|
7930
|
-
return { error:
|
|
7963
|
+
const migrateCallback = ctx.callbackRegistry["__pl_data_upgrade"];
|
|
7964
|
+
if (typeof migrateCallback !== "function") {
|
|
7965
|
+
return { error: "__pl_data_upgrade callback not found (DataModel not registered)" };
|
|
7931
7966
|
}
|
|
7932
7967
|
// Call the migrator's migrate function
|
|
7933
7968
|
let result;
|
|
@@ -7951,7 +7986,7 @@
|
|
|
7951
7986
|
};
|
|
7952
7987
|
}
|
|
7953
7988
|
// Register migrate callback
|
|
7954
|
-
tryRegisterCallback(
|
|
7989
|
+
tryRegisterCallback("__pl_storage_migrate", (currentStorageJson) => {
|
|
7955
7990
|
return migrateStorage(currentStorageJson);
|
|
7956
7991
|
});
|
|
7957
7992
|
/**
|
|
@@ -7964,14 +7999,14 @@
|
|
|
7964
7999
|
function deriveArgsFromStorage(storageJson) {
|
|
7965
8000
|
const ctx = tryGetCfgRenderCtx();
|
|
7966
8001
|
if (ctx === undefined) {
|
|
7967
|
-
return { error:
|
|
8002
|
+
return { error: "Not in config rendering context" };
|
|
7968
8003
|
}
|
|
7969
8004
|
// Extract data from storage
|
|
7970
8005
|
const { data } = normalizeStorage(storageJson);
|
|
7971
8006
|
// Get the args callback (registered by BlockModelV3.args())
|
|
7972
|
-
const argsCallback = ctx.callbackRegistry[
|
|
7973
|
-
if (typeof argsCallback !==
|
|
7974
|
-
return { error:
|
|
8007
|
+
const argsCallback = ctx.callbackRegistry["args"];
|
|
8008
|
+
if (typeof argsCallback !== "function") {
|
|
8009
|
+
return { error: "args callback not found" };
|
|
7975
8010
|
}
|
|
7976
8011
|
// Call the args callback with extracted data
|
|
7977
8012
|
try {
|
|
@@ -7984,7 +8019,7 @@
|
|
|
7984
8019
|
}
|
|
7985
8020
|
}
|
|
7986
8021
|
// Register args derivation callback
|
|
7987
|
-
tryRegisterCallback(
|
|
8022
|
+
tryRegisterCallback("__pl_args_derive", (storageJson) => {
|
|
7988
8023
|
return deriveArgsFromStorage(storageJson);
|
|
7989
8024
|
});
|
|
7990
8025
|
/**
|
|
@@ -7997,13 +8032,13 @@
|
|
|
7997
8032
|
function derivePrerunArgsFromStorage(storageJson) {
|
|
7998
8033
|
const ctx = tryGetCfgRenderCtx();
|
|
7999
8034
|
if (ctx === undefined) {
|
|
8000
|
-
return { error:
|
|
8035
|
+
return { error: "Not in config rendering context" };
|
|
8001
8036
|
}
|
|
8002
8037
|
// Extract data from storage
|
|
8003
8038
|
const { data } = normalizeStorage(storageJson);
|
|
8004
8039
|
// Try prerunArgs callback first
|
|
8005
|
-
const prerunArgsCallback = ctx.callbackRegistry[
|
|
8006
|
-
if (typeof prerunArgsCallback ===
|
|
8040
|
+
const prerunArgsCallback = ctx.callbackRegistry["prerunArgs"];
|
|
8041
|
+
if (typeof prerunArgsCallback === "function") {
|
|
8007
8042
|
try {
|
|
8008
8043
|
const result = prerunArgsCallback(data);
|
|
8009
8044
|
return { value: result };
|
|
@@ -8014,9 +8049,9 @@
|
|
|
8014
8049
|
}
|
|
8015
8050
|
}
|
|
8016
8051
|
// Fall back to args callback
|
|
8017
|
-
const argsCallback = ctx.callbackRegistry[
|
|
8018
|
-
if (typeof argsCallback !==
|
|
8019
|
-
return { error:
|
|
8052
|
+
const argsCallback = ctx.callbackRegistry["args"];
|
|
8053
|
+
if (typeof argsCallback !== "function") {
|
|
8054
|
+
return { error: "args callback not found (fallback from missing prerunArgs)" };
|
|
8020
8055
|
}
|
|
8021
8056
|
try {
|
|
8022
8057
|
const result = argsCallback(data);
|
|
@@ -8028,7 +8063,7 @@
|
|
|
8028
8063
|
}
|
|
8029
8064
|
}
|
|
8030
8065
|
// Register prerunArgs derivation callback
|
|
8031
|
-
tryRegisterCallback(
|
|
8066
|
+
tryRegisterCallback("__pl_prerunArgs_derive", (storageJson) => {
|
|
8032
8067
|
return derivePrerunArgsFromStorage(storageJson);
|
|
8033
8068
|
});
|
|
8034
8069
|
|
|
@@ -8060,7 +8095,7 @@
|
|
|
8060
8095
|
return createPlDataTableStateV2();
|
|
8061
8096
|
}
|
|
8062
8097
|
// v1 -> v2
|
|
8063
|
-
if (!(
|
|
8098
|
+
if (!("version" in state)) {
|
|
8064
8099
|
// Non upgradeable as sourceId calculation algorithm has changed, resetting state to default
|
|
8065
8100
|
state = createPlDataTableStateV2();
|
|
8066
8101
|
}
|
|
@@ -8176,12 +8211,12 @@
|
|
|
8176
8211
|
secondaryColumns.push(...params.labelColumns);
|
|
8177
8212
|
return {
|
|
8178
8213
|
src: {
|
|
8179
|
-
type:
|
|
8214
|
+
type: "outer",
|
|
8180
8215
|
primary: {
|
|
8181
8216
|
type: params.coreJoinType,
|
|
8182
|
-
entries: coreColumns.map((c) => ({ type:
|
|
8217
|
+
entries: coreColumns.map((c) => ({ type: "column", column: c })),
|
|
8183
8218
|
},
|
|
8184
|
-
secondary: secondaryColumns.map((c) => ({ type:
|
|
8219
|
+
secondary: secondaryColumns.map((c) => ({ type: "column", column: c })),
|
|
8185
8220
|
},
|
|
8186
8221
|
partitionFilters: params.partitionFilters,
|
|
8187
8222
|
filters: params.filters,
|
|
@@ -8190,7 +8225,7 @@
|
|
|
8190
8225
|
}
|
|
8191
8226
|
/** Check if column is hidden by default */
|
|
8192
8227
|
function isColumnOptional(spec) {
|
|
8193
|
-
return readAnnotation(spec, Annotation.Table.Visibility) ===
|
|
8228
|
+
return readAnnotation(spec, Annotation.Table.Visibility) === "optional";
|
|
8194
8229
|
}
|
|
8195
8230
|
/**
|
|
8196
8231
|
* Create p-table spec and handle given ui table state
|
|
@@ -8223,14 +8258,13 @@
|
|
|
8223
8258
|
const fullColumns = [...columns, ...fullLabelColumns];
|
|
8224
8259
|
const fullColumnsAxes = uniqueBy(fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))), (a) => canonicalizeJson(a));
|
|
8225
8260
|
const fullColumnsIds = [
|
|
8226
|
-
...fullColumnsAxes.map((a) => ({ type:
|
|
8227
|
-
...fullColumns.map((c) => ({ type:
|
|
8261
|
+
...fullColumnsAxes.map((a) => ({ type: "axis", id: a })),
|
|
8262
|
+
...fullColumns.map((c) => ({ type: "column", id: c.id })),
|
|
8228
8263
|
];
|
|
8229
8264
|
const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson(c)));
|
|
8230
8265
|
const isValidColumnId = (id) => fullColumnsIdsSet.has(canonicalizeJson(id));
|
|
8231
|
-
const coreJoinType =
|
|
8232
|
-
const partitionFilters = tableStateNormalized.pTableParams.partitionFilters
|
|
8233
|
-
.filter((f) => {
|
|
8266
|
+
const coreJoinType = "full";
|
|
8267
|
+
const partitionFilters = tableStateNormalized.pTableParams.partitionFilters.filter((f) => {
|
|
8234
8268
|
const valid = isValidColumnId(f.column);
|
|
8235
8269
|
if (!valid)
|
|
8236
8270
|
ctx.logWarn(`Partition filter ${JSON.stringify(f)} does not match provided columns, skipping`);
|
|
@@ -8264,19 +8298,19 @@
|
|
|
8264
8298
|
const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;
|
|
8265
8299
|
if (hiddenColIds)
|
|
8266
8300
|
return hiddenColIds;
|
|
8267
|
-
return columns
|
|
8268
|
-
.filter((c) => isColumnOptional(c.spec))
|
|
8269
|
-
.map((c) => c.id);
|
|
8301
|
+
return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);
|
|
8270
8302
|
})());
|
|
8271
8303
|
// Preserve linker columns
|
|
8272
|
-
columns
|
|
8273
|
-
.filter((c) => isLinkerColumn(c.spec))
|
|
8274
|
-
.forEach((c) => hiddenColumns.delete(c.id));
|
|
8304
|
+
columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));
|
|
8275
8305
|
// Preserve core columns as they change the shape of join.
|
|
8276
8306
|
const coreColumnPredicate = ops?.coreColumnPredicate;
|
|
8277
8307
|
// Filters decrease the number of result rows, sorting changes the order of result rows
|
|
8278
|
-
[
|
|
8279
|
-
.
|
|
8308
|
+
[
|
|
8309
|
+
...partitionFilters.map((f) => f.column),
|
|
8310
|
+
...filters.map((f) => f.column),
|
|
8311
|
+
...sorting.map((s) => s.column),
|
|
8312
|
+
]
|
|
8313
|
+
.filter((c) => c.type === "column")
|
|
8280
8314
|
.forEach((c) => hiddenColumns.delete(c.id));
|
|
8281
8315
|
const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));
|
|
8282
8316
|
const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);
|
|
@@ -8347,7 +8381,7 @@
|
|
|
8347
8381
|
// https://zod.dev/?id=recursive-types
|
|
8348
8382
|
// We need zod to parse error strings into these objects for keeping new UI and old blocks compatible.
|
|
8349
8383
|
const BasePlErrorLike = z.object({
|
|
8350
|
-
type: z.literal(
|
|
8384
|
+
type: z.literal("PlError"),
|
|
8351
8385
|
name: z.string(),
|
|
8352
8386
|
message: z.string(),
|
|
8353
8387
|
/** The message with all details needed for SDK developers. */
|
|
@@ -8359,7 +8393,7 @@
|
|
|
8359
8393
|
errors: z.lazy(() => ErrorLike.array()).optional(),
|
|
8360
8394
|
});
|
|
8361
8395
|
const BaseStandardErrorLike = z.object({
|
|
8362
|
-
type: z.literal(
|
|
8396
|
+
type: z.literal("StandardError"),
|
|
8363
8397
|
name: z.string(),
|
|
8364
8398
|
message: z.string(),
|
|
8365
8399
|
stack: z.string().optional(),
|
|
@@ -8405,11 +8439,11 @@
|
|
|
8405
8439
|
numbers: z.array(z.coerce.number()),
|
|
8406
8440
|
handles: z.array(ImportFileHandleSchema),
|
|
8407
8441
|
});
|
|
8408
|
-
const platforma = BlockModel.create(
|
|
8442
|
+
const platforma = BlockModel.create("Heavy")
|
|
8409
8443
|
.withArgs({ numbers: [1, 2, 3, 4], handles: [] })
|
|
8410
8444
|
.withUiState({
|
|
8411
8445
|
dataTableV2: {
|
|
8412
|
-
sourceId:
|
|
8446
|
+
sourceId: "source_1",
|
|
8413
8447
|
numRows: 200,
|
|
8414
8448
|
state: createPlDataTableStateV2(),
|
|
8415
8449
|
},
|
|
@@ -8418,66 +8452,66 @@
|
|
|
8418
8452
|
})
|
|
8419
8453
|
.argsValid((ctx) => {
|
|
8420
8454
|
if (ctx.args.numbers.length === 5) {
|
|
8421
|
-
throw new Error(
|
|
8455
|
+
throw new Error("argsValid: test error");
|
|
8422
8456
|
}
|
|
8423
8457
|
return ctx.args.numbers.length > 0;
|
|
8424
8458
|
})
|
|
8425
|
-
.output(
|
|
8426
|
-
.output(
|
|
8427
|
-
const m = ctx.outputs?.resolve(
|
|
8459
|
+
.output("numbers", (ctx) => ctx.outputs?.resolve("numbers")?.getDataAsJson())
|
|
8460
|
+
.output("progresses", (ctx) => {
|
|
8461
|
+
const m = ctx.outputs?.resolve("progresses");
|
|
8428
8462
|
const progresses = m?.mapFields((name, val) => [name, val?.getImportProgress()]);
|
|
8429
8463
|
return Object.fromEntries(progresses ?? []);
|
|
8430
8464
|
})
|
|
8431
|
-
.output(
|
|
8465
|
+
.output("ptV2Sheets", (ctx) => {
|
|
8432
8466
|
const rowCount = ctx.uiState.dataTableV2.numRows ?? 0;
|
|
8433
8467
|
const sheets = [
|
|
8434
8468
|
{
|
|
8435
8469
|
axis: {
|
|
8436
8470
|
type: ValueType.Int,
|
|
8437
|
-
name:
|
|
8471
|
+
name: "part",
|
|
8438
8472
|
annotations: {
|
|
8439
|
-
[Annotation.Label]:
|
|
8473
|
+
[Annotation.Label]: "Partitioned axis",
|
|
8440
8474
|
[Annotation.DiscreteValues]: stringifyJson([0, 1]),
|
|
8441
8475
|
},
|
|
8442
8476
|
},
|
|
8443
8477
|
options: [
|
|
8444
|
-
{ value: 0, label:
|
|
8445
|
-
{ value: 1, label:
|
|
8478
|
+
{ value: 0, label: "Partition 1" },
|
|
8479
|
+
{ value: 1, label: "Partition 2" },
|
|
8446
8480
|
],
|
|
8447
8481
|
},
|
|
8448
8482
|
];
|
|
8449
8483
|
return rowCount > 0 ? sheets : [];
|
|
8450
8484
|
})
|
|
8451
|
-
.outputWithStatus(
|
|
8485
|
+
.outputWithStatus("ptV2", (ctx) => {
|
|
8452
8486
|
const rowCount = ctx.uiState.dataTableV2.numRows ?? 0;
|
|
8453
8487
|
const makePartitionId = (rowCount, i) => Math.floor((2 * i) / (rowCount + 1));
|
|
8454
8488
|
const columns = [
|
|
8455
8489
|
{
|
|
8456
|
-
id:
|
|
8490
|
+
id: "column1",
|
|
8457
8491
|
spec: {
|
|
8458
|
-
kind:
|
|
8492
|
+
kind: "PColumn",
|
|
8459
8493
|
valueType: ValueType.String,
|
|
8460
|
-
name:
|
|
8494
|
+
name: "example",
|
|
8461
8495
|
annotations: {
|
|
8462
|
-
[Annotation.Label]:
|
|
8463
|
-
[Annotation.DiscreteValues]: stringifyJson([
|
|
8496
|
+
[Annotation.Label]: "String column",
|
|
8497
|
+
[Annotation.DiscreteValues]: stringifyJson(["up", "down"]),
|
|
8464
8498
|
[Annotation.Table.OrderPriority]: stringifyJson(101),
|
|
8465
|
-
[Annotation.Description]:
|
|
8499
|
+
[Annotation.Description]: "String column description",
|
|
8466
8500
|
},
|
|
8467
8501
|
axesSpec: [
|
|
8468
8502
|
{
|
|
8469
8503
|
type: ValueType.Int,
|
|
8470
|
-
name:
|
|
8504
|
+
name: "part",
|
|
8471
8505
|
annotations: {
|
|
8472
|
-
[Annotation.Label]:
|
|
8506
|
+
[Annotation.Label]: "Partitioned axis",
|
|
8473
8507
|
[Annotation.DiscreteValues]: stringifyJson([0, 1]),
|
|
8474
8508
|
},
|
|
8475
8509
|
},
|
|
8476
8510
|
{
|
|
8477
8511
|
type: ValueType.Int,
|
|
8478
|
-
name:
|
|
8512
|
+
name: "index",
|
|
8479
8513
|
annotations: {
|
|
8480
|
-
[Annotation.Label]:
|
|
8514
|
+
[Annotation.Label]: "Int axis",
|
|
8481
8515
|
},
|
|
8482
8516
|
},
|
|
8483
8517
|
],
|
|
@@ -8491,31 +8525,31 @@
|
|
|
8491
8525
|
}),
|
|
8492
8526
|
},
|
|
8493
8527
|
{
|
|
8494
|
-
id:
|
|
8528
|
+
id: "column2",
|
|
8495
8529
|
spec: {
|
|
8496
|
-
kind:
|
|
8530
|
+
kind: "PColumn",
|
|
8497
8531
|
valueType: ValueType.Float,
|
|
8498
|
-
name:
|
|
8532
|
+
name: "value",
|
|
8499
8533
|
annotations: {
|
|
8500
|
-
[Annotation.Label]:
|
|
8501
|
-
[Annotation.Table.Visibility]:
|
|
8534
|
+
[Annotation.Label]: "Float column",
|
|
8535
|
+
[Annotation.Table.Visibility]: "optional",
|
|
8502
8536
|
[Annotation.Table.OrderPriority]: stringifyJson(100),
|
|
8503
|
-
[Annotation.Description]:
|
|
8537
|
+
[Annotation.Description]: "Float column description",
|
|
8504
8538
|
},
|
|
8505
8539
|
axesSpec: [
|
|
8506
8540
|
{
|
|
8507
8541
|
type: ValueType.Int,
|
|
8508
|
-
name:
|
|
8542
|
+
name: "part",
|
|
8509
8543
|
annotations: {
|
|
8510
|
-
[Annotation.Label]:
|
|
8544
|
+
[Annotation.Label]: "Partitioned axis",
|
|
8511
8545
|
[Annotation.DiscreteValues]: stringifyJson([0, 1]),
|
|
8512
8546
|
},
|
|
8513
8547
|
},
|
|
8514
8548
|
{
|
|
8515
8549
|
type: ValueType.Int,
|
|
8516
|
-
name:
|
|
8550
|
+
name: "index",
|
|
8517
8551
|
annotations: {
|
|
8518
|
-
[Annotation.Label]:
|
|
8552
|
+
[Annotation.Label]: "Int axis",
|
|
8519
8553
|
},
|
|
8520
8554
|
},
|
|
8521
8555
|
],
|
|
@@ -8529,20 +8563,20 @@
|
|
|
8529
8563
|
}),
|
|
8530
8564
|
},
|
|
8531
8565
|
{
|
|
8532
|
-
id:
|
|
8566
|
+
id: "labelColumn",
|
|
8533
8567
|
spec: {
|
|
8534
|
-
kind:
|
|
8568
|
+
kind: "PColumn",
|
|
8535
8569
|
valueType: ValueType.Int,
|
|
8536
8570
|
name: PColumnName.Label,
|
|
8537
8571
|
annotations: {
|
|
8538
|
-
[Annotation.Label]:
|
|
8572
|
+
[Annotation.Label]: "Int axis labels",
|
|
8539
8573
|
},
|
|
8540
8574
|
axesSpec: [
|
|
8541
8575
|
{
|
|
8542
8576
|
type: ValueType.Int,
|
|
8543
|
-
name:
|
|
8577
|
+
name: "index",
|
|
8544
8578
|
annotations: {
|
|
8545
|
-
[Annotation.Label]:
|
|
8579
|
+
[Annotation.Label]: "Int axis",
|
|
8546
8580
|
},
|
|
8547
8581
|
},
|
|
8548
8582
|
],
|
|
@@ -8556,29 +8590,29 @@
|
|
|
8556
8590
|
}),
|
|
8557
8591
|
},
|
|
8558
8592
|
{
|
|
8559
|
-
id:
|
|
8593
|
+
id: "linkerColumn",
|
|
8560
8594
|
spec: {
|
|
8561
|
-
kind:
|
|
8595
|
+
kind: "PColumn",
|
|
8562
8596
|
valueType: ValueType.Int,
|
|
8563
|
-
name:
|
|
8597
|
+
name: "linker",
|
|
8564
8598
|
annotations: {
|
|
8565
|
-
[Annotation.Label]:
|
|
8599
|
+
[Annotation.Label]: "Index axis linker",
|
|
8566
8600
|
[Annotation.IsLinkerColumn]: stringifyJson(true),
|
|
8567
|
-
[Annotation.Table.Visibility]:
|
|
8601
|
+
[Annotation.Table.Visibility]: "hidden",
|
|
8568
8602
|
},
|
|
8569
8603
|
axesSpec: [
|
|
8570
8604
|
{
|
|
8571
8605
|
type: ValueType.Int,
|
|
8572
|
-
name:
|
|
8606
|
+
name: "index",
|
|
8573
8607
|
annotations: {
|
|
8574
|
-
[Annotation.Label]:
|
|
8608
|
+
[Annotation.Label]: "Int axis",
|
|
8575
8609
|
},
|
|
8576
8610
|
},
|
|
8577
8611
|
{
|
|
8578
8612
|
type: ValueType.Int,
|
|
8579
|
-
name:
|
|
8613
|
+
name: "linkedIndex",
|
|
8580
8614
|
annotations: {
|
|
8581
|
-
[Annotation.Label]:
|
|
8615
|
+
[Annotation.Label]: "Linked int axis",
|
|
8582
8616
|
},
|
|
8583
8617
|
},
|
|
8584
8618
|
],
|
|
@@ -8596,20 +8630,20 @@
|
|
|
8596
8630
|
columns.push({
|
|
8597
8631
|
id: `alphabeticalColumn${j}`,
|
|
8598
8632
|
spec: {
|
|
8599
|
-
kind:
|
|
8633
|
+
kind: "PColumn",
|
|
8600
8634
|
valueType: ValueType.String,
|
|
8601
|
-
name:
|
|
8635
|
+
name: "value",
|
|
8602
8636
|
annotations: {
|
|
8603
8637
|
[Annotation.Label]: `Alphabetical column ${j}`,
|
|
8604
|
-
[Annotation.Table.Visibility]:
|
|
8638
|
+
[Annotation.Table.Visibility]: "optional",
|
|
8605
8639
|
[Annotation.Table.OrderPriority]: stringifyJson(10 - j),
|
|
8606
8640
|
},
|
|
8607
8641
|
axesSpec: [
|
|
8608
8642
|
{
|
|
8609
8643
|
type: ValueType.Int,
|
|
8610
|
-
name:
|
|
8644
|
+
name: "linkedIndex",
|
|
8611
8645
|
annotations: {
|
|
8612
|
-
[Annotation.Label]:
|
|
8646
|
+
[Annotation.Label]: "Linked int axis",
|
|
8613
8647
|
},
|
|
8614
8648
|
},
|
|
8615
8649
|
],
|
|
@@ -8627,67 +8661,63 @@
|
|
|
8627
8661
|
})
|
|
8628
8662
|
.title((ctx) => {
|
|
8629
8663
|
if (ctx.args.numbers.length === 5) {
|
|
8630
|
-
throw new Error(
|
|
8664
|
+
throw new Error("block title: test error");
|
|
8631
8665
|
}
|
|
8632
|
-
return
|
|
8666
|
+
return "Ui Examples";
|
|
8633
8667
|
})
|
|
8634
8668
|
.sections((ctx) => {
|
|
8635
8669
|
const dynamicSections = (ctx.uiState.dynamicSections ?? []).map((it) => ({
|
|
8636
|
-
type:
|
|
8670
|
+
type: "link",
|
|
8637
8671
|
href: `/section?id=${it.id}`,
|
|
8638
8672
|
label: it.label,
|
|
8639
8673
|
}));
|
|
8640
|
-
if (dynamicSections.some((it) => it.label ===
|
|
8641
|
-
throw new Error(
|
|
8674
|
+
if (dynamicSections.some((it) => it.label === "Error")) {
|
|
8675
|
+
throw new Error("sections: test error");
|
|
8642
8676
|
}
|
|
8643
8677
|
return [
|
|
8644
|
-
{ type:
|
|
8645
|
-
{ type:
|
|
8646
|
-
{ type:
|
|
8647
|
-
{ type:
|
|
8648
|
-
{ type:
|
|
8649
|
-
{ type:
|
|
8650
|
-
{ type:
|
|
8651
|
-
{ type:
|
|
8652
|
-
{ type:
|
|
8653
|
-
{ type:
|
|
8654
|
-
{ type:
|
|
8655
|
-
{ type:
|
|
8656
|
-
{ type:
|
|
8657
|
-
{ type:
|
|
8658
|
-
{ type:
|
|
8659
|
-
{ type:
|
|
8660
|
-
{ type:
|
|
8661
|
-
{ type:
|
|
8662
|
-
{ type:
|
|
8663
|
-
{ type:
|
|
8664
|
-
{ type:
|
|
8665
|
-
{ type:
|
|
8666
|
-
{ type:
|
|
8667
|
-
{ type:
|
|
8668
|
-
{ type:
|
|
8669
|
-
{ type:
|
|
8670
|
-
{ type:
|
|
8671
|
-
{ type:
|
|
8672
|
-
{ type:
|
|
8673
|
-
{ type:
|
|
8674
|
-
{ type:
|
|
8675
|
-
{ type:
|
|
8676
|
-
{ type:
|
|
8677
|
-
{ type:
|
|
8678
|
-
{ type:
|
|
8678
|
+
{ type: "link", href: "/loaders", label: "Loaders" },
|
|
8679
|
+
{ type: "link", href: "/", label: "Icons/Masks" },
|
|
8680
|
+
{ type: "link", href: "/state", label: "State" },
|
|
8681
|
+
{ type: "link", href: "/layout", label: "Layout" },
|
|
8682
|
+
{ type: "link", href: "/form-components", label: "Form Components" },
|
|
8683
|
+
{ type: "link", href: "/log-view", label: "PlLogView" },
|
|
8684
|
+
{ type: "link", href: "/modals", label: "Modals" },
|
|
8685
|
+
{ type: "link", href: "/select-files", label: "Select Files" },
|
|
8686
|
+
{ type: "link", href: "/inject-env", label: "Inject env" },
|
|
8687
|
+
{ type: "link", href: "/use-watch-fetch", label: "useWatchFetch" },
|
|
8688
|
+
{ type: "link", href: "/typography", label: "Typography" },
|
|
8689
|
+
{ type: "link", href: "/ag-grid-vue", label: "AgGridVue" },
|
|
8690
|
+
{ type: "link", href: "/ag-grid-vue-with-builder", label: "AgGridVue with builder" },
|
|
8691
|
+
{ type: "link", href: "/pl-annotations", label: "PlAnnotations" },
|
|
8692
|
+
{ type: "link", href: "/pl-ag-data-table-v2", label: "PlAgDataTableV2" },
|
|
8693
|
+
{ type: "link", href: "/pl-splash-page", label: "PlSplashPage" },
|
|
8694
|
+
{ type: "link", href: "/pl-file-input-page", label: "PlFileInputPage" },
|
|
8695
|
+
{ type: "link", href: "/pl-number-field-page", label: "PlNumberFieldPage" },
|
|
8696
|
+
{ type: "link", href: "/pl-error-boundary-page", label: "PlErrorBoundaryPage" },
|
|
8697
|
+
{ type: "link", href: "/pl-element-list-page", label: "PlElementList" },
|
|
8698
|
+
{ type: "link", href: "/text-fields", label: "PlTextField" },
|
|
8699
|
+
{ type: "link", href: "/tabs", label: "PlTabs" },
|
|
8700
|
+
{ type: "link", href: "/pl-autocomplete", label: "PlAutocomplete" },
|
|
8701
|
+
{ type: "link", href: "/radio", label: "PlRadio" },
|
|
8702
|
+
{ type: "link", href: "/stacked-bar", label: "PlChartStackedBar" },
|
|
8703
|
+
{ type: "link", href: "/histogram", label: "PlChartHistogram" },
|
|
8704
|
+
{ type: "link", href: "/buttons", label: "ButtonsPage" },
|
|
8705
|
+
{ type: "link", href: "/errors", label: "Errors" },
|
|
8706
|
+
{ type: "link", href: "/downloads", label: "Downloads" },
|
|
8707
|
+
{ type: "link", href: "/notifications", label: "Notifications" },
|
|
8708
|
+
{ type: "link", href: "/drafts", label: "Drafts" },
|
|
8709
|
+
{ type: "link", href: "/pl-autocomplete", label: "PlAutocomplete" },
|
|
8710
|
+
{ type: "link", href: "/pl-autocomplete-multi", label: "PlAutocompleteMulti" },
|
|
8711
|
+
{ type: "link", href: "/radio", label: "PlRadio" },
|
|
8712
|
+
{ type: "link", href: "/advanced-filter", label: "PlAdvancedFilter" },
|
|
8679
8713
|
...(dynamicSections.length
|
|
8680
|
-
? [
|
|
8681
|
-
{ type: 'delimiter' },
|
|
8682
|
-
...dynamicSections,
|
|
8683
|
-
{ type: 'delimiter' },
|
|
8684
|
-
]
|
|
8714
|
+
? [{ type: "delimiter" }, ...dynamicSections, { type: "delimiter" }]
|
|
8685
8715
|
: []),
|
|
8686
8716
|
{
|
|
8687
|
-
type:
|
|
8688
|
-
href:
|
|
8689
|
-
appearance:
|
|
8690
|
-
label:
|
|
8717
|
+
type: "link",
|
|
8718
|
+
href: "/add-section",
|
|
8719
|
+
appearance: "add-section",
|
|
8720
|
+
label: "New Dynamic section",
|
|
8691
8721
|
},
|
|
8692
8722
|
];
|
|
8693
8723
|
})
|