@platforma-open/milaboratories.sequence-embeddings 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -27,10 +27,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  * prep). Wired so far: ESM-2, CurrAb, VHHBERT, H3BERTa and TCR-BERT (all HF
28
28
  * checkpoints via the shared `AutoModel` loader), PeptideCLM-2 (HF custom model via
29
29
  * trust_remote_code) and AbLang2 (the `ablang2` pip model with asset-shipped
30
- * weights). Input prep per model: AA as-is (ESM-2/CurrAb/VHHBERT/AbLang2), CDR3
31
- * flank-trim (H3BERTa, `aa-cdr3-trimmed`), space-separated residues (TCR-BERT,
32
- * `aa-spaced`), or AA→SMILES (PeptideCLM-2, `smiles`) all applied in the Python
33
- * step. Only SCEPTR (pass 2) remains: it needs paired V-gene + CDR assembly the
30
+ * weights). Input prep per model: AA as-is (ESM-2/CurrAb/AbLang2), CDR3
31
+ * flank-trim (H3BERTa, `aa-cdr3-trimmed`), space-separated residues (TCR-BERT and
32
+ * VHHBERT, `aa-spaced` their tokenizers need one token per residue), or AA→SMILES
33
+ * (PeptideCLM-2, `smiles`) — all applied in the Python step. Only SCEPTR (pass 2) remains: it needs paired V-gene + CDR assembly the
34
34
  * block does not yet gather. Add a model's id here as its asset/runenv/routing
35
35
  * lands — the UI and matrix pick it up automatically.
36
36
  */
@@ -47,7 +47,6 @@ const EMBEDDING_MODELS = {
47
47
  esm2: {
48
48
  id: "esm2",
49
49
  label: "ESM-2 (universal)",
50
- inputKind: "aa",
51
50
  receptors: [
52
51
  "IG",
53
52
  "TCRAB",
@@ -60,92 +59,61 @@ const EMBEDDING_MODELS = {
60
59
  "Fv",
61
60
  "scFv"
62
61
  ],
63
- dim: "varies",
64
- asset: true,
65
- pass: 1,
66
62
  priority: 0
67
63
  },
68
64
  currab: {
69
65
  id: "currab",
70
66
  label: "CurrAb (antibody)",
71
- inputKind: "aa",
72
67
  receptors: ["IG"],
73
68
  features: ["VDJRegion", "Fv"],
74
- dim: 1280,
75
- asset: true,
76
- pass: 1,
77
69
  priority: 50
78
70
  },
79
71
  ablang2: {
80
72
  id: "ablang2",
81
73
  label: "AbLang2 (antibody)",
82
- inputKind: "aa",
83
74
  receptors: ["IG"],
84
75
  features: ["VDJRegion", "Fv"],
85
- dim: 480,
86
- asset: false,
87
- pass: 1,
88
76
  priority: 40
89
77
  },
90
78
  vhhbert: {
91
79
  id: "vhhbert",
92
80
  label: "VHHBERT (nanobody)",
93
- inputKind: "aa",
94
81
  receptors: ["IG"],
95
82
  features: ["VDJRegion"],
96
83
  heavyOnly: true,
97
- dim: 768,
98
- asset: true,
99
- pass: 1,
100
84
  priority: 45
101
85
  },
102
86
  h3berta: {
103
87
  id: "h3berta",
104
88
  label: "H3BERTa (CDR-H3)",
105
- inputKind: "aa-cdr3-trimmed",
106
89
  receptors: ["IG"],
107
90
  features: ["CDR3"],
108
91
  heavyOnly: true,
109
- dim: 768,
110
- asset: true,
111
- pass: 1,
112
92
  priority: 50
113
93
  },
114
94
  "tcr-bert": {
115
95
  id: "tcr-bert",
116
96
  label: "TCR-BERT (CDR3)",
117
- inputKind: "aa-spaced",
118
97
  receptors: ["TCRAB"],
119
98
  features: ["CDR3"],
120
- dim: 768,
121
- asset: true,
122
- pass: 1,
123
99
  priority: 50
124
100
  },
125
101
  peptideclm2: {
126
102
  id: "peptideclm2",
127
103
  label: "PeptideCLM-2 (peptide)",
128
- inputKind: "smiles",
129
104
  receptors: [
130
105
  "IG",
131
106
  "TCRAB",
132
107
  "TCRGD"
133
108
  ],
134
109
  features: ["peptide"],
135
- dim: 1024,
136
- asset: true,
137
- pass: 1,
138
110
  priority: 50
139
111
  },
140
112
  sceptr: {
141
113
  id: "sceptr",
142
114
  label: "SCEPTR (paired αβ)",
143
- inputKind: "paired-structured",
144
115
  receptors: ["TCRAB"],
145
116
  features: ["VDJRegion", "Fv"],
146
- dim: 64,
147
- asset: false,
148
- pass: 2,
149
117
  priority: 60
150
118
  }
151
119
  };
@@ -162,14 +130,14 @@ function isCompatible(feature, isHeavy, receptor, model) {
162
130
  return modelSupports(EMBEDDING_MODELS[model], feature, isHeavy, receptor);
163
131
  }
164
132
  //#endregion
165
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/plugin_handle.js
133
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/plugin_handle.js
166
134
  const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
167
135
  /** Construct the output key for a plugin output in the block outputs map. */
168
136
  function pluginOutputKey(handle, outputKey) {
169
137
  return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
170
138
  }
171
139
  //#endregion
172
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/block_storage.js
140
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage.js
173
141
  /**
174
142
  * Discriminator key for BlockStorage format detection.
175
143
  * This unique hash-based key identifies data as BlockStorage vs legacy formats.
@@ -411,7 +379,7 @@ function getPluginData(rawStorage, handle) {
411
379
  return pluginEntry.__data;
412
380
  }
413
381
  //#endregion
414
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/block_migrations.js
382
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_migrations.js
415
383
  /** Create a DataVersioned wrapper with correct shape */
416
384
  function makeVersionedData(version, data) {
417
385
  return {
@@ -906,7 +874,7 @@ var DataModel = class DataModel {
906
874
  }
907
875
  };
908
876
  //#endregion
909
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/internal.js
877
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/internal.js
910
878
  /** Utility code helping to identify whether the code is running in actual UI environment */
911
879
  function isInUI() {
912
880
  return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
@@ -976,7 +944,7 @@ function registerFutureAwait(handle, onResolve) {
976
944
  futureResolves.get(handle).push(onResolve);
977
945
  }
978
946
  //#endregion
979
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
947
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
980
948
  /**
981
949
  * All facade callback names as constants.
982
950
  * These are the source of truth - the interface is derived from these.
@@ -1011,7 +979,7 @@ function registerFacadeCallbacks(callbacks) {
1011
979
  for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
1012
980
  }
1013
981
  //#endregion
1014
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/future.js
982
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/future.js
1015
983
  var FutureRef = class FutureRef {
1016
984
  handle;
1017
985
  postProcess;
@@ -4592,12 +4560,12 @@ objectType({
4592
4560
  to: numberType().min(1)
4593
4561
  });
4594
4562
  //#endregion
4595
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/util.js
4563
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/util.js
4596
4564
  function assertNever(x) {
4597
4565
  throw new Error("Unexpected object: " + x);
4598
4566
  }
4599
4567
  //#endregion
4600
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
4568
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
4601
4569
  /**
4602
4570
  * Type guard function that checks if the given value is a valid DataInfo.
4603
4571
  *
@@ -4788,7 +4756,7 @@ function entriesToDataInfo(dataInfoEntries) {
4788
4756
  }
4789
4757
  }
4790
4758
  //#endregion
4791
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/errors.js
4759
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/errors.js
4792
4760
  var ServiceError = class extends Error {
4793
4761
  name = "ServiceError";
4794
4762
  };
@@ -4812,7 +4780,7 @@ function ensureError(value) {
4812
4780
  return new Error(stringifyValue(value));
4813
4781
  }
4814
4782
  //#endregion
4815
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/json.js
4783
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/json.js
4816
4784
  var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
4817
4785
  module.exports = function serialize(object) {
4818
4786
  if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
@@ -4837,8 +4805,15 @@ function canonicalizeJson(value) {
4837
4805
  function parseJson(value) {
4838
4806
  return JSON.parse(value);
4839
4807
  }
4808
+ function parseJsonSafely(value, fallback) {
4809
+ try {
4810
+ return JSON.parse(value);
4811
+ } catch {
4812
+ return fallback;
4813
+ }
4814
+ }
4840
4815
  //#endregion
4841
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4816
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4842
4817
  function readMetadata(metadata, key) {
4843
4818
  return metadata?.[key];
4844
4819
  }
@@ -5127,7 +5102,7 @@ function matchAxisId(query, target) {
5127
5102
  return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
5128
5103
  }
5129
5104
  //#endregion
5130
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
5105
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
5131
5106
  /**
5132
5107
  * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.
5133
5108
  *
@@ -5177,20 +5152,23 @@ function traverseQuerySpec(query, visitor) {
5177
5152
  secondary: query.secondary.map(traverseEntry)
5178
5153
  };
5179
5154
  break;
5180
- case "linkerJoin":
5155
+ case "linkerJoin": {
5156
+ const linker = "type" in query.linker ? query.linker : {
5157
+ type: "column",
5158
+ column: query.linker.column
5159
+ };
5181
5160
  result = {
5182
5161
  ...query,
5183
- linker: {
5184
- ...query.linker,
5185
- column: visitor.column(query.linker.column)
5186
- },
5162
+ linker: traverseQuerySpec(linker, visitor),
5187
5163
  secondary: query.secondary.map(traverseEntry)
5188
5164
  };
5189
5165
  break;
5166
+ }
5190
5167
  case "filter":
5191
5168
  case "sort":
5192
5169
  case "sliceAxes":
5193
5170
  case "transformColumns":
5171
+ case "specOverride":
5194
5172
  result = {
5195
5173
  ...query,
5196
5174
  input: traverseQuerySpec(query.input, visitor)
@@ -5201,19 +5179,19 @@ function traverseQuerySpec(query, visitor) {
5201
5179
  return visitor.node ? visitor.node(result) : result;
5202
5180
  }
5203
5181
  /** Recursively maps all column references in a SpecQuery tree. */
5204
- function mapSpecQueryColumns(query, cb) {
5205
- return traverseQuerySpec(query, { column: cb });
5182
+ function mapSpecQueryColumns(query, visitor) {
5183
+ return traverseQuerySpec(query, visitor);
5206
5184
  }
5207
5185
  //#endregion
5208
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
5186
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
5209
5187
  function mapPTableDef(def, cb) {
5210
5188
  return {
5211
5189
  ...def,
5212
5190
  src: mapJoinEntry(def.src, cb)
5213
5191
  };
5214
5192
  }
5215
- function mapPTableDefV2(def, cb) {
5216
- return { query: mapSpecQueryColumns(def.query, cb) };
5193
+ function mapPTableDefV2(def, visitor) {
5194
+ return { query: mapSpecQueryColumns(def.query, visitor) };
5217
5195
  }
5218
5196
  function mapJoinEntry(entry, cb) {
5219
5197
  switch (entry.type) {
@@ -5248,17 +5226,367 @@ function mapJoinEntry(entry, cb) {
5248
5226
  }
5249
5227
  }
5250
5228
  //#endregion
5251
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
5229
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
5230
+ function stringifyColumnFilteredId(key) {
5231
+ return canonicalizeJson(createColumnFilteredKey(key));
5232
+ }
5233
+ function isColumnFilteredKey(obj) {
5234
+ return typeof obj === "object" && obj !== null && "__isFiltered" in obj;
5235
+ }
5236
+ function createColumnFilteredKey(props) {
5237
+ const axisFilters = props.axisFilters.toSorted((a, b) => a[0] - b[0]);
5238
+ return {
5239
+ __isFiltered: true,
5240
+ source: props.source,
5241
+ axisFilters
5242
+ };
5243
+ }
5244
+ /**
5245
+ * Drop the axes pinned by `axisFilters` from a {@link PColumnSpec}'s
5246
+ * `axesSpec`. Indices are positional against `spec.axesSpec`. Returns `spec`
5247
+ * unchanged when there are no filters.
5248
+ *
5249
+ * Single source of the Filtered-layer spec math — shared by
5250
+ * `reconstructSpecFromId` (host, id-walking) and `ColumnFilteredRecipe.getSpec`
5251
+ * (sandbox, recipe-graph walking).
5252
+ */
5253
+ function applyAxisFilters(spec, axisFilters) {
5254
+ if (axisFilters.length === 0) return spec;
5255
+ const fixed = new Set(axisFilters.map(([i]) => i));
5256
+ return {
5257
+ ...spec,
5258
+ axesSpec: spec.axesSpec.filter((_, i) => !fixed.has(i))
5259
+ };
5260
+ }
5261
+ //#endregion
5262
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
5263
+ function isPObjectId(value) {
5264
+ if (typeof value !== "string") return false;
5265
+ return isPObjectKey(parseJsonSafely(value));
5266
+ }
5267
+ function isPObjectKey(value) {
5268
+ return isLocalPObjectKey(value) || isGlobalPObjectKey(value);
5269
+ }
5270
+ function createPObjectId(obj) {
5271
+ if (isLocalPObjectKey(obj)) return createLocalPObjectId(obj.resolvePath, obj.name);
5272
+ if (isGlobalPObjectKey(obj)) return createGlobalPObjectId(obj.blockId, obj.name);
5273
+ throw new Error(`createPObjectId: unrecognized object key structure: ${JSON.stringify(obj)}`);
5274
+ }
5275
+ function createLocalPObjectId(resolvePath, name) {
5276
+ return canonicalizeJson({
5277
+ resolvePath,
5278
+ name
5279
+ });
5280
+ }
5281
+ function isLocalPObjectKey(value) {
5282
+ if (typeof value !== "object" || value === null) return false;
5283
+ const v = value;
5284
+ return Array.isArray(v.resolvePath) && typeof v.name === "string";
5285
+ }
5286
+ function createGlobalPObjectId(blockId, exportName) {
5287
+ return canonicalizeJson({
5288
+ __isRef: true,
5289
+ blockId,
5290
+ name: exportName
5291
+ });
5292
+ }
5293
+ function isGlobalPObjectKey(value) {
5294
+ if (typeof value !== "object" || value === null) return false;
5295
+ return "__isRef" in value && "blockId" in value && "name" in value;
5296
+ }
5297
+ function isPObject(obj) {
5298
+ return typeof obj === "object" && obj !== null && "id" in obj && "spec" in obj && "data" in obj;
5299
+ }
5300
+ function isPColumn(obj) {
5301
+ return isPObject(obj) && isPColumnSpec(obj.spec);
5302
+ }
5303
+ function isPColumnSpec(spec) {
5304
+ return spec.kind === "PColumn";
5305
+ }
5306
+ function ensurePColumn(obj) {
5307
+ if (!isPColumn(obj)) throw new Error(`not a PColumn (kind = ${obj.spec.kind})`);
5308
+ return obj;
5309
+ }
5310
+ function mapPObjectData(pObj, cb) {
5311
+ return pObj === void 0 ? void 0 : {
5312
+ ...pObj,
5313
+ data: cb(pObj.data)
5314
+ };
5315
+ }
5316
+ function extractAllColumns(entry) {
5317
+ const columns = /* @__PURE__ */ new Map();
5318
+ const addAllColumns = (entry) => {
5319
+ switch (entry.type) {
5320
+ case "column":
5321
+ columns.set(entry.column.id, entry.column);
5322
+ return;
5323
+ case "slicedColumn":
5324
+ columns.set(entry.column.id, entry.column);
5325
+ return;
5326
+ case "artificialColumn":
5327
+ columns.set(entry.column.id, entry.column);
5328
+ return;
5329
+ case "inlineColumn": return;
5330
+ case "full":
5331
+ case "inner":
5332
+ for (const e of entry.entries) addAllColumns(e);
5333
+ return;
5334
+ case "outer":
5335
+ addAllColumns(entry.primary);
5336
+ for (const e of entry.secondary) addAllColumns(e);
5337
+ return;
5338
+ default: assertNever(entry);
5339
+ }
5340
+ };
5341
+ addAllColumns(entry);
5342
+ return [...columns.values()];
5343
+ }
5344
+ Array.isArray;
5345
+ //#endregion
5346
+ //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.4/node_modules/@milaboratories/helpers/dist/error.js
5347
+ function throwError(v) {
5348
+ if (typeof v === "string") throw new Error(v);
5349
+ else throw v;
5350
+ }
5351
+ //#endregion
5352
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
5353
+ function isColumnDiscoveredKey(obj) {
5354
+ return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
5355
+ }
5356
+ function distillColumnDiscoveredKey(props) {
5357
+ return {
5358
+ __isDiscovered: true,
5359
+ column: props.column,
5360
+ path: Array.isArray(props.path) && props.path.length > 0 ? props.path : void 0,
5361
+ columnQualifications: Array.isArray(props.columnQualifications) && props.columnQualifications.length > 0 ? props.columnQualifications : void 0,
5362
+ queriesQualifications: props.queriesQualifications && Object.keys(props.queriesQualifications).length > 0 ? props.queriesQualifications : void 0
5363
+ };
5364
+ }
5365
+ function stringifyColumnDiscoveredId(id) {
5366
+ return canonicalizeJson(distillColumnDiscoveredKey({
5367
+ __isDiscovered: true,
5368
+ ...id
5369
+ }));
5370
+ }
5371
+ //#endregion
5372
+ //#region ../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isFunction.mjs
5373
+ /**
5374
+ * Checks if `value` is a function.
5375
+ *
5376
+ * @param {any} value The value to check.
5377
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
5378
+ *
5379
+ * @example
5380
+ * isFunction(Array.prototype.slice); // true
5381
+ * isFunction(async function () {}); // true
5382
+ * isFunction(function* () {}); // true
5383
+ * isFunction(Proxy); // true
5384
+ * isFunction(Int8Array); // true
5385
+ */
5386
+ function isFunction(value) {
5387
+ return typeof value === "function";
5388
+ }
5389
+ //#endregion
5390
+ //#region ../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isNil.mjs
5391
+ /**
5392
+ * Checks if a given value is null or undefined.
5393
+ *
5394
+ * This function tests whether the provided value is either `null` or `undefined`.
5395
+ * It returns `true` if the value is `null` or `undefined`, and `false` otherwise.
5396
+ *
5397
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `null` or `undefined`.
5398
+ *
5399
+ * @param {unknown} x - The value to test for null or undefined.
5400
+ * @returns {boolean} `true` if the value is null or undefined, `false` otherwise.
5401
+ *
5402
+ * @example
5403
+ * const value1 = null;
5404
+ * const value2 = undefined;
5405
+ * const value3 = 42;
5406
+ * const result1 = isNil(value1); // true
5407
+ * const result2 = isNil(value2); // true
5408
+ * const result3 = isNil(value3); // false
5409
+ */
5410
+ function isNil(x) {
5411
+ return x == null;
5412
+ }
5413
+ //#endregion
5414
+ //#region ../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isString.mjs
5415
+ /**
5416
+ * Checks if a given value is string.
5417
+ *
5418
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `string`.
5419
+ *
5420
+ * @param {unknown} value The value to check if it is string.
5421
+ * @returns {value is string} Returns `true` if `value` is a string, else `false`.
5422
+ *
5423
+ * @example
5424
+ * const value1 = 'abc';
5425
+ * const value2 = 123;
5426
+ * const value3 = true;
5427
+ *
5428
+ * console.log(isString(value1)); // true
5429
+ * console.log(isString(value2)); // false
5430
+ * console.log(isString(value3)); // false
5431
+ */
5432
+ function isString(value) {
5433
+ return typeof value === "string";
5434
+ }
5435
+ //#endregion
5436
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
5252
5437
  /**
5253
- * Canonically serializes a {@link UniversalPColumnId} to a string.
5254
- * @param id - The column identifier to serialize
5255
- * @returns The canonically serialized string
5438
+ * Canonically serializes a column key to a branded string id. Accepts both
5439
+ * the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
5440
+ * (anchored / old filtered object form).
5256
5441
  */
5257
5442
  function stringifyColumnId(id) {
5258
- return (0, import_canonicalize.default)(id);
5443
+ return canonicalizeJson(id);
5444
+ }
5445
+ function parseColumnIdSafely(str, fallback = void 0) {
5446
+ try {
5447
+ return JSON.parse(str);
5448
+ } catch {
5449
+ return fallback;
5450
+ }
5451
+ }
5452
+ /**
5453
+ * Walk a rich column id down to its terminal leaf {@link PObjectId}.
5454
+ */
5455
+ function extractPObjectId(id) {
5456
+ if (isString(id)) {
5457
+ if (isPObjectId(id)) return id;
5458
+ return extractPObjectId(parseColumnIdSafely(id) ?? throwError(`extractPObjectId: id "${id}" is not a valid canonical column id`));
5459
+ }
5460
+ if (isPObjectKey(id)) return createPObjectId(id);
5461
+ if (isColumnFilteredKey(id)) return extractPObjectId(id.source);
5462
+ if (isColumnOverriddenKey(id)) return extractPObjectId(id.source);
5463
+ if (isColumnDiscoveredKey(id)) return extractPObjectId(id.column);
5464
+ throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
5465
+ }
5466
+ //#endregion
5467
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5468
+ function isColumnOverriddenKey(obj) {
5469
+ return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
5470
+ }
5471
+ function distillColumnOverriddenKey(props) {
5472
+ return {
5473
+ __isOverridden: true,
5474
+ source: props.source,
5475
+ specOverrides: props.specOverrides
5476
+ };
5477
+ }
5478
+ function createColumnOverriddenId(props) {
5479
+ return stringifyColumnOverriddenId(createColumnOverriddenKey(props));
5480
+ }
5481
+ function createColumnOverriddenKey(props) {
5482
+ const { source, specOverrides } = props;
5483
+ const unwrapped = unwrapOverrides(source);
5484
+ return {
5485
+ __isOverridden: true,
5486
+ source: unwrapped ? unwrapped.source : source,
5487
+ specOverrides: unwrapped ? mergeSpecOverrides(unwrapped.specOverrides, specOverrides) : specOverrides
5488
+ };
5489
+ }
5490
+ function stringifyColumnOverriddenId(id) {
5491
+ return canonicalizeJson(distillColumnOverriddenKey(id));
5492
+ }
5493
+ /**
5494
+ * Peel one override-wrap layer.
5495
+ *
5496
+ * Invariant: `{source, specOverrides}` can only appear at the top level —
5497
+ * the inner `source` is never itself an override-wrap. Anything else throws.
5498
+ */
5499
+ function unwrapOverrides(id) {
5500
+ const parsed = parseColumnIdSafely(id);
5501
+ if (parsed === void 0 || !isColumnOverriddenKey(parsed)) return void 0;
5502
+ const inner = parseColumnIdSafely(parsed.source);
5503
+ if (inner !== void 0 && isColumnOverriddenKey(inner)) throw new Error("nested override-wrap detected — invariant broken");
5504
+ return parsed;
5505
+ }
5506
+ /**
5507
+ * Apply `specOverrides` from a rich id (`SUniversalPColumnId`) on top of a
5508
+ * resolved {@link PColumnSpec}. Returns `base` unchanged when the id carries
5509
+ * no overrides.
5510
+ */
5511
+ function applySpecOverrides(base, idOrOverride) {
5512
+ if (isNil(idOrOverride)) return base;
5513
+ const overrides = isString(idOrOverride) ? unwrapOverrides(idOrOverride)?.specOverrides : idOrOverride;
5514
+ if (isNil(overrides)) return base;
5515
+ const result = { ...base };
5516
+ if (overrides.annotations) result.annotations = mergeRecord(base.annotations, overrides.annotations);
5517
+ if (overrides.domain) result.domain = mergeRecord(base.domain, overrides.domain);
5518
+ if (overrides.contextDomain) result.contextDomain = mergeRecord(base.contextDomain, overrides.contextDomain);
5519
+ if (overrides.axesSpec) result.axesSpec = applyAxesPatches(base.axesSpec, overrides.axesSpec);
5520
+ return result;
5521
+ }
5522
+ /**
5523
+ * Compose two override patches: applying `mergeSpecOverrides(prior, next)` on
5524
+ * top of a base spec produces the same result as applying `prior` then `next`.
5525
+ */
5526
+ function mergeSpecOverrides(prior, next) {
5527
+ const result = {};
5528
+ const axesSpec = mergeAxesPatches(prior.axesSpec, next.axesSpec);
5529
+ if (axesSpec !== void 0) result.axesSpec = axesSpec;
5530
+ const annotations = mergeRecord(prior.annotations, next.annotations);
5531
+ if (annotations !== void 0) result.annotations = annotations;
5532
+ const domain = mergeRecord(prior.domain, next.domain);
5533
+ if (domain !== void 0) result.domain = domain;
5534
+ const contextDomain = mergeRecord(prior.contextDomain, next.contextDomain);
5535
+ if (contextDomain !== void 0) result.contextDomain = contextDomain;
5536
+ return result;
5537
+ }
5538
+ /**
5539
+ * Apply positional `patches` onto `base.axesSpec`. Patches deep-merge
5540
+ * `annotations` / `domain` / `contextDomain` and shallow-override `name` /
5541
+ * `type` at their slot. Indices `>= base.length` append new axes; intermediate
5542
+ * gaps (if any) are filled with the patch itself, so callers should not leave
5543
+ * holes between base.length and the highest patched index.
5544
+ */
5545
+ function applyAxesPatches(base, patches) {
5546
+ const result = base.slice();
5547
+ for (const [k, p] of Object.entries(patches)) {
5548
+ const i = Number(k);
5549
+ const existing = result[i];
5550
+ result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
5551
+ }
5552
+ return result;
5553
+ }
5554
+ /**
5555
+ * Compose two positional patch maps: `mergeAxesPatches(prior, next)` applied to
5556
+ * a base spec must equal applying `prior` then `next`. Patches sharing an
5557
+ * index deep-merge field-by-field.
5558
+ */
5559
+ function mergeAxesPatches(prior, next) {
5560
+ if (!prior || Object.keys(prior).length === 0) return next;
5561
+ if (!next || Object.keys(next).length === 0) return prior;
5562
+ const result = { ...prior };
5563
+ for (const [k, p] of Object.entries(next)) {
5564
+ const i = Number(k);
5565
+ const existing = result[i];
5566
+ result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
5567
+ }
5568
+ return result;
5569
+ }
5570
+ function mergeAxisPatch(axis, patch) {
5571
+ const result = {
5572
+ ...axis,
5573
+ ...patch
5574
+ };
5575
+ if (patch.annotations) result.annotations = mergeRecord(axis.annotations, patch.annotations);
5576
+ if (patch.domain) result.domain = mergeRecord(axis.domain, patch.domain);
5577
+ if (patch.contextDomain) result.contextDomain = mergeRecord(axis.contextDomain, patch.contextDomain);
5578
+ return result;
5579
+ }
5580
+ function mergeRecord(a, b) {
5581
+ if (!b) return a;
5582
+ if (!a) return b;
5583
+ return {
5584
+ ...a,
5585
+ ...b
5586
+ };
5259
5587
  }
5260
5588
  //#endregion
5261
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5589
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5262
5590
  function axisKey(axis) {
5263
5591
  return (0, import_canonicalize.default)(getAxisId(axis));
5264
5592
  }
@@ -5504,53 +5832,7 @@ function isAnchorAxisRef(value) {
5504
5832
  return typeof value === "object" && "anchor" in value;
5505
5833
  }
5506
5834
  //#endregion
5507
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
5508
- function isPColumnSpec(spec) {
5509
- return spec.kind === "PColumn";
5510
- }
5511
- function isPColumn(obj) {
5512
- return isPColumnSpec(obj.spec);
5513
- }
5514
- function ensurePColumn(obj) {
5515
- if (!isPColumn(obj)) throw new Error(`not a PColumn (kind = ${obj.spec.kind})`);
5516
- return obj;
5517
- }
5518
- function mapPObjectData(pObj, cb) {
5519
- return pObj === void 0 ? void 0 : {
5520
- ...pObj,
5521
- data: cb(typeof pObj.data === "function" ? pObj.data() : pObj.data)
5522
- };
5523
- }
5524
- function extractAllColumns(entry) {
5525
- const columns = /* @__PURE__ */ new Map();
5526
- const addAllColumns = (entry) => {
5527
- switch (entry.type) {
5528
- case "column":
5529
- columns.set(entry.column.id, entry.column);
5530
- return;
5531
- case "slicedColumn":
5532
- columns.set(entry.column.id, entry.column);
5533
- return;
5534
- case "artificialColumn":
5535
- columns.set(entry.column.id, entry.column);
5536
- return;
5537
- case "inlineColumn": return;
5538
- case "full":
5539
- case "inner":
5540
- for (const e of entry.entries) addAllColumns(e);
5541
- return;
5542
- case "outer":
5543
- addAllColumns(entry.primary);
5544
- for (const e of entry.secondary) addAllColumns(e);
5545
- return;
5546
- default: assertNever(entry);
5547
- }
5548
- };
5549
- addAllColumns(entry);
5550
- return [...columns.values()];
5551
- }
5552
- //#endregion
5553
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5835
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5554
5836
  /**
5555
5837
  * Determines if an axis ID matches an axis selector.
5556
5838
  *
@@ -5631,7 +5913,7 @@ function legacyColumnSelectorsToPredicate(predicateOrSelectors) {
5631
5913
  else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);
5632
5914
  }
5633
5915
  //#endregion
5634
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5916
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5635
5917
  function deriveNativeId(spec) {
5636
5918
  const result = {
5637
5919
  kind: spec.kind,
@@ -5642,15 +5924,8 @@ function deriveNativeId(spec) {
5642
5924
  if (isPColumnSpec(spec)) result.axesSpec = getAxesId(spec.axesSpec);
5643
5925
  return (0, import_canonicalize.default)(result);
5644
5926
  }
5645
- Array.isArray;
5646
- //#endregion
5647
- //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.2/node_modules/@milaboratories/helpers/dist/error.js
5648
- function throwError(v) {
5649
- if (typeof v === "string") throw new Error(v);
5650
- else throw v;
5651
- }
5652
5927
  //#endregion
5653
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5928
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5654
5929
  var LinkerMap = class LinkerMap {
5655
5930
  /** Graph of linkers connected by axes (single or grouped by parents) */
5656
5931
  data;
@@ -5828,7 +6103,7 @@ var LinkerMap = class LinkerMap {
5828
6103
  }
5829
6104
  };
5830
6105
  //#endregion
5831
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
6106
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5832
6107
  /**
5833
6108
  * Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
5834
6109
  * version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
@@ -5871,7 +6146,7 @@ function withEnrichments(ref, requireEnrichments = true) {
5871
6146
  }
5872
6147
  }
5873
6148
  //#endregion
5874
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
6149
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5875
6150
  function mapValueInVOE(voe, cb) {
5876
6151
  return voe.ok ? {
5877
6152
  ok: true,
@@ -5879,7 +6154,51 @@ function mapValueInVOE(voe, cb) {
5879
6154
  } : voe;
5880
6155
  }
5881
6156
  //#endregion
5882
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
6157
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
6158
+ /** Well-known resource type names used across the platform. */
6159
+ const ResourceTypeName = {
6160
+ StreamManager: "StreamManager",
6161
+ StdMap: "StdMap",
6162
+ StdMapSlash: "std/map",
6163
+ EphStdMap: "EphStdMap",
6164
+ PFrame: "PFrame",
6165
+ ParquetChunk: "ParquetChunk",
6166
+ BContext: "BContext",
6167
+ BlockPackCustom: "BlockPackCustom",
6168
+ BinaryMap: "BinaryMap",
6169
+ BinaryValue: "BinaryValue",
6170
+ BlobMap: "BlobMap",
6171
+ BResolveSingle: "BResolveSingle",
6172
+ BResolveSingleNoResult: "BResolveSingleNoResult",
6173
+ BQueryResult: "BQueryResult",
6174
+ TengoTemplate: "TengoTemplate",
6175
+ TengoLib: "TengoLib",
6176
+ SoftwareInfo: "SoftwareInfo",
6177
+ Dummy: "Dummy",
6178
+ JsonResourceError: "json/resourceError",
6179
+ JsonObject: "json/object",
6180
+ JsonGzObject: "json-gz/object",
6181
+ JsonString: "json/string",
6182
+ JsonArray: "json/array",
6183
+ JsonNumber: "json/number",
6184
+ BContextEnd: "BContextEnd",
6185
+ FrontendFromUrl: "Frontend/FromUrl",
6186
+ FrontendFromFolder: "Frontend/FromFolder",
6187
+ BObjectSpec: "BObjectSpec",
6188
+ Blob: "Blob",
6189
+ Null: "Null",
6190
+ Binary: "binary",
6191
+ LSProvider: "LSProvider",
6192
+ WorkingDirectory: "WorkingDirectory",
6193
+ UserProject: "UserProject",
6194
+ Projects: "Projects",
6195
+ ClientRoot: "ClientRoot",
6196
+ SharingOutbox: "SharingOutbox",
6197
+ SharingState: "SharingState",
6198
+ SharedEnvelope: "SharedEnvelope"
6199
+ };
6200
+ //#endregion
6201
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5883
6202
  const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5884
6203
  const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
5885
6204
  const typeMap = /* @__PURE__ */ new Map();
@@ -5918,7 +6237,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
5918
6237
  };
5919
6238
  })();
5920
6239
  //#endregion
5921
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
6240
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5922
6241
  const Services = {
5923
6242
  PFrameSpec: service()({
5924
6243
  type: "wasm",
@@ -5976,6 +6295,28 @@ const Services = {
5976
6295
  name: "dialog",
5977
6296
  modelMethods: [],
5978
6297
  uiMethods: ["showSaveDialog"]
6298
+ }),
6299
+ ColumnsCollection: service()({
6300
+ type: "wasm",
6301
+ name: "columnsCollection",
6302
+ modelMethods: [
6303
+ "create",
6304
+ "isEmpty",
6305
+ "isFinal",
6306
+ "getColumns",
6307
+ "addSource",
6308
+ "discover",
6309
+ "filter"
6310
+ ],
6311
+ uiMethods: [
6312
+ "create",
6313
+ "isEmpty",
6314
+ "isFinal",
6315
+ "getColumns",
6316
+ "addSource",
6317
+ "discover",
6318
+ "filter"
6319
+ ]
5979
6320
  })
5980
6321
  };
5981
6322
  Object.keys(Services).map((key) => `requires${key}`);
@@ -5990,7 +6331,7 @@ function resolveRequiredServices(flags) {
5990
6331
  }
5991
6332
  Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
5992
6333
  //#endregion
5993
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.3/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6334
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
5994
6335
  function buildMethodMap(pick) {
5995
6336
  const result = {};
5996
6337
  for (const id of Object.values(Services)) result[id] = [...pick(id)];
@@ -5999,24 +6340,226 @@ function buildMethodMap(pick) {
5999
6340
  buildMethodMap(getServiceUiMethods);
6000
6341
  buildMethodMap(getServiceModelMethods);
6001
6342
  //#endregion
6002
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/accessor.js
6003
- function ifDef(value, cb) {
6004
- return value === void 0 ? void 0 : cb(value);
6005
- }
6343
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6344
+ /** Resource types that hold column collections — DFS stops here and collects. */
6345
+ const COLLECT_TYPES = [ResourceTypeName.PFrame];
6346
+ /** Resource types DFS descends through when looking for PFrames. */
6347
+ const DESCEND_TYPES = [ResourceTypeName.StdMap, ResourceTypeName.StdMapSlash];
6006
6348
  /**
6007
- * Decode an error node's content into a display message. The backend serializes
6008
- * a resource error as `{"message": "..."}` (`ResourceError`); unwrap that to the
6009
- * human-readable message. Falls back to the raw string when the content is not
6010
- * that envelope (e.g. plain text, or an unexpected shape).
6349
+ * Enumerate column names backing a PFrame accessor derived from
6350
+ * `<name>.spec` field names, without resolving the spec resources.
6011
6351
  */
6012
- function decodeErrorMessage(raw) {
6013
- try {
6014
- const parsed = JSON.parse(raw);
6015
- if (typeof parsed?.message === "string") return parsed.message;
6016
- } catch {}
6017
- return raw;
6352
+ function listColumnNames(accessor, prefix = "") {
6353
+ if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];
6354
+ const out = [];
6355
+ for (const field of accessor.listInputFields()) {
6356
+ if (!field.endsWith(".spec")) continue;
6357
+ const raw = field.slice(0, -5);
6358
+ if (!raw.startsWith(prefix)) continue;
6359
+ out.push(raw.slice(prefix.length));
6360
+ }
6361
+ return out;
6018
6362
  }
6019
- /** Represent resource tree node accessor */
6363
+ /**
6364
+ * DFS over the input-field subtree of `root`. Collects nodes whose resource
6365
+ * type ∈ `collectTypes`. Descends only through `descendTypes`
6366
+ * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
6367
+ *
6368
+ * Threads the field-name path from `rootPath` to each hit, so callers can
6369
+ * build canonical {@link createLocalPObjectId}s without relying on the
6370
+ * accessor itself to remember its path.
6371
+ *
6372
+ * Includes `root` itself in the walk.
6373
+ */
6374
+ function findDescendantsByType(opts) {
6375
+ const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
6376
+ const collectSet = new Set(collectTypes);
6377
+ const descendSet = new Set(descendTypes);
6378
+ const result = [];
6379
+ const stack = [{
6380
+ node: root,
6381
+ path: rootPath
6382
+ }];
6383
+ while (stack.length > 0) {
6384
+ const { node, path } = stack.pop();
6385
+ const typeName = node.resourceType.name;
6386
+ if (collectSet.has(typeName)) {
6387
+ result.push({
6388
+ node,
6389
+ path
6390
+ });
6391
+ continue;
6392
+ }
6393
+ if (!descendSet.has(typeName)) continue;
6394
+ const fields = node.listInputFields();
6395
+ for (let i = fields.length - 1; i >= 0; i--) {
6396
+ const child = node.traverse({
6397
+ field: fields[i],
6398
+ assertFieldType: "Input",
6399
+ ignoreError: true
6400
+ });
6401
+ if (child !== void 0) stack.push({
6402
+ node: child,
6403
+ path: [...path, fields[i]]
6404
+ });
6405
+ }
6406
+ }
6407
+ return result;
6408
+ }
6409
+ /**
6410
+ * Walk an accessor root and return one {@link LeafEntry} per discovered column.
6411
+ * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
6412
+ * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
6413
+ */
6414
+ function indexAccessorRoot(root, rootPath) {
6415
+ const result = [];
6416
+ for (const { node, path } of findDescendantsByType({
6417
+ root,
6418
+ rootPath,
6419
+ collectTypes: COLLECT_TYPES,
6420
+ descendTypes: DESCEND_TYPES
6421
+ })) for (const name of listColumnNames(node)) result.push({
6422
+ accessor: node,
6423
+ name,
6424
+ id: createLocalPObjectId([...path], name)
6425
+ });
6426
+ return result;
6427
+ }
6428
+ /**
6429
+ * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
6430
+ * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
6431
+ * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
6432
+ */
6433
+ function indexPoolBlock(block) {
6434
+ const accessors = [];
6435
+ if (block.prodCtx) accessors.push(block.prodCtx);
6436
+ if (block.stagingCtx) accessors.push(block.stagingCtx);
6437
+ const result = [];
6438
+ const seen = /* @__PURE__ */ new Set();
6439
+ for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
6440
+ if (seen.has(name)) continue;
6441
+ seen.add(name);
6442
+ result.push({
6443
+ accessor,
6444
+ name,
6445
+ id: createGlobalPObjectId(block.blockId, name)
6446
+ });
6447
+ }
6448
+ return result;
6449
+ }
6450
+ //#endregion
6451
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6452
+ /**
6453
+ * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
6454
+ * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
6455
+ * the same class backs both sandbox (`TreeNodeAccessor`) and host
6456
+ * (`PlTreeNodeAccessor`) usage.
6457
+ *
6458
+ * Stateless beyond the provider list — every lookup goes through each
6459
+ * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
6460
+ * directly at the call site that has the providers; there is no ambient
6461
+ * singleton.
6462
+ */
6463
+ var ColumnRegistry = class {
6464
+ providers;
6465
+ constructor(providers) {
6466
+ this.providers = providers;
6467
+ }
6468
+ /**
6469
+ * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
6470
+ * `undefined` if the column is not reachable from any provider — caller
6471
+ * decides whether that's `absent` or `resolving` via {@link isFinal}.
6472
+ */
6473
+ resolve(id) {
6474
+ return this.lookupById(id);
6475
+ }
6476
+ /** Whether every indexed source has finished enumerating its columns. */
6477
+ isFinal() {
6478
+ return this.providers.every((p) => p.isFinal());
6479
+ }
6480
+ lookupById(id) {
6481
+ for (const p of this.providers) {
6482
+ const hit = p.getPObjectEntries().get(id);
6483
+ if (hit !== void 0) return hit;
6484
+ }
6485
+ }
6486
+ };
6487
+ //#endregion
6488
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6489
+ /**
6490
+ * Generic entries provider over a single accessor root. Walks `<root>` once
6491
+ * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
6492
+ * exposes `isFinal()` via the root's `getInputsLocked()`.
6493
+ *
6494
+ * Used directly on the host side; sandbox extends it with `getColumns()`
6495
+ * returning {@link ColumnLazy}s — see `AccessorColumnsProvider` in
6496
+ * `@platforma-sdk/model`.
6497
+ */
6498
+ var AccessorEntriesProvider = class {
6499
+ root;
6500
+ entries;
6501
+ constructor(root, rootPath) {
6502
+ this.root = root;
6503
+ const map = /* @__PURE__ */ new Map();
6504
+ for (const entry of indexAccessorRoot(root, rootPath)) if (!map.has(entry.id)) map.set(entry.id, entry);
6505
+ this.entries = map;
6506
+ }
6507
+ getPObjectEntries() {
6508
+ return this.entries;
6509
+ }
6510
+ isFinal() {
6511
+ return this.root.getInputsLocked();
6512
+ }
6513
+ };
6514
+ /**
6515
+ * Generic entries provider over a list of upstream-block ctx pairs.
6516
+ *
6517
+ * Per-block merge: iterate `prod` then `staging`, dedupe by name with
6518
+ * first-wins semantics (prod takes precedence).
6519
+ *
6520
+ * `isFinal()` is the AND of `getInputsLocked()` over every present ctx
6521
+ * accessor and `!prodIncomplete && !stagingIncomplete` over every block.
6522
+ */
6523
+ var ResultPoolEntriesProvider = class {
6524
+ blocks;
6525
+ cachedEntries;
6526
+ constructor(blocks) {
6527
+ this.blocks = blocks;
6528
+ }
6529
+ getPObjectEntries() {
6530
+ if (this.cachedEntries !== void 0) return this.cachedEntries;
6531
+ const map = /* @__PURE__ */ new Map();
6532
+ for (const block of this.blocks) for (const entry of indexPoolBlock(block)) if (!map.has(entry.id)) map.set(entry.id, entry);
6533
+ return this.cachedEntries = map;
6534
+ }
6535
+ isFinal() {
6536
+ for (const block of this.blocks) {
6537
+ if (block.prodIncomplete || block.stagingIncomplete) return false;
6538
+ if (block.prodCtx && !block.prodCtx.getInputsLocked()) return false;
6539
+ if (block.stagingCtx && !block.stagingCtx.getInputsLocked()) return false;
6540
+ }
6541
+ return true;
6542
+ }
6543
+ };
6544
+ //#endregion
6545
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/accessor.js
6546
+ function ifDef(value, cb) {
6547
+ return value === void 0 ? void 0 : cb(value);
6548
+ }
6549
+ /**
6550
+ * Decode an error node's content into a display message. The backend serializes
6551
+ * a resource error as `{"message": "..."}` (`ResourceError`); unwrap that to the
6552
+ * human-readable message. Falls back to the raw string when the content is not
6553
+ * that envelope (e.g. plain text, or an unexpected shape).
6554
+ */
6555
+ function decodeErrorMessage(raw) {
6556
+ try {
6557
+ const parsed = JSON.parse(raw);
6558
+ if (typeof parsed?.message === "string") return parsed.message;
6559
+ } catch {}
6560
+ return raw;
6561
+ }
6562
+ /** Represent resource tree node accessor */
6020
6563
  var TreeNodeAccessor = class TreeNodeAccessor {
6021
6564
  handle;
6022
6565
  resolvePath;
@@ -6045,7 +6588,7 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6045
6588
  }));
6046
6589
  return this.resolveWithCommon({}, ...transformedSteps);
6047
6590
  }
6048
- resolveAny(...steps) {
6591
+ traverse(...steps) {
6049
6592
  return this.resolveWithCommon({}, ...steps);
6050
6593
  }
6051
6594
  resolveWithCommon(commonOptions, ...steps) {
@@ -6091,6 +6634,9 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6091
6634
  if (content == void 0) throw new Error("Resource has no content.");
6092
6635
  return JSON.parse(content);
6093
6636
  }
6637
+ hasData() {
6638
+ return getCfgRenderCtx().hasData(this.handle);
6639
+ }
6094
6640
  getDataBase64() {
6095
6641
  return getCfgRenderCtx().getDataBase64(this.handle);
6096
6642
  }
@@ -6127,9 +6673,16 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6127
6673
  }
6128
6674
  return this.getDataAsJson();
6129
6675
  }
6130
- /**
6131
- *
6132
- */
6676
+ getFileContentAsBase64(range) {
6677
+ return new FutureRef(getCfgRenderCtx().getBlobContentAsBase64(this.handle, range));
6678
+ }
6679
+ getFileContentAsString(range) {
6680
+ return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range));
6681
+ }
6682
+ getFileContentAsJson(range) {
6683
+ return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range)).mapDefined((v) => JSON.parse(v));
6684
+ }
6685
+ /** @deprecated */
6133
6686
  getPColumns(errorOnUnknownField = false, prefix = "") {
6134
6687
  const result = this.parsePObjectCollection(errorOnUnknownField, prefix);
6135
6688
  if (result === void 0) return void 0;
@@ -6138,9 +6691,7 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6138
6691
  return obj;
6139
6692
  });
6140
6693
  }
6141
- /**
6142
- *
6143
- */
6694
+ /** @deprecated */
6144
6695
  parsePObjectCollection(errorOnUnknownField = false, prefix = "") {
6145
6696
  const pObjects = getCfgRenderCtx().parsePObjectCollection(this.handle, errorOnUnknownField, prefix, ...this.resolvePath);
6146
6697
  if (pObjects === void 0) return void 0;
@@ -6151,15 +6702,6 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6151
6702
  }
6152
6703
  return result;
6153
6704
  }
6154
- getFileContentAsBase64(range) {
6155
- return new FutureRef(getCfgRenderCtx().getBlobContentAsBase64(this.handle, range));
6156
- }
6157
- getFileContentAsString(range) {
6158
- return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range));
6159
- }
6160
- getFileContentAsJson(range) {
6161
- return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range)).mapDefined((v) => JSON.parse(v));
6162
- }
6163
6705
  /**
6164
6706
  * @deprecated use getFileContentAsBase64
6165
6707
  */
@@ -6250,11 +6792,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
6250
6792
  }
6251
6793
  };
6252
6794
  //#endregion
6253
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/internal.js
6254
- const StagingAccessorName = "staging";
6795
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/internal.js
6255
6796
  const MainAccessorName = "main";
6797
+ const StagingAccessorName = "staging";
6256
6798
  //#endregion
6257
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
6799
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
6258
6800
  function filterDataInfoEntries(dataInfoEntries, axisFilters) {
6259
6801
  const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
6260
6802
  const { type } = dataInfoEntries;
@@ -6318,49 +6860,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
6318
6860
  }
6319
6861
  }
6320
6862
  //#endregion
6321
- //#region ../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isFunction.mjs
6322
- /**
6323
- * Checks if `value` is a function.
6324
- *
6325
- * @param {any} value The value to check.
6326
- * @returns {boolean} Returns `true` if `value` is a function, else `false`.
6327
- *
6328
- * @example
6329
- * isFunction(Array.prototype.slice); // true
6330
- * isFunction(async function () {}); // true
6331
- * isFunction(function* () {}); // true
6332
- * isFunction(Proxy); // true
6333
- * isFunction(Int8Array); // true
6334
- */
6335
- function isFunction(value) {
6336
- return typeof value === "function";
6337
- }
6338
- //#endregion
6339
- //#region ../node_modules/.pnpm/es-toolkit@1.47.0/node_modules/es-toolkit/dist/predicate/isNil.mjs
6340
- /**
6341
- * Checks if a given value is null or undefined.
6342
- *
6343
- * This function tests whether the provided value is either `null` or `undefined`.
6344
- * It returns `true` if the value is `null` or `undefined`, and `false` otherwise.
6345
- *
6346
- * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `null` or `undefined`.
6347
- *
6348
- * @param {unknown} x - The value to test for null or undefined.
6349
- * @returns {boolean} `true` if the value is null or undefined, `false` otherwise.
6350
- *
6351
- * @example
6352
- * const value1 = null;
6353
- * const value2 = undefined;
6354
- * const value3 = 42;
6355
- * const result1 = isNil(value1); // true
6356
- * const result2 = isNil(value2); // true
6357
- * const result3 = isNil(value3); // false
6358
- */
6359
- function isNil(x) {
6360
- return x == null;
6361
- }
6362
- //#endregion
6363
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
6863
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
6364
6864
  const DISTANCE_PENALTY = .001;
6365
6865
  const LABEL_TYPE = "__LABEL__";
6366
6866
  const LABEL_TYPE_FULL = "__LABEL__@1";
@@ -6626,7 +7126,7 @@ function minimizeTypeSet(typeSet, records, stats, forceTraceElements, forcedSet,
6626
7126
  return result;
6627
7127
  }
6628
7128
  //#endregion
6629
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/util/label.js
7129
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/label.js
6630
7130
  /** @deprecated Use deriveDistinctLabels */
6631
7131
  function deriveLabels(values, getSpec, options = {}) {
6632
7132
  return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
@@ -6635,7 +7135,7 @@ function deriveLabels(values, getSpec, options = {}) {
6635
7135
  }));
6636
7136
  }
6637
7137
  //#endregion
6638
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7138
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
6639
7139
  const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
6640
7140
  const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
6641
7141
  const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
@@ -6922,7 +7422,7 @@ function isPColumnReady(c) {
6922
7422
  const isValues = (d) => Array.isArray(d);
6923
7423
  const isAccessor = (d) => d instanceof TreeNodeAccessor;
6924
7424
  let ready = true;
6925
- const data = typeof c.data === "function" ? c.data() : c.data;
7425
+ const data = c.data;
6926
7426
  if (data == null) return false;
6927
7427
  else if (isAccessor(data)) ready &&= data.getIsReadyOrError();
6928
7428
  else if (isDataInfo(data)) visitDataInfo(data, (v) => ready &&= v.getIsReadyOrError());
@@ -6933,7 +7433,7 @@ function allPColumnsReady(columns) {
6933
7433
  return columns.every(isPColumnReady);
6934
7434
  }
6935
7435
  //#endregion
6936
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
7436
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
6937
7437
  function isPColumnValues(value) {
6938
7438
  if (!Array.isArray(value)) return false;
6939
7439
  if (value.length === 0) return true;
@@ -6943,7 +7443,7 @@ function isPColumnValues(value) {
6943
7443
  /**
6944
7444
  * A simple implementation of {@link ColumnProvider} backed by a pre-defined array of columns.
6945
7445
  */
6946
- var ArrayColumnProvider = class {
7446
+ var ArrayColumnsProvider = class {
6947
7447
  columns;
6948
7448
  constructor(columns) {
6949
7449
  this.columns = columns;
@@ -6995,7 +7495,7 @@ function getSplitAxisIndices(selector) {
6995
7495
  }
6996
7496
  var PColumnCollection = class {
6997
7497
  defaultProviderStore = [];
6998
- providers = [new ArrayColumnProvider(this.defaultProviderStore)];
7498
+ providers = [new ArrayColumnsProvider(this.defaultProviderStore)];
6999
7499
  axisLabelProviders = [];
7000
7500
  constructor() {}
7001
7501
  addColumnProvider(provider) {
@@ -7158,7 +7658,9 @@ var PColumnCollection = class {
7158
7658
  result.push({
7159
7659
  id: finalId,
7160
7660
  spec: finalSpec,
7161
- data: () => entry.type === "split" ? entriesToDataInfo(filterDataInfoEntries(entry.dataEntries, axisFiltersTuple)) : entry.originalColumn.data,
7661
+ get data() {
7662
+ return entry.type === "split" ? entriesToDataInfo(filterDataInfoEntries(entry.dataEntries, axisFiltersTuple)) : entry.originalColumn.data;
7663
+ },
7162
7664
  label
7163
7665
  });
7164
7666
  }
@@ -7194,7 +7696,7 @@ var PColumnCollection = class {
7194
7696
  if (!entries) return void 0;
7195
7697
  const columns = [];
7196
7698
  for (const entry of entries) {
7197
- const data = entry.data();
7699
+ const data = entry.data;
7198
7700
  if (!data) {
7199
7701
  if (opts?.dontWaitAllData) continue;
7200
7702
  return;
@@ -7209,7 +7711,7 @@ var PColumnCollection = class {
7209
7711
  }
7210
7712
  };
7211
7713
  //#endregion
7212
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/services/block_services.js
7714
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/block_services.js
7213
7715
  /**
7214
7716
  * Services required by all V3 blocks by default.
7215
7717
  * Edit this when a new service should be available to all blocks.
@@ -7220,11 +7722,12 @@ var PColumnCollection = class {
7220
7722
  const BLOCK_SERVICE_FLAGS = {
7221
7723
  requiresPFrameSpec: true,
7222
7724
  requiresPFrame: true,
7223
- requiresDialog: true
7725
+ requiresDialog: true,
7726
+ requiresColumnsCollection: true
7224
7727
  };
7225
7728
  resolveRequiredServices(BLOCK_SERVICE_FLAGS);
7226
7729
  //#endregion
7227
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
7730
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
7228
7731
  /**
7229
7732
  * Builds a ServiceProxy from a ServiceDispatch.
7230
7733
  * Each service method call is forwarded to dispatch.callServiceMethod.
@@ -7233,10 +7736,10 @@ function createServiceProxy(dispatch) {
7233
7736
  return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
7234
7737
  }
7235
7738
  //#endregion
7236
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/services/get_services.js
7739
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/get_services.js
7237
7740
  const cachedServices = /* @__PURE__ */ new WeakMap();
7238
- function getService(name) {
7239
- const ctx = getCfgRenderCtx();
7741
+ function getService(name, deps) {
7742
+ const ctx = deps?.ctx ?? getCfgRenderCtx();
7240
7743
  const map = cachedServices.has(ctx) ? cachedServices.get(ctx) : (() => {
7241
7744
  cachedServices.set(ctx, /* @__PURE__ */ new Map());
7242
7745
  return cachedServices.get(ctx);
@@ -7247,7 +7750,7 @@ function getService(name) {
7247
7750
  })();
7248
7751
  }
7249
7752
  //#endregion
7250
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
7753
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
7251
7754
  function patchInSetFilters(filters) {
7252
7755
  const inSetToOrEqual = (predicate) => {
7253
7756
  if (predicate.operator !== "InSet") return predicate;
@@ -7285,7 +7788,7 @@ function patchInSetFilters(filters) {
7285
7788
  return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
7286
7789
  }
7287
7790
  //#endregion
7288
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/render/api.js
7791
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/api.js
7289
7792
  /**
7290
7793
  * Helper function to match domain objects
7291
7794
  * @param query Optional domain to match against
@@ -7300,24 +7803,35 @@ function matchDomain(query, target) {
7300
7803
  }
7301
7804
  /**
7302
7805
  * Transforms PColumn data into the internal representation expected by the platform
7303
- * @param data Data from a PColumn to transform
7806
+ * @param column Data from a PColumn to transform
7304
7807
  * @returns Transformed data compatible with platform API
7305
7808
  */
7306
- function transformPColumnData(data) {
7307
- return mapPObjectData(data, (d) => {
7308
- if (d instanceof TreeNodeAccessor) return d.handle;
7309
- else if (isDataInfo(d)) return mapDataInfo(d, (accessor) => accessor.handle);
7310
- else return d ?? [];
7809
+ function finalizePColumnData(column) {
7810
+ return mapPObjectData(column, (data) => {
7811
+ if (data instanceof TreeNodeAccessor) return data.handle;
7812
+ else if (isDataInfo(data)) {
7813
+ let ready = true;
7814
+ visitDataInfo(data, (accessor) => ready &&= accessor?.getIsReadyOrError() ?? false);
7815
+ if (!ready) return [];
7816
+ return mapDataInfo(data, (accessor) => accessor?.handle ?? throwError("Accessor handle is undefined"));
7817
+ } else return data ?? [];
7311
7818
  });
7312
7819
  }
7820
+ /**
7821
+ * @deprecated use the direct `ctx.*` methods on `RenderCtxBase` instead.
7822
+ *
7823
+ * Migration map:
7824
+ * - `getSpecs` → `ctx.getSpecs`
7825
+ * - `getSpecByRef` / `getPColumnSpecByRef` → `ctx.getSpecByRef` / `ctx.getPColumnSpecByRef`
7826
+ * - `getDataByRef` / `getPColumnByRef` → `ctx.getDataByRef` / `ctx.getPColumnByRef`
7827
+ * - `getOptions` → `ctx.getOptions`
7828
+ *
7829
+ * Eager methods `selectColumns` / `getData` / `getDataWithErrors` should be
7830
+ * replaced by `ctx.getSpecs` + on-demand `ctx.getStatusByRef` /
7831
+ * `ctx.getPColumnByRef` so that the data resource is not subscribed up-front.
7832
+ */
7313
7833
  var ResultPool = class {
7314
7834
  ctx = getCfgRenderCtx();
7315
- /**
7316
- * @deprecated use getOptions()
7317
- */
7318
- calculateOptions(predicate) {
7319
- return this.ctx.calculateOptions(predicate);
7320
- }
7321
7835
  getOptions(predicateOrSelector, opts) {
7322
7836
  const predicate = typeof predicateOrSelector === "function" ? predicateOrSelector : legacyColumnSelectorsToPredicate(predicateOrSelector);
7323
7837
  const filtered = this.getSpecs().entries.filter((s) => predicate(s.obj));
@@ -7461,7 +7975,6 @@ var ResultPool = class {
7461
7975
  * @returns data associated with the ref
7462
7976
  */
7463
7977
  getDataByRef(ref) {
7464
- if (typeof this.ctx.getDataFromResultPoolByRef === "undefined") return this.getData().entries.find((f) => f.ref.blockId === ref.blockId && f.ref.name === ref.name)?.obj;
7465
7978
  const data = this.ctx.getDataFromResultPoolByRef(ref.blockId, ref.name);
7466
7979
  if (!data) return void 0;
7467
7980
  return mapPObjectData(data, (handle) => new TreeNodeAccessor(handle, [ref.blockId, ref.name]));
@@ -7542,6 +8055,9 @@ var ResultPool = class {
7542
8055
  *
7543
8056
  * @param selectors - A predicate function, a single selector, or an array of selectors.
7544
8057
  * @returns An array of PColumn objects matching the selectors. Data is loaded on first access.
8058
+ * @deprecated use `RenderCtxBase.rawResultPool` + `ResultPoolColumnsProvider` +
8059
+ * `discoverColumns` instead. This eager path materializes column data
8060
+ * unnecessarily for callers that only filter by spec.
7545
8061
  */
7546
8062
  selectColumns(selectors) {
7547
8063
  const predicate = typeof selectors === "function" ? selectors : legacyColumnSelectorsToPredicate(selectors);
@@ -7619,20 +8135,8 @@ var RenderCtxBase = class {
7619
8135
  get outputs() {
7620
8136
  return this.getNamedAccessor(MainAccessorName);
7621
8137
  }
8138
+ /** @deprecated use `rawResultPool` + `ResultPoolColumnsProvider` instead. */
7622
8139
  resultPool = new ResultPool();
7623
- /**
7624
- * Find labels data for a given axis id. It will search for a label column and return its data as a map.
7625
- * @returns a map of axis value => label
7626
- * @deprecated Use resultPool.findLabels instead
7627
- */
7628
- findLabels(axis) {
7629
- return this.resultPool.findLabels(axis);
7630
- }
7631
- verifyInlineAndExplicitColumnsSupport(columns) {
7632
- const hasInlineColumns = columns.some((c) => !(c.data instanceof TreeNodeAccessor) || isDataInfo(c.data));
7633
- const inlineColumnsSupport = this.ctx.featureFlags?.inlineColumnsSupport === true;
7634
- if (hasInlineColumns && !inlineColumnsSupport) throw Error(`Inline or explicit columns not supported`);
7635
- }
7636
8140
  patchPTableDef(def) {
7637
8141
  if (!this.ctx.featureFlags?.pTablePartitionFiltersSupport) def = {
7638
8142
  ...def,
@@ -7647,7 +8151,7 @@ var RenderCtxBase = class {
7647
8151
  return def;
7648
8152
  }
7649
8153
  createPFrame(def) {
7650
- return this.ctx.createPFrame(def.map((c) => transformPColumnData(c)));
8154
+ return this.ctx.createPFrame(def.map((v) => isString(v) ? v : finalizePColumnData(v)));
7651
8155
  }
7652
8156
  createPTable(def) {
7653
8157
  let rawDef;
@@ -7664,17 +8168,11 @@ var RenderCtxBase = class {
7664
8168
  sorting: def.sorting ?? []
7665
8169
  });
7666
8170
  else rawDef = this.patchPTableDef(def);
7667
- const columns = extractAllColumns(rawDef.src);
7668
- this.verifyInlineAndExplicitColumnsSupport(columns);
7669
- if (!allPColumnsReady(columns)) return void 0;
7670
- return this.ctx.createPTable(mapPTableDef(rawDef, (po) => transformPColumnData(po)));
8171
+ if (!allPColumnsReady(extractAllColumns(rawDef.src))) return void 0;
8172
+ return this.ctx.createPTable(mapPTableDef(rawDef, finalizePColumnData));
7671
8173
  }
7672
8174
  createPTableV2(def) {
7673
- return this.ctx.createPTableV2(mapPTableDefV2(def, (po) => transformPColumnData(po)));
7674
- }
7675
- /** @deprecated scheduled for removal from SDK */
7676
- getBlockLabel(blockId) {
7677
- return this.ctx.getBlockLabel(blockId);
8175
+ return this.ctx.createPTableV2(mapPTableDefV2(def, { column: (v) => isString(v) ? v : finalizePColumnData(v) }));
7678
8176
  }
7679
8177
  getCurrentUnstableMarker() {
7680
8178
  return this.ctx.getCurrentUnstableMarker();
@@ -7739,27 +8237,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
7739
8237
  }
7740
8238
  };
7741
8239
  //#endregion
7742
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/version.js
7743
- const PlatformaSDKVersion = "1.79.24";
8240
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/version.js
8241
+ const PlatformaSDKVersion = "1.80.2";
7744
8242
  //#endregion
7745
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/bconfig/types.js
8243
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/bconfig/types.js
7746
8244
  function isConfigLambda(cfgOrFh) {
7747
8245
  return cfgOrFh.__renderLambda === true;
7748
8246
  }
7749
8247
  //#endregion
7750
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
8248
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
7751
8249
  function downgradeCfgOrLambda(data) {
7752
8250
  if (data === void 0) return void 0;
7753
8251
  if (isConfigLambda(data)) return data.handle;
7754
8252
  return data;
7755
8253
  }
7756
8254
  //#endregion
7757
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/plugin_model.js
8255
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/plugin_model.js
7758
8256
  /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
7759
8257
  * identical across multiple `@platforma-sdk/model` copies in one process. */
7760
8258
  const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
7761
8259
  //#endregion
7762
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
8260
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
7763
8261
  /**
7764
8262
  * BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
7765
8263
  *
@@ -7936,7 +8434,7 @@ function derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFuncti
7936
8434
  }
7937
8435
  }
7938
8436
  //#endregion
7939
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.24/node_modules/@platforma-sdk/model/dist/block_model.js
8437
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_model.js
7940
8438
  /**
7941
8439
  * Merges two feature flag objects with type-aware logic:
7942
8440
  * - `supports*` (boolean): OR — `true` if either side is `true`
@@ -8247,6 +8745,1466 @@ var BlockModelV3 = class BlockModelV3 {
8247
8745
  };
8248
8746
  }
8249
8747
  };
8748
+ //#endregion
8749
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
8750
+ /**
8751
+ * Replace every column leaf whose id equals `fromId` with `toId`, leaving
8752
+ * other column refs (linkers, sub-anchors) intact. Wrapper recipes
8753
+ * (Overridden / Filtered) and Discovered use this to lift their own id onto
8754
+ * the hit leaf, so per-variant uniqueness propagates to the engine and
8755
+ * resolver-emitted ids match leaves in the emitted SpecQuery.
8756
+ *
8757
+ * Generic over all SpecQuery node shapes — including `linkerJoin`, which
8758
+ * occurs when a wrapper sits over a {@link ColumnDiscoveredRecipe}: only
8759
+ * the deepest hit leaf carries `fromId`, every linker leaf has a different
8760
+ * id and is left untouched.
8761
+ */
8762
+ function rebrandLeafId(node, fromId, toId) {
8763
+ if (fromId === toId) return node;
8764
+ return mapSpecQueryColumns(node, { column: (id) => id === fromId ? toId : id });
8765
+ }
8766
+ //#endregion
8767
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
8768
+ /**
8769
+ * Recipe wrapper that overlays {@link SpecOverrides} on top of any other
8770
+ * recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
8771
+ *
8772
+ * Flat-merge invariant: `inner` is never another {@link ColumnOverriddenRecipe}.
8773
+ * Repeated overrides go through {@link wrap} / {@link withSpecs}, which merge
8774
+ * `specOverrides` at the current level and keep wrapper depth constant.
8775
+ *
8776
+ * This invariant matches the one enforced inside `unwrapOverrides` from
8777
+ * pl-model-common: it explicitly throws on a nested override-wrap.
8778
+ */
8779
+ var ColumnOverriddenRecipe = class ColumnOverriddenRecipe {
8780
+ inner;
8781
+ overrides;
8782
+ /**
8783
+ * Wrap any recipe with overrides. If `inner` is already a
8784
+ * {@link ColumnOverriddenRecipe}, merges `overrides` into the existing ones
8785
+ * and returns a new Overridden sharing the original `inner`. No
8786
+ * `Overridden<Overridden<X>>` is produced.
8787
+ */
8788
+ static wrap(col, overrides) {
8789
+ if (col instanceof ColumnOverriddenRecipe) return new ColumnOverriddenRecipe(col.inner, mergeSpecOverrides(col.overrides, overrides));
8790
+ return new ColumnOverriddenRecipe(col, overrides);
8791
+ }
8792
+ /**
8793
+ * Static counterpart to {@link wrap}: returns the resolution status of a
8794
+ * {@link ColumnOverriddenKey} without constructing the recipe. Overrides
8795
+ * do not add references — status collapses to the source's status.
8796
+ */
8797
+ static getStatusByKey(key, opts = {}) {
8798
+ return ColumnRecipe.getStatus(key.source, opts);
8799
+ }
8800
+ id;
8801
+ specCache;
8802
+ queryCache;
8803
+ dataStatusCache;
8804
+ constructor(inner, overrides) {
8805
+ this.inner = inner;
8806
+ this.overrides = overrides;
8807
+ this.id = createColumnOverriddenId({
8808
+ source: inner.id,
8809
+ specOverrides: overrides
8810
+ });
8811
+ }
8812
+ /** Wrapped recipe — exposed so external walkers can descend. */
8813
+ getInner() {
8814
+ return this.inner;
8815
+ }
8816
+ /**
8817
+ * `inner` owns all references; overrides are a pure spec patch and do not
8818
+ * introduce new column refs.
8819
+ */
8820
+ getReferencedIds() {
8821
+ return this.inner.getReferencedIds();
8822
+ }
8823
+ getDataStatus() {
8824
+ if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
8825
+ return this.dataStatusCache.value;
8826
+ }
8827
+ /**
8828
+ * Take the inner spec and overlay our overrides. `applySpecOverrides`
8829
+ * extracts the overrides from `this.id` itself.
8830
+ */
8831
+ getSpec() {
8832
+ if (this.specCache === void 0) this.specCache = { value: applySpecOverrides(this.inner.getSpec(), this.id) };
8833
+ return this.specCache.value;
8834
+ }
8835
+ /**
8836
+ * Emit a client-side `specOverride` node wrapping the inner query.
8837
+ *
8838
+ * This is a structural-but-collapsible node: it carries the override
8839
+ * patch through the query tree so consumers see the full recipe shape,
8840
+ * but it is collapsed at the host boundary (`resolvePColumn`) before
8841
+ * the query reaches pframe-engine. The engine never sees this node.
8842
+ *
8843
+ * Overrides do not change query topology — they are a pure spec patch.
8844
+ */
8845
+ getQuery() {
8846
+ if (this.queryCache === void 0) this.queryCache = { value: {
8847
+ type: "specOverride",
8848
+ input: rebrandLeafId(this.inner.getQuery(), this.inner.id, this.id),
8849
+ override: this.overrides
8850
+ } };
8851
+ return this.queryCache.value;
8852
+ }
8853
+ /**
8854
+ * Flat merge: new overrides merge with existing ones; `inner` is unchanged.
8855
+ * The result is an Overridden of the same depth.
8856
+ */
8857
+ withSpecs(overrides) {
8858
+ return ColumnOverriddenRecipe.wrap(this, overrides);
8859
+ }
8860
+ };
8861
+ //#endregion
8862
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
8863
+ /**
8864
+ * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
8865
+ * column + a `path` of linkers + qualifications.
8866
+ *
8867
+ * Specifics:
8868
+ * - References more than one column (`column` + each `path[i].column`);
8869
+ * {@link getDataStatus} aggregates across the whole set.
8870
+ * - {@link getQuery} assembles the {@link SpecQuery} locally
8871
+ * ({@link buildSpecQuery}) — the hit is inlined as its own recipe's query
8872
+ * tree, linkers fold inside-out into nested `linkerJoin` nodes.
8873
+ * - {@link getSpec} passes through to the hit column's own spec: the linker
8874
+ * chain only enables co-indexing and does not remap the hit's `axesSpec`, so
8875
+ * no engine round-trip is needed (mirrors the Discovered branch of
8876
+ * `reconstructSpecFromId` on the host side).
8877
+ */
8878
+ var ColumnDiscoveredRecipe = class ColumnDiscoveredRecipe {
8879
+ key;
8880
+ columns;
8881
+ /**
8882
+ * Validate the key + resolve every referenced column via
8883
+ * {@link ColumnLazy.fromId} (which itself checks the leaf accessor reports
8884
+ * `hasData()`). Returns `undefined` if the key is malformed or any
8885
+ * referenced column is not yet spec-resolvable.
8886
+ *
8887
+ * Spec JSON is deserialized lazily on first {@link getSpec}/{@link getQuery}.
8888
+ */
8889
+ static fromKey(key, opts = {}) {
8890
+ const distilled = distillColumnDiscoveredKey(key);
8891
+ const columns = {};
8892
+ for (const uniId of referencedUniIdsOf(distilled)) {
8893
+ const recipe = Column(uniId, opts);
8894
+ if (recipe === void 0) return void 0;
8895
+ columns[uniId] = recipe;
8896
+ }
8897
+ return new ColumnDiscoveredRecipe(distilled, columns);
8898
+ }
8899
+ /**
8900
+ * Static counterpart to {@link fromKey}: returns the resolution status of
8901
+ * a {@link ColumnDiscoveredKey} without constructing the recipe. Worst-wins
8902
+ * across every referenced {@link ColumnUniversalId} (hit + path linkers),
8903
+ * each resolved via the top-level {@link ColumnRecipe.getStatus} dispatcher.
8904
+ */
8905
+ static getStatusByKey(key, opts = {}) {
8906
+ const distilled = distillColumnDiscoveredKey(key);
8907
+ let worst = "present";
8908
+ for (const uniId of referencedUniIdsOf(distilled)) {
8909
+ const s = ColumnRecipe.getStatus(uniId, opts);
8910
+ if (s === "absent") return "absent";
8911
+ if (s === "resolving") worst = "resolving";
8912
+ }
8913
+ return worst;
8914
+ }
8915
+ id;
8916
+ specCache;
8917
+ queryCache;
8918
+ dataStatusCache;
8919
+ constructor(key, columns) {
8920
+ this.key = key;
8921
+ this.columns = columns;
8922
+ this.id = stringifyColumnDiscoveredId(this.key);
8923
+ }
8924
+ /**
8925
+ * Universal id of the hit column (excluding path/qualifications on top).
8926
+ * May itself be a wrapped id (Overridden / Filtered / nested Discovered) —
8927
+ * preserves projections applied to the underlying column.
8928
+ */
8929
+ getHitId() {
8930
+ return this.key.column;
8931
+ }
8932
+ /**
8933
+ * Axis qualifications attached to the hit column itself — applied to the
8934
+ * outer-join entry that wraps this column at the consumer boundary.
8935
+ */
8936
+ getColumnQualifications() {
8937
+ return this.key.columnQualifications ?? [];
8938
+ }
8939
+ /**
8940
+ * Per-primary-column qualifications applied to the primary anchors on
8941
+ * this group's side. Keyed by the external primary column id.
8942
+ */
8943
+ getQueriesQualifications() {
8944
+ return this.key.queriesQualifications ?? {};
8945
+ }
8946
+ /**
8947
+ * Leaf {@link PObjectId}s the recipe physically depends on: hit column +
8948
+ * each linker in `path`, with any projection wrappers unwrapped down to
8949
+ * their underlying storage column. Used to track real-data dependencies
8950
+ * (e.g. {@link getDataStatus}), not projected identities.
8951
+ */
8952
+ getReferencedIds() {
8953
+ return [...new Set([...referencedUniIdsOf(this.key)].map((uniId) => extractPObjectId(uniId)))];
8954
+ }
8955
+ /**
8956
+ * Final spec of a discovered hit is just the hit column's own spec: the
8957
+ * linker chain only enables co-indexing, it does not remap the hit's
8958
+ * `axesSpec`, and axis qualifications live on the outer join entry (see
8959
+ * {@link buildSpecQuery}), not in the spec. So pass through to the hit
8960
+ * recipe's `getSpec()` — no engine round-trip needed. This mirrors the
8961
+ * Discovered branch of `reconstructSpecFromId` on the host side.
8962
+ */
8963
+ getSpec() {
8964
+ if (this.specCache === void 0) {
8965
+ const hit = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.getSpec: missing column ${this.key.column}`);
8966
+ this.specCache = { value: hit.getSpec() };
8967
+ }
8968
+ return this.specCache.value;
8969
+ }
8970
+ /** IR for building the final spec — see {@link buildSpecQuery}. */
8971
+ getQuery() {
8972
+ if (this.queryCache === void 0) this.queryCache = { value: this.buildSpecQuery() };
8973
+ return this.queryCache.value;
8974
+ }
8975
+ getDataStatus() {
8976
+ if (this.dataStatusCache === void 0) this.dataStatusCache = { value: Object.values(this.columns).reduce((worst, lazy) => {
8977
+ const s = lazy.getDataStatus();
8978
+ if (s === "absent" || worst === "absent") return "absent";
8979
+ if (s === "resolving") return "resolving";
8980
+ return worst;
8981
+ }, "present") };
8982
+ return this.dataStatusCache.value;
8983
+ }
8984
+ /**
8985
+ * Discovered + overrides → Overridden<Discovered>. Delegates to the
8986
+ * flat-merge factory of ColumnOverriddenRecipe; subsequent `withSpecs`
8987
+ * calls merge at the Overridden level (one wrapper, no nesting).
8988
+ */
8989
+ withSpecs(overrides) {
8990
+ return ColumnOverriddenRecipe.wrap(this, overrides);
8991
+ }
8992
+ /**
8993
+ * Assembles the SpecQuery for this discovered hit by folding `key.path`
8994
+ * around the hit column.
8995
+ *
8996
+ * The hit (innermost) is built by inlining `columns[key.column].getQuery()`
8997
+ * — recursing into the hit's own recipe — so wrapping layers on the hit
8998
+ * (Overridden / Filtered / nested Discovered) appear in the produced tree.
8999
+ * The previous `pframeSpec.buildQuery` path was a flat
9000
+ * {@link PObjectId}-only call and could not express that.
9001
+ *
9002
+ * Linkers stay as plain column references on the linker side of
9003
+ * `linkerJoin` (the spec node has no slot for a query-side linker); the
9004
+ * linker's recipe id is used directly. The frame registered in
9005
+ * {@link getSpec} carries each recipe's final spec under that same id, so
9006
+ * the engine resolves linker axes from the post-projection spec.
9007
+ *
9008
+ * Path ordering matches {@link ColumnDiscoveredKey.path}: `path[0]` is
9009
+ * outermost, `path[N-1]` is closest to the hit. We fold from the inside
9010
+ * out — innermost wrap first — so the result lines up with that convention.
9011
+ *
9012
+ * `columnQualifications` / `queriesQualifications` are not emitted here —
9013
+ * qualifications live on a {@link SpecQueryJoinEntry} wrapper (lost on
9014
+ * unwrapping to {@link SpecQuery}). External consumers apply them at the
9015
+ * outer join via {@link getColumnQualifications} / {@link getQueriesQualifications}.
9016
+ */
9017
+ buildSpecQuery() {
9018
+ const hitRecipe = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing column ${this.key.column}`);
9019
+ let query = rebrandLeafId(hitRecipe.getQuery(), hitRecipe.id, this.id);
9020
+ const path = this.key.path ?? [];
9021
+ for (let i = path.length - 1; i >= 0; i--) query = {
9022
+ type: "linkerJoin",
9023
+ linker: (this.columns[path[i].column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing linker column ${path[i].column}`)).getQuery(),
9024
+ secondary: [{ entry: query }]
9025
+ };
9026
+ return query;
9027
+ }
9028
+ };
9029
+ function referencedUniIdsOf(key) {
9030
+ return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
9031
+ }
9032
+ //#endregion
9033
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
9034
+ /**
9035
+ * Recipe wrapper that fixes the values of selected axes of an inner recipe
9036
+ * (axis slicing). The id is `FilteredPColumnId { source: inner.id,
9037
+ * axisFilters }`.
9038
+ *
9039
+ * Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.
9040
+ * Repeated {@link wrap} concatenates `axisFilters` at the current level.
9041
+ *
9042
+ * Layering: `withSpecs` on a Filtered recipe yields
9043
+ * `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.
9044
+ * The reverse layering (`Filtered<Overridden<...>>`) is not reachable via
9045
+ * the public interface.
9046
+ */
9047
+ var ColumnFilteredRecipe = class ColumnFilteredRecipe {
9048
+ inner;
9049
+ axisFilters;
9050
+ /**
9051
+ * Wrap any recipe with axis filters. If `inner` is already a
9052
+ * {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a
9053
+ * new Filtered sharing the original `inner`.
9054
+ *
9055
+ * Validates every axis index against `inner.getSpec().axesSpec` at
9056
+ * construction — throws on an out-of-range index. After {@link wrap}, the
9057
+ * recipe is guaranteed to be spec-complete.
9058
+ *
9059
+ * Order semantics: new filters are appended after existing ones, preserving
9060
+ * their relative order. AND composition is otherwise commutative; order
9061
+ * only affects canonicalize/equality.
9062
+ */
9063
+ static wrap(col, axisFilters) {
9064
+ const combined = col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;
9065
+ const base = col instanceof ColumnFilteredRecipe ? col.inner : col;
9066
+ if (combined.length === 0) throw new Error("ColumnFilteredRecipe.wrap: at least one axis filter must be provided");
9067
+ const innerSpec = base.getSpec();
9068
+ const fixed = /* @__PURE__ */ new Set();
9069
+ for (const [idx] of combined) {
9070
+ if (innerSpec.axesSpec[idx] === void 0) throw new Error(`ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`);
9071
+ fixed.add(idx);
9072
+ }
9073
+ if (fixed.size >= innerSpec.axesSpec.length) throw new Error(`ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`);
9074
+ return new ColumnFilteredRecipe(base, combined);
9075
+ }
9076
+ /**
9077
+ * Static counterpart to {@link wrap}: returns the resolution status of a
9078
+ * {@link ColumnFilteredKey} without constructing the recipe. Axis filters
9079
+ * do not add references — status collapses to the source's status.
9080
+ */
9081
+ static getStatusByKey(key, opts = {}) {
9082
+ if (typeof key.source !== "string") throw new Error("ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source");
9083
+ return ColumnRecipe.getStatus(key.source, opts);
9084
+ }
9085
+ id;
9086
+ specCache;
9087
+ queryCache;
9088
+ dataStatusCache;
9089
+ constructor(inner, axisFilters) {
9090
+ this.inner = inner;
9091
+ this.axisFilters = axisFilters;
9092
+ this.id = stringifyColumnFilteredId({
9093
+ source: inner.id,
9094
+ axisFilters
9095
+ });
9096
+ }
9097
+ /** Wrapped recipe — exposed so external walkers can descend. */
9098
+ getInner() {
9099
+ return this.inner;
9100
+ }
9101
+ /** Axis filters do not introduce references to other columns. */
9102
+ getReferencedIds() {
9103
+ return this.inner.getReferencedIds();
9104
+ }
9105
+ getDataStatus() {
9106
+ if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
9107
+ return this.dataStatusCache.value;
9108
+ }
9109
+ /**
9110
+ * Final spec — the inner spec with fixed axes removed. Indices in
9111
+ * `axisFilters` are positional against `inner.getSpec().axesSpec` and were
9112
+ * validated at {@link wrap} time.
9113
+ */
9114
+ getSpec() {
9115
+ if (this.specCache === void 0) this.specCache = { value: applyAxisFilters(this.inner.getSpec(), this.axisFilters) };
9116
+ return this.specCache.value;
9117
+ }
9118
+ /**
9119
+ * Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution
9120
+ * goes through the inner spec — guaranteed available since {@link wrap}
9121
+ * validated all indices at construction.
9122
+ */
9123
+ getQuery() {
9124
+ if (this.queryCache === void 0) {
9125
+ const innerQuery = this.inner.getQuery();
9126
+ if (this.axisFilters.length === 0) this.queryCache = { value: rebrandLeafId(innerQuery, this.inner.id, this.id) };
9127
+ else {
9128
+ const innerSpec = this.inner.getSpec();
9129
+ this.queryCache = { value: {
9130
+ type: "sliceAxes",
9131
+ input: rebrandLeafId(innerQuery, this.inner.id, this.id),
9132
+ axisFilters: this.axisFilters.map(([idx, value]) => ({
9133
+ axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),
9134
+ constant: value
9135
+ }))
9136
+ } };
9137
+ }
9138
+ }
9139
+ return this.queryCache.value;
9140
+ }
9141
+ /**
9142
+ * Filtered + overrides → Overridden<Filtered>. Overridden is always the
9143
+ * outermost layer.
9144
+ */
9145
+ withSpecs(overrides) {
9146
+ return ColumnOverriddenRecipe.wrap(this, overrides);
9147
+ }
9148
+ };
9149
+ function toAxisSelector(axis) {
9150
+ const selector = {
9151
+ name: axis.name,
9152
+ type: axis.type
9153
+ };
9154
+ if (axis.domain !== void 0 && Object.keys(axis.domain).length > 0) selector.domain = axis.domain;
9155
+ if (axis.contextDomain !== void 0 && Object.keys(axis.contextDomain).length > 0) selector.contextDomain = axis.contextDomain;
9156
+ return selector;
9157
+ }
9158
+ //#endregion
9159
+ //#region ../node_modules/.pnpm/lru-cache@11.5.1/node_modules/lru-cache/dist/esm/browser/index.min.js
9160
+ var L = { hasSubscribers: !1 }, S = L, W = L;
9161
+ var M = typeof performance == "object" && performance && typeof performance.now == "function" ? performance : Date;
9162
+ var D = () => S.hasSubscribers || W.hasSubscribers, j = /* @__PURE__ */ new Set(), I = typeof process == "object" && process ? process : {}, P = (u, e, t, i) => {
9163
+ typeof I.emitWarning == "function" ? I.emitWarning(u, e, t, i) : console.error(`[${t}] ${e}: ${u}`);
9164
+ }, k = (u) => !j.has(u);
9165
+ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(u) ? u <= Math.pow(2, 8) ? Uint8Array : u <= Math.pow(2, 16) ? Uint16Array : u <= Math.pow(2, 32) ? Uint32Array : u <= Number.MAX_SAFE_INTEGER ? O : null : null, O = class extends Array {
9166
+ constructor(e) {
9167
+ super(e), this.fill(0);
9168
+ }
9169
+ }, R = class u {
9170
+ heap;
9171
+ length;
9172
+ static #o = !1;
9173
+ static create(e) {
9174
+ let t = G(e);
9175
+ if (!t) return [];
9176
+ u.#o = !0;
9177
+ let i = new u(e, t);
9178
+ return u.#o = !1, i;
9179
+ }
9180
+ constructor(e, t) {
9181
+ if (!u.#o) throw new TypeError("instantiate Stack using Stack.create(n)");
9182
+ this.heap = new t(e), this.length = 0;
9183
+ }
9184
+ push(e) {
9185
+ this.heap[this.length++] = e;
9186
+ }
9187
+ pop() {
9188
+ return this.heap[--this.length];
9189
+ }
9190
+ }, U = class u {
9191
+ #o;
9192
+ #c;
9193
+ #S;
9194
+ #O;
9195
+ #w;
9196
+ #M;
9197
+ #I;
9198
+ #m;
9199
+ get perf() {
9200
+ return this.#m;
9201
+ }
9202
+ ttl;
9203
+ ttlResolution;
9204
+ ttlAutopurge;
9205
+ updateAgeOnGet;
9206
+ updateAgeOnHas;
9207
+ allowStale;
9208
+ noDisposeOnSet;
9209
+ noUpdateTTL;
9210
+ maxEntrySize;
9211
+ sizeCalculation;
9212
+ noDeleteOnFetchRejection;
9213
+ noDeleteOnStaleGet;
9214
+ allowStaleOnFetchAbort;
9215
+ allowStaleOnFetchRejection;
9216
+ ignoreFetchAbort;
9217
+ backgroundFetchSize;
9218
+ #n;
9219
+ #b;
9220
+ #s;
9221
+ #i;
9222
+ #t;
9223
+ #l;
9224
+ #u;
9225
+ #a;
9226
+ #h;
9227
+ #y;
9228
+ #r;
9229
+ #_;
9230
+ #F;
9231
+ #d;
9232
+ #g;
9233
+ #T;
9234
+ #U;
9235
+ #f;
9236
+ #x;
9237
+ static unsafeExposeInternals(e) {
9238
+ return {
9239
+ starts: e.#F,
9240
+ ttls: e.#d,
9241
+ autopurgeTimers: e.#g,
9242
+ sizes: e.#_,
9243
+ keyMap: e.#s,
9244
+ keyList: e.#i,
9245
+ valList: e.#t,
9246
+ next: e.#l,
9247
+ prev: e.#u,
9248
+ get head() {
9249
+ return e.#a;
9250
+ },
9251
+ get tail() {
9252
+ return e.#h;
9253
+ },
9254
+ free: e.#y,
9255
+ isBackgroundFetch: (t) => e.#e(t),
9256
+ backgroundFetch: (t, i, s, n) => e.#P(t, i, s, n),
9257
+ moveToTail: (t) => e.#L(t),
9258
+ indexes: (t) => e.#A(t),
9259
+ rindexes: (t) => e.#z(t),
9260
+ isStale: (t) => e.#p(t)
9261
+ };
9262
+ }
9263
+ get max() {
9264
+ return this.#o;
9265
+ }
9266
+ get maxSize() {
9267
+ return this.#c;
9268
+ }
9269
+ get calculatedSize() {
9270
+ return this.#b;
9271
+ }
9272
+ get size() {
9273
+ return this.#n;
9274
+ }
9275
+ get fetchMethod() {
9276
+ return this.#M;
9277
+ }
9278
+ get memoMethod() {
9279
+ return this.#I;
9280
+ }
9281
+ get dispose() {
9282
+ return this.#S;
9283
+ }
9284
+ get onInsert() {
9285
+ return this.#O;
9286
+ }
9287
+ get disposeAfter() {
9288
+ return this.#w;
9289
+ }
9290
+ constructor(e) {
9291
+ let { max: t = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: r, updateAgeOnHas: h, allowStale: a, dispose: o, onInsert: d, disposeAfter: y, noDisposeOnSet: _, noUpdateTTL: c, maxSize: g = 0, maxEntrySize: f = 0, sizeCalculation: b, fetchMethod: l, memoMethod: w, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: m, allowStaleOnFetchRejection: p, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, backgroundFetchSize: C = 1, perf: E } = e;
9292
+ if (this.backgroundFetchSize = C, E !== void 0 && typeof E?.now != "function") throw new TypeError("perf option must have a now() method if specified");
9293
+ if (this.#m = E ?? M, t !== 0 && !T(t)) throw new TypeError("max option must be a nonnegative integer");
9294
+ let v = t ? G(t) : Array;
9295
+ if (!v) throw new Error("invalid max value: " + t);
9296
+ if (this.#o = t, this.#c = g, this.maxEntrySize = f || this.#c, this.sizeCalculation = b, this.sizeCalculation) {
9297
+ if (!this.#c && !this.maxEntrySize) throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
9298
+ if (typeof this.sizeCalculation != "function") throw new TypeError("sizeCalculation set to non-function");
9299
+ }
9300
+ if (w !== void 0 && typeof w != "function") throw new TypeError("memoMethod must be a function if defined");
9301
+ if (this.#I = w, l !== void 0 && typeof l != "function") throw new TypeError("fetchMethod must be a function if specified");
9302
+ if (this.#M = l, this.#U = !!l, this.#s = /* @__PURE__ */ new Map(), this.#i = Array.from({ length: t }).fill(void 0), this.#t = Array.from({ length: t }).fill(void 0), this.#l = new v(t), this.#u = new v(t), this.#a = 0, this.#h = 0, this.#y = R.create(t), this.#n = 0, this.#b = 0, typeof o == "function" && (this.#S = o), typeof d == "function" && (this.#O = d), typeof y == "function" ? (this.#w = y, this.#r = []) : (this.#w = void 0, this.#r = void 0), this.#T = !!this.#S, this.#x = !!this.#O, this.#f = !!this.#w, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!c, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!p, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
9303
+ if (this.#c !== 0 && !T(this.#c)) throw new TypeError("maxSize must be a positive integer if specified");
9304
+ if (!T(this.maxEntrySize)) throw new TypeError("maxEntrySize must be a positive integer if specified");
9305
+ this.#X();
9306
+ }
9307
+ if (this.allowStale = !!a, this.noDeleteOnStaleGet = !!m, this.updateAgeOnGet = !!r, this.updateAgeOnHas = !!h, this.ttlResolution = T(s) || s === 0 ? s : 1, this.ttlAutopurge = !!n, this.ttl = i || 0, this.ttl) {
9308
+ if (!T(this.ttl)) throw new TypeError("ttl must be a positive integer if specified");
9309
+ this.#k();
9310
+ }
9311
+ if (this.#o === 0 && this.ttl === 0 && this.#c === 0) throw new TypeError("At least one of max, maxSize, or ttl is required");
9312
+ if (!this.ttlAutopurge && !this.#o && !this.#c) {
9313
+ let x = "LRU_CACHE_UNBOUNDED";
9314
+ k(x) && (j.add(x), P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", x, u));
9315
+ }
9316
+ }
9317
+ getRemainingTTL(e) {
9318
+ return this.#s.has(e) ? Infinity : 0;
9319
+ }
9320
+ #k() {
9321
+ let e = new O(this.#o), t = new O(this.#o);
9322
+ this.#d = e, this.#F = t;
9323
+ let i = this.ttlAutopurge ? Array.from({ length: this.#o }) : void 0;
9324
+ this.#g = i, this.#H = (h, a, o = this.#m.now()) => {
9325
+ t[h] = a !== 0 ? o : 0, e[h] = a, s(h, a);
9326
+ }, this.#D = (h) => {
9327
+ t[h] = e[h] !== 0 ? this.#m.now() : 0, s(h, e[h]);
9328
+ };
9329
+ let s = this.ttlAutopurge ? (h, a) => {
9330
+ if (i?.[h] && (clearTimeout(i[h]), i[h] = void 0), a && a !== 0 && i) {
9331
+ let o = setTimeout(() => {
9332
+ this.#p(h) && this.#E(this.#i[h], "expire");
9333
+ }, a + 1);
9334
+ o.unref && o.unref(), i[h] = o;
9335
+ }
9336
+ } : () => {};
9337
+ this.#v = (h, a) => {
9338
+ if (e[a]) {
9339
+ let o = e[a], d = t[a];
9340
+ if (!o || !d) return;
9341
+ h.ttl = o, h.start = d, h.now = n || r();
9342
+ h.remainingTTL = o - (h.now - d);
9343
+ }
9344
+ };
9345
+ let n = 0, r = () => {
9346
+ let h = this.#m.now();
9347
+ if (this.ttlResolution > 0) {
9348
+ n = h;
9349
+ let a = setTimeout(() => n = 0, this.ttlResolution);
9350
+ a.unref && a.unref();
9351
+ }
9352
+ return h;
9353
+ };
9354
+ this.getRemainingTTL = (h) => {
9355
+ let a = this.#s.get(h);
9356
+ if (a === void 0) return 0;
9357
+ let o = e[a], d = t[a];
9358
+ if (!o || !d) return Infinity;
9359
+ return o - ((n || r()) - d);
9360
+ }, this.#p = (h) => {
9361
+ let a = t[h], o = e[h];
9362
+ return !!o && !!a && (n || r()) - a > o;
9363
+ };
9364
+ }
9365
+ #D = () => {};
9366
+ #v = () => {};
9367
+ #H = () => {};
9368
+ #p = () => !1;
9369
+ #X() {
9370
+ let e = new O(this.#o);
9371
+ this.#b = 0, this.#_ = e, this.#R = (t) => {
9372
+ this.#b -= e[t], e[t] = 0;
9373
+ }, this.#N = (t, i, s, n) => {
9374
+ if (!T(s)) {
9375
+ if (this.#e(i)) return this.backgroundFetchSize;
9376
+ if (n) {
9377
+ if (typeof n != "function") throw new TypeError("sizeCalculation must be a function");
9378
+ if (s = n(i, t), !T(s)) throw new TypeError("sizeCalculation return invalid (expect positive integer)");
9379
+ } else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");
9380
+ }
9381
+ return s;
9382
+ }, this.#j = (t, i, s) => {
9383
+ if (e[t] = i, this.#c) {
9384
+ let n = this.#c - e[t];
9385
+ for (; this.#b > n;) this.#G(!0);
9386
+ }
9387
+ this.#b += e[t], s && (s.entrySize = i, s.totalCalculatedSize = this.#b);
9388
+ };
9389
+ }
9390
+ #R = (e) => {};
9391
+ #j = (e, t, i) => {};
9392
+ #N = (e, t, i, s) => {
9393
+ if (i || s) throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
9394
+ return 0;
9395
+ };
9396
+ *#A({ allowStale: e = this.allowStale } = {}) {
9397
+ if (this.#n) for (let t = this.#h; this.#V(t) && ((e || !this.#p(t)) && (yield t), t !== this.#a);) t = this.#u[t];
9398
+ }
9399
+ *#z({ allowStale: e = this.allowStale } = {}) {
9400
+ if (this.#n) for (let t = this.#a; this.#V(t) && ((e || !this.#p(t)) && (yield t), t !== this.#h);) t = this.#l[t];
9401
+ }
9402
+ #V(e) {
9403
+ return e !== void 0 && this.#s.get(this.#i[e]) === e;
9404
+ }
9405
+ *entries() {
9406
+ for (let e of this.#A()) this.#t[e] !== void 0 && this.#i[e] !== void 0 && !this.#e(this.#t[e]) && (yield [this.#i[e], this.#t[e]]);
9407
+ }
9408
+ *rentries() {
9409
+ for (let e of this.#z()) this.#t[e] !== void 0 && this.#i[e] !== void 0 && !this.#e(this.#t[e]) && (yield [this.#i[e], this.#t[e]]);
9410
+ }
9411
+ *keys() {
9412
+ for (let e of this.#A()) {
9413
+ let t = this.#i[e];
9414
+ t !== void 0 && !this.#e(this.#t[e]) && (yield t);
9415
+ }
9416
+ }
9417
+ *rkeys() {
9418
+ for (let e of this.#z()) {
9419
+ let t = this.#i[e];
9420
+ t !== void 0 && !this.#e(this.#t[e]) && (yield t);
9421
+ }
9422
+ }
9423
+ *values() {
9424
+ for (let e of this.#A()) this.#t[e] !== void 0 && !this.#e(this.#t[e]) && (yield this.#t[e]);
9425
+ }
9426
+ *rvalues() {
9427
+ for (let e of this.#z()) this.#t[e] !== void 0 && !this.#e(this.#t[e]) && (yield this.#t[e]);
9428
+ }
9429
+ [Symbol.iterator]() {
9430
+ return this.entries();
9431
+ }
9432
+ [Symbol.toStringTag] = "LRUCache";
9433
+ find(e, t = {}) {
9434
+ for (let i of this.#A()) {
9435
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
9436
+ if (n !== void 0 && e(n, this.#i[i], this)) return this.#C(this.#i[i], t);
9437
+ }
9438
+ }
9439
+ forEach(e, t = this) {
9440
+ for (let i of this.#A()) {
9441
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
9442
+ n !== void 0 && e.call(t, n, this.#i[i], this);
9443
+ }
9444
+ }
9445
+ rforEach(e, t = this) {
9446
+ for (let i of this.#z()) {
9447
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
9448
+ n !== void 0 && e.call(t, n, this.#i[i], this);
9449
+ }
9450
+ }
9451
+ purgeStale() {
9452
+ let e = !1;
9453
+ for (let t of this.#z({ allowStale: !0 })) this.#p(t) && (this.#E(this.#i[t], "expire"), e = !0);
9454
+ return e;
9455
+ }
9456
+ info(e) {
9457
+ let t = this.#s.get(e);
9458
+ if (t === void 0) return;
9459
+ let i = this.#t[t], s = this.#e(i) ? i.__staleWhileFetching : i;
9460
+ if (s === void 0) return;
9461
+ let n = { value: s };
9462
+ if (this.#d && this.#F) {
9463
+ let r = this.#d[t], h = this.#F[t];
9464
+ if (r && h) n.ttl = r - (this.#m.now() - h), n.start = Date.now();
9465
+ }
9466
+ return this.#_ && (n.size = this.#_[t]), n;
9467
+ }
9468
+ dump() {
9469
+ let e = [];
9470
+ for (let t of this.#A({ allowStale: !0 })) {
9471
+ let i = this.#i[t], s = this.#t[t], n = this.#e(s) ? s.__staleWhileFetching : s;
9472
+ if (n === void 0 || i === void 0) continue;
9473
+ let r = { value: n };
9474
+ if (this.#d && this.#F) {
9475
+ r.ttl = this.#d[t];
9476
+ let h = this.#m.now() - this.#F[t];
9477
+ r.start = Math.floor(Date.now() - h);
9478
+ }
9479
+ this.#_ && (r.size = this.#_[t]), e.unshift([i, r]);
9480
+ }
9481
+ return e;
9482
+ }
9483
+ load(e) {
9484
+ this.clear();
9485
+ for (let [t, i] of e) {
9486
+ if (i.start) {
9487
+ let s = Date.now() - i.start;
9488
+ i.start = this.#m.now() - s;
9489
+ }
9490
+ this.#W(t, i.value, i);
9491
+ }
9492
+ }
9493
+ set(e, t, i = {}) {
9494
+ let { status: s = S.hasSubscribers ? {} : void 0 } = i;
9495
+ i.status = s, s && (s.op = "set", s.key = e, t !== void 0 && (s.value = t), s.cache = this);
9496
+ let n = this.#W(e, t, i);
9497
+ return s && S.hasSubscribers && S.publish(s), n;
9498
+ }
9499
+ #W(e, t, i, s) {
9500
+ let { ttl: n = this.ttl, start: r, noDisposeOnSet: h = this.noDisposeOnSet, sizeCalculation: a = this.sizeCalculation, status: o } = i, d = this.#e(t);
9501
+ if (t === void 0) return o && (o.set = "deleted"), this.delete(e), this;
9502
+ let { noUpdateTTL: y = this.noUpdateTTL } = i;
9503
+ o && !d && (o.value = t);
9504
+ let _ = this.#N(e, t, i.size || 0, a, o);
9505
+ if (this.maxEntrySize && _ > this.maxEntrySize) return this.#E(e, "set"), o && (o.set = "miss", o.maxEntrySizeExceeded = !0), this;
9506
+ let c = this.#n === 0 ? void 0 : this.#s.get(e);
9507
+ if (c === void 0) c = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(!1) : this.#n, this.#i[c] = e, this.#t[c] = t, this.#s.set(e, c), this.#l[this.#h] = c, this.#u[c] = this.#h, this.#h = c, this.#n++, this.#j(c, _, o), o && (o.set = "add"), y = !1, this.#x && !d && this.#O?.(t, e, "add");
9508
+ else {
9509
+ this.#L(c);
9510
+ let g = this.#t[c];
9511
+ if (t !== g) {
9512
+ if (!h) if (this.#e(g)) {
9513
+ g !== s && g.__abortController.abort(/* @__PURE__ */ new Error("replaced"));
9514
+ let { __staleWhileFetching: f } = g;
9515
+ f !== void 0 && f !== t && (this.#T && this.#S?.(f, e, "set"), this.#f && this.#r?.push([
9516
+ f,
9517
+ e,
9518
+ "set"
9519
+ ]));
9520
+ } else this.#T && this.#S?.(g, e, "set"), this.#f && this.#r?.push([
9521
+ g,
9522
+ e,
9523
+ "set"
9524
+ ]);
9525
+ if (this.#R(c), this.#j(c, _, o), this.#t[c] = t, !d) {
9526
+ let f = g && this.#e(g) ? g.__staleWhileFetching : g, b = f === void 0 ? "add" : t !== f ? "replace" : "update";
9527
+ o && (o.set = b, f !== void 0 && (o.oldValue = f)), this.#x && this.onInsert?.(t, e, b);
9528
+ }
9529
+ } else d || (o && (o.set = "update"), this.#x && this.onInsert?.(t, e, "update"));
9530
+ }
9531
+ if (n !== 0 && !this.#d && this.#k(), this.#d && (y || this.#H(c, n, r), o && this.#v(o, c)), !h && this.#f && this.#r) {
9532
+ let g = this.#r, f;
9533
+ for (; f = g?.shift();) this.#w?.(...f);
9534
+ }
9535
+ return this;
9536
+ }
9537
+ pop() {
9538
+ try {
9539
+ for (; this.#n;) {
9540
+ let e = this.#t[this.#a];
9541
+ if (this.#G(!0), this.#e(e)) {
9542
+ if (e.__staleWhileFetching) return e.__staleWhileFetching;
9543
+ } else if (e !== void 0) return e;
9544
+ }
9545
+ } finally {
9546
+ if (this.#f && this.#r) {
9547
+ let e = this.#r, t;
9548
+ for (; t = e?.shift();) this.#w?.(...t);
9549
+ }
9550
+ }
9551
+ }
9552
+ #G(e) {
9553
+ let t = this.#a, i = this.#i[t], s = this.#t[t], n = this.#e(s);
9554
+ n && s.__abortController.abort(/* @__PURE__ */ new Error("evicted"));
9555
+ let r = n ? s.__staleWhileFetching : s;
9556
+ return (this.#T || this.#f) && r !== void 0 && (this.#T && this.#S?.(r, i, "evict"), this.#f && this.#r?.push([
9557
+ r,
9558
+ i,
9559
+ "evict"
9560
+ ])), this.#R(t), this.#g?.[t] && (clearTimeout(this.#g[t]), this.#g[t] = void 0), e && (this.#i[t] = void 0, this.#t[t] = void 0, this.#y.push(t)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t], this.#s.delete(i), this.#n--, t;
9561
+ }
9562
+ has(e, t = {}) {
9563
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
9564
+ t.status = i, i && (i.op = "has", i.key = e, i.cache = this);
9565
+ let s = this.#Y(e, t);
9566
+ return S.hasSubscribers && S.publish(i), s;
9567
+ }
9568
+ #Y(e, t = {}) {
9569
+ let { updateAgeOnHas: i = this.updateAgeOnHas, status: s } = t, n = this.#s.get(e);
9570
+ if (n !== void 0) {
9571
+ let r = this.#t[n];
9572
+ if (this.#e(r) && r.__staleWhileFetching === void 0) return !1;
9573
+ if (this.#p(n)) s && (s.has = "stale", this.#v(s, n));
9574
+ else return i && this.#D(n), s && (s.has = "hit", this.#v(s, n)), !0;
9575
+ } else s && (s.has = "miss");
9576
+ return !1;
9577
+ }
9578
+ peek(e, t = {}) {
9579
+ let { status: i = D() ? {} : void 0 } = t;
9580
+ i && (i.op = "peek", i.key = e, i.cache = this), t.status = i;
9581
+ let s = this.#J(e, t);
9582
+ return S.hasSubscribers && S.publish(i), s;
9583
+ }
9584
+ #J(e, t) {
9585
+ let { status: i, allowStale: s = this.allowStale } = t, n = this.#s.get(e);
9586
+ if (n === void 0 || !s && this.#p(n)) {
9587
+ i && (i.peek = n === void 0 ? "miss" : "stale");
9588
+ return;
9589
+ }
9590
+ let r = this.#t[n], h = this.#e(r) ? r.__staleWhileFetching : r;
9591
+ return i && (h !== void 0 ? (i.peek = "hit", i.value = h) : i.peek = "miss"), h;
9592
+ }
9593
+ #P(e, t, i, s) {
9594
+ let n = t === void 0 ? void 0 : this.#t[t];
9595
+ if (this.#e(n)) return n;
9596
+ let r = new AbortController(), { signal: h } = i;
9597
+ h?.addEventListener("abort", () => r.abort(h.reason), { signal: r.signal });
9598
+ let a = {
9599
+ signal: r.signal,
9600
+ options: i,
9601
+ context: s
9602
+ }, o = (f, b = !1) => {
9603
+ let { aborted: l } = r.signal, w = i.ignoreFetchAbort && f !== void 0, F = i.ignoreFetchAbort || !!(i.allowStaleOnFetchAbort && f !== void 0);
9604
+ if (i.status && (l && !b ? (i.status.fetchAborted = !0, i.status.fetchError = r.signal.reason, w && (i.status.fetchAbortIgnored = !0)) : i.status.fetchResolved = !0), l && !w && !b) return y(r.signal.reason, F);
9605
+ let m = c, p = this.#t[t];
9606
+ return (p === c || p === void 0 && w && b) && (f === void 0 ? m.__staleWhileFetching !== void 0 ? this.#t[t] = m.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = !0), this.#W(e, f, a.options, m))), f;
9607
+ }, d = (f) => (i.status && (i.status.fetchRejected = !0, i.status.fetchError = f), y(f, !1)), y = (f, b) => {
9608
+ let { aborted: l } = r.signal, w = l && i.allowStaleOnFetchAbort, F = w || i.allowStaleOnFetchRejection, m = F || i.noDeleteOnFetchRejection, p = c;
9609
+ if (this.#t[t] === c && (!m || !b && p.__staleWhileFetching === void 0 ? this.#E(e, "fetch") : w || (this.#t[t] = p.__staleWhileFetching)), F) return i.status && p.__staleWhileFetching !== void 0 && (i.status.returnedStale = !0), p.__staleWhileFetching;
9610
+ if (p.__returned === p) throw f;
9611
+ }, _ = (f, b) => {
9612
+ let l = this.#M?.(e, n, a);
9613
+ r.signal.addEventListener("abort", () => {
9614
+ (!i.ignoreFetchAbort || i.allowStaleOnFetchAbort) && (f(void 0), i.allowStaleOnFetchAbort && (f = (w) => o(w, !0)));
9615
+ }), l && l instanceof Promise ? l.then((w) => f(w === void 0 ? void 0 : w), b) : l !== void 0 && f(l);
9616
+ };
9617
+ i.status && (i.status.fetchDispatched = !0);
9618
+ let c = new Promise(_).then(o, d), g = Object.assign(c, {
9619
+ __abortController: r,
9620
+ __staleWhileFetching: n,
9621
+ __returned: void 0
9622
+ });
9623
+ return t === void 0 ? (this.#W(e, g, {
9624
+ ...a.options,
9625
+ status: void 0
9626
+ }), t = this.#s.get(e)) : this.#t[t] = g, g;
9627
+ }
9628
+ #e(e) {
9629
+ if (!this.#U) return !1;
9630
+ let t = e;
9631
+ return !!t && t instanceof Promise && t.hasOwnProperty("__staleWhileFetching") && t.__abortController instanceof AbortController;
9632
+ }
9633
+ fetch(e, t = {}) {
9634
+ let i = W.hasSubscribers, { status: s = D() ? {} : void 0 } = t;
9635
+ t.status = s, s && t.context && (s.context = t.context);
9636
+ let n = this.#B(e, t);
9637
+ return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
9638
+ }
9639
+ async #B(e, t = {}) {
9640
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: r = this.ttl, noDisposeOnSet: h = this.noDisposeOnSet, size: a = 0, sizeCalculation: o = this.sizeCalculation, noUpdateTTL: d = this.noUpdateTTL, noDeleteOnFetchRejection: y = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: c = this.ignoreFetchAbort, allowStaleOnFetchAbort: g = this.allowStaleOnFetchAbort, context: f, forceRefresh: b = !1, status: l, signal: w } = t;
9641
+ if (l && (l.op = "fetch", l.key = e, b && (l.forceRefresh = !0), l.cache = this), !this.#U) return l && (l.fetch = "get"), this.#C(e, {
9642
+ allowStale: i,
9643
+ updateAgeOnGet: s,
9644
+ noDeleteOnStaleGet: n,
9645
+ status: l
9646
+ });
9647
+ let F = {
9648
+ allowStale: i,
9649
+ updateAgeOnGet: s,
9650
+ noDeleteOnStaleGet: n,
9651
+ ttl: r,
9652
+ noDisposeOnSet: h,
9653
+ size: a,
9654
+ sizeCalculation: o,
9655
+ noUpdateTTL: d,
9656
+ noDeleteOnFetchRejection: y,
9657
+ allowStaleOnFetchRejection: _,
9658
+ allowStaleOnFetchAbort: g,
9659
+ ignoreFetchAbort: c,
9660
+ status: l,
9661
+ signal: w
9662
+ }, m = this.#s.get(e);
9663
+ if (m === void 0) {
9664
+ l && (l.fetch = "miss");
9665
+ let p = this.#P(e, m, F, f);
9666
+ return p.__returned = p;
9667
+ } else {
9668
+ let p = this.#t[m];
9669
+ if (this.#e(p)) {
9670
+ let v = i && p.__staleWhileFetching !== void 0;
9671
+ return l && (l.fetch = "inflight", v && (l.returnedStale = !0)), v ? p.__staleWhileFetching : p.__returned = p;
9672
+ }
9673
+ let A = this.#p(m);
9674
+ if (!b && !A) return l && (l.fetch = "hit"), this.#L(m), s && this.#D(m), l && this.#v(l, m), p;
9675
+ let z = this.#P(e, m, F, f), E = z.__staleWhileFetching !== void 0 && i;
9676
+ return l && (l.fetch = A ? "stale" : "refresh", E && A && (l.returnedStale = !0)), E ? z.__staleWhileFetching : z.__returned = z;
9677
+ }
9678
+ }
9679
+ forceFetch(e, t = {}) {
9680
+ let i = W.hasSubscribers, { status: s = D() ? {} : void 0 } = t;
9681
+ t.status = s, s && t.context && (s.context = t.context);
9682
+ let n = this.#K(e, t);
9683
+ return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
9684
+ }
9685
+ async #K(e, t = {}) {
9686
+ let i = await this.#B(e, t);
9687
+ if (i === void 0) throw new Error("fetch() returned undefined");
9688
+ return i;
9689
+ }
9690
+ memo(e, t = {}) {
9691
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
9692
+ t.status = i, i && (i.op = "memo", i.key = e, t.context && (i.context = t.context), i.cache = this);
9693
+ let s = this.#Q(e, t);
9694
+ return i && (i.value = s), S.hasSubscribers && S.publish(i), s;
9695
+ }
9696
+ #Q(e, t = {}) {
9697
+ let i = this.#I;
9698
+ if (!i) throw new Error("no memoMethod provided to constructor");
9699
+ let { context: s, status: n, forceRefresh: r, ...h } = t;
9700
+ n && r && (n.forceRefresh = !0);
9701
+ let a = this.#C(e, h), o = r || a === void 0;
9702
+ if (n && (n.memo = o ? "miss" : "hit", o || (n.value = a)), !o) return a;
9703
+ let d = i(e, a, {
9704
+ options: h,
9705
+ context: s
9706
+ });
9707
+ return n && (n.value = d), this.#W(e, d, h), d;
9708
+ }
9709
+ get(e, t = {}) {
9710
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
9711
+ t.status = i, i && (i.op = "get", i.key = e, i.cache = this);
9712
+ let s = this.#C(e, t);
9713
+ return i && (s !== void 0 && (i.value = s), S.hasSubscribers && S.publish(i)), s;
9714
+ }
9715
+ #C(e, t = {}) {
9716
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: r } = t, h = this.#s.get(e);
9717
+ if (h === void 0) {
9718
+ r && (r.get = "miss");
9719
+ return;
9720
+ }
9721
+ let a = this.#t[h], o = this.#e(a);
9722
+ return r && this.#v(r, h), this.#p(h) ? o ? (r && (r.get = "stale-fetching"), i && a.__staleWhileFetching !== void 0 ? (r && (r.returnedStale = !0), a.__staleWhileFetching) : void 0) : (n || this.#E(e, "expire"), r && (r.get = "stale"), i ? (r && (r.returnedStale = !0), a) : void 0) : (r && (r.get = o ? "fetching" : "hit"), this.#L(h), s && this.#D(h), o ? a.__staleWhileFetching : a);
9723
+ }
9724
+ #$(e, t) {
9725
+ this.#u[t] = e, this.#l[e] = t;
9726
+ }
9727
+ #L(e) {
9728
+ e !== this.#h && (e === this.#a ? this.#a = this.#l[e] : this.#$(this.#u[e], this.#l[e]), this.#$(this.#h, e), this.#h = e);
9729
+ }
9730
+ delete(e) {
9731
+ return this.#E(e, "delete");
9732
+ }
9733
+ #E(e, t) {
9734
+ S.hasSubscribers && S.publish({
9735
+ op: "delete",
9736
+ delete: t,
9737
+ key: e,
9738
+ cache: this
9739
+ });
9740
+ let i = !1;
9741
+ if (this.#n !== 0) {
9742
+ let s = this.#s.get(e);
9743
+ if (s !== void 0) if (this.#g?.[s] && (clearTimeout(this.#g?.[s]), this.#g[s] = void 0), i = !0, this.#n === 1) this.#q(t);
9744
+ else {
9745
+ this.#R(s);
9746
+ let n = this.#t[s];
9747
+ if (this.#e(n) ? n.__abortController.abort(/* @__PURE__ */ new Error("deleted")) : (this.#T || this.#f) && (this.#T && this.#S?.(n, e, t), this.#f && this.#r?.push([
9748
+ n,
9749
+ e,
9750
+ t
9751
+ ])), this.#s.delete(e), this.#i[s] = void 0, this.#t[s] = void 0, s === this.#h) this.#h = this.#u[s];
9752
+ else if (s === this.#a) this.#a = this.#l[s];
9753
+ else {
9754
+ let r = this.#u[s];
9755
+ this.#l[r] = this.#l[s];
9756
+ let h = this.#l[s];
9757
+ this.#u[h] = this.#u[s];
9758
+ }
9759
+ this.#n--, this.#y.push(s);
9760
+ }
9761
+ }
9762
+ if (this.#f && this.#r?.length) {
9763
+ let s = this.#r, n;
9764
+ for (; n = s?.shift();) this.#w?.(...n);
9765
+ }
9766
+ return i;
9767
+ }
9768
+ clear() {
9769
+ return this.#q("delete");
9770
+ }
9771
+ #q(e) {
9772
+ for (let t of this.#z({ allowStale: !0 })) {
9773
+ let i = this.#t[t];
9774
+ if (this.#e(i)) i.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
9775
+ else {
9776
+ let s = this.#i[t];
9777
+ this.#T && this.#S?.(i, s, e), this.#f && this.#r?.push([
9778
+ i,
9779
+ s,
9780
+ e
9781
+ ]);
9782
+ }
9783
+ }
9784
+ if (this.#s.clear(), this.#t.fill(void 0), this.#i.fill(void 0), this.#d && this.#F) {
9785
+ this.#d.fill(0), this.#F.fill(0);
9786
+ for (let t of this.#g ?? []) t !== void 0 && clearTimeout(t);
9787
+ this.#g?.fill(void 0);
9788
+ }
9789
+ if (this.#_ && this.#_.fill(0), this.#a = 0, this.#h = 0, this.#y.length = 0, this.#b = 0, this.#n = 0, this.#f && this.#r) {
9790
+ let t = this.#r, i;
9791
+ for (; i = t?.shift();) this.#w?.(...i);
9792
+ }
9793
+ }
9794
+ };
9795
+ //#endregion
9796
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
9797
+ /**
9798
+ * Unified memoised factory dispatching to the right provider flavour by the
9799
+ * source shape:
9800
+ * - `TreeNodeAccessor` → {@link AccessorColumnsProvider}
9801
+ * (indexed by `root.handle`, walks the accessor tree once per root).
9802
+ * - `UpstreamBlockCtx<AccessorHandle>[]` (or omitted — pulled from the
9803
+ * ambient ctx) → {@link ResultPoolColumnsProvider}
9804
+ * (indexed by a content-hash of the block list).
9805
+ *
9806
+ * Both branches return cached instances within their LRU window, so repeated
9807
+ * calls with the same source skip re-walking / re-hashing.
9808
+ */
9809
+ function ColumnsProvider(source) {
9810
+ if (isNil(source) || Array.isArray(source)) return ResultPoolColumnsProvider(source);
9811
+ else if (source instanceof TreeNodeAccessor) return AccessorColumnsProvider(source);
9812
+ else throw new Error("Unknown columns provider source");
9813
+ }
9814
+ /**
9815
+ * Memoised constructor — same `root.handle` returns the same
9816
+ * {@link AccessorColumnsProviderImpl}, so `indexAccessorRoot` runs once per
9817
+ * accessor root (within the LRU window).
9818
+ */
9819
+ const _accessorProviderCache = new U({ max: 64 });
9820
+ function AccessorColumnsProvider(root) {
9821
+ let provider = _accessorProviderCache.get(root.handle);
9822
+ if (provider === void 0) {
9823
+ provider = new AccessorColumnsProviderImpl(root);
9824
+ _accessorProviderCache.set(root.handle, provider);
9825
+ }
9826
+ return provider;
9827
+ }
9828
+ /**
9829
+ * Memoised constructor — same `rawPool` content returns the same
9830
+ * {@link ResultPoolColumnsProviderImpl}, so `indexPoolBlock` runs once per
9831
+ * pool snapshot (within the LRU window).
9832
+ */
9833
+ const _resultPoolProviderCache = new U({ max: 4 });
9834
+ function ResultPoolColumnsProvider(rawPool = getCfgRenderCtx().getUpstreamBlockCtx()) {
9835
+ const key = hashRawPool(rawPool);
9836
+ let provider = _resultPoolProviderCache.get(key);
9837
+ if (provider === void 0) {
9838
+ provider = new ResultPoolColumnsProviderImpl(rawPool);
9839
+ _resultPoolProviderCache.set(key, provider);
9840
+ }
9841
+ return provider;
9842
+ }
9843
+ /**
9844
+ * Sandbox-specific provider over a {@link TreeNodeAccessor} root. Uses the
9845
+ * accessor's own `resolvePath` as the canonical root path for id construction,
9846
+ * and adds `getColumns()` returning {@link ColumnLazy}s on top of the generic
9847
+ * entries index.
9848
+ */
9849
+ var AccessorColumnsProviderImpl = class extends AccessorEntriesProvider {
9850
+ cachedColumns;
9851
+ constructor(root) {
9852
+ super(root, root.resolvePath);
9853
+ }
9854
+ getColumns() {
9855
+ if (this.cachedColumns !== void 0) return this.cachedColumns;
9856
+ return this.cachedColumns = Array.from(this.entries.values()).map((e) => ColumnLazyImpl.fromAccessor(e)).filter((v) => !isNil(v));
9857
+ }
9858
+ };
9859
+ /**
9860
+ * Sandbox-specific result-pool provider. Accepts the raw handle-shaped blocks
9861
+ * returned by {@link GlobalCfgRenderCtxMethods.getUpstreamBlockCtx} and
9862
+ * wraps them into {@link TreeNodeAccessor}s, then adds `getColumns()`.
9863
+ */
9864
+ var ResultPoolColumnsProviderImpl = class extends ResultPoolEntriesProvider {
9865
+ cachedColumns;
9866
+ constructor(rawPool = getCfgRenderCtx().getUpstreamBlockCtx()) {
9867
+ const blocks = rawPool.map((b) => ({
9868
+ blockId: b.blockId,
9869
+ prodCtx: b.prodCtx !== void 0 ? new TreeNodeAccessor(b.prodCtx, [b.blockId, "prodCtx"]) : void 0,
9870
+ stagingCtx: b.stagingCtx !== void 0 ? new TreeNodeAccessor(b.stagingCtx, [b.blockId, "stagingCtx"]) : void 0,
9871
+ prodIncomplete: b.prodIncomplete,
9872
+ stagingIncomplete: b.stagingIncomplete
9873
+ }));
9874
+ super(blocks);
9875
+ }
9876
+ getColumns() {
9877
+ if (this.cachedColumns !== void 0) return this.cachedColumns;
9878
+ return this.cachedColumns = Array.from(this.getPObjectEntries().values()).map((e) => ColumnLazyImpl.fromAccessor(e)).filter((v) => !isNil(v));
9879
+ }
9880
+ };
9881
+ function hashRawPool(rawPool) {
9882
+ return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
9883
+ }
9884
+ //#endregion
9885
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
9886
+ /**
9887
+ * Build the default set of ColumnsProviders for the ambient render ctx:
9888
+ * - `AccessorColumnsProvider` over `outputs` (if present)
9889
+ * - `AccessorColumnsProvider` over `prerun` (if present)
9890
+ * - `ResultPoolColumnsProvider` over `rawResultPool`
9891
+ *
9892
+ * Pulls handles directly from the ambient `cfgRenderCtx`. Returns `[]` when
9893
+ * called outside a render context.
9894
+ *
9895
+ * Result is memoised per-ctx (WeakMap → array). Repeated calls within the
9896
+ * same render cycle return the same provider triplet — inner providers are
9897
+ * also LRU-memoised by their content keys, so even a cache miss here doesn't
9898
+ * re-walk the trees.
9899
+ */
9900
+ const _ctxProvidersCache = /* @__PURE__ */ new WeakMap();
9901
+ function getCtxProviders(deps) {
9902
+ const ctx = deps?.ctx ?? getCfgRenderCtx();
9903
+ const cached = _ctxProvidersCache.get(ctx);
9904
+ if (cached !== void 0) return cached;
9905
+ const providers = [];
9906
+ const outputs = ctx.getAccessorHandleByName(MainAccessorName);
9907
+ if (outputs !== void 0) providers.push(ColumnsProvider(new TreeNodeAccessor(outputs, [MainAccessorName])));
9908
+ const prerun = ctx.getAccessorHandleByName(StagingAccessorName);
9909
+ if (prerun !== void 0) providers.push(ColumnsProvider(new TreeNodeAccessor(prerun, [StagingAccessorName])));
9910
+ providers.push(ColumnsProvider(ctx.getUpstreamBlockCtx()));
9911
+ _ctxProvidersCache.set(ctx, providers);
9912
+ return providers;
9913
+ }
9914
+ //#endregion
9915
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_lazy.js
9916
+ /**
9917
+ * Thrown by leaf-recipe factories when the requested column is provably
9918
+ * absent in the active render ctx — i.e. every relevant accessor reports
9919
+ * `inputsLocked` and the column did not appear. Distinct from the
9920
+ * `undefined` return that the factories still use for the "resolving" case
9921
+ * (the column may still appear later).
9922
+ *
9923
+ * Catch at the boundary (resolver / filter+sort wiring / data-table assembly)
9924
+ * when partial absence should be surfaced to the user rather than silently
9925
+ * producing an empty result.
9926
+ */
9927
+ var ColumnAbsentError = class extends Error {
9928
+ id;
9929
+ constructor(id) {
9930
+ super(`Column is absent in the active render ctx and will not appear: ${id}`);
9931
+ this.id = id;
9932
+ this.name = "ColumnAbsentError";
9933
+ }
9934
+ };
9935
+ /**
9936
+ * ColumnLazy is the leaf-recipe building block: a {@link ColumnRecipe} whose
9937
+ * `id` is a bare {@link PObjectId} and whose readers are bound to a single
9938
+ * tree-accessor leaf. Layered encodings (Overridden / Discovered / Filtered)
9939
+ * are reified through their dedicated recipe classes and reference leaf
9940
+ * columns by id.
9941
+ */
9942
+ var ColumnLazyImpl = class ColumnLazyImpl {
9943
+ id;
9944
+ options;
9945
+ specCache;
9946
+ dataCache;
9947
+ dataStatusCache;
9948
+ constructor(id, options) {
9949
+ this.id = id;
9950
+ this.options = options;
9951
+ }
9952
+ /** A leaf-recipe references exactly one column — its own id. */
9953
+ getReferencedIds() {
9954
+ return [this.id];
9955
+ }
9956
+ getSpec() {
9957
+ if (this.specCache === void 0) this.specCache = { value: this.options.getSpec() };
9958
+ return this.specCache.value;
9959
+ }
9960
+ /** Leaf-shaped — points straight at `this.id`. */
9961
+ getQuery() {
9962
+ return {
9963
+ type: "column",
9964
+ column: this.id
9965
+ };
9966
+ }
9967
+ /** Leaf-only: not on the recipe interface — only the leaf can read data directly. */
9968
+ getData() {
9969
+ if (this.dataCache === void 0) this.dataCache = { value: this.options.getData() };
9970
+ return this.dataCache.value;
9971
+ }
9972
+ getDataStatus() {
9973
+ if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.options.getDataStatus() };
9974
+ return this.dataStatusCache.value;
9975
+ }
9976
+ /**
9977
+ * Overlay overrides → produces a {@link ColumnOverriddenRecipe} wrapping
9978
+ * this leaf. ColumnLazy itself stays bare (id remains a plain PObjectId);
9979
+ * layering lives entirely in the recipe wrappers.
9980
+ */
9981
+ withSpecs(overrides) {
9982
+ return ColumnOverriddenRecipe.wrap(this, overrides);
9983
+ }
9984
+ /**
9985
+ * Resolve via the ambient {@link ColumnRegistry}. Spec is resolved eagerly:
9986
+ * returns `undefined` if the leaf isn't reachable yet (resolving). Throws
9987
+ * {@link ColumnAbsentError} when every relevant accessor is `inputsLocked`
9988
+ * and the column did not appear — the column will not exist in this ctx.
9989
+ * Data and dataStatus stay lazy.
9990
+ */
9991
+ static fromId(id, { ctx } = {}) {
9992
+ const registry = new ColumnRegistry(getCtxProviders({ ctx }));
9993
+ const leaf = registry.resolve(id);
9994
+ if (isNil(leaf)) {
9995
+ if (registry.isFinal()) throw new ColumnAbsentError(id);
9996
+ return;
9997
+ }
9998
+ const spec = readSpecAccessor(leaf);
9999
+ if (isNil(spec)) {
10000
+ if (leaf.accessor.getInputsLocked()) throw new ColumnAbsentError(id);
10001
+ return;
10002
+ }
10003
+ if (!spec.hasData()) return void 0;
10004
+ return new ColumnLazyImpl(id, {
10005
+ getSpec: () => spec.getDataAsJson(),
10006
+ getData: () => readDataAccessor(leaf),
10007
+ getDataStatus: () => readDataStatus(leaf)
10008
+ });
10009
+ }
10010
+ /** {@link PlRef} wrapper over {@link fromId}. */
10011
+ static fromPlRef(ref) {
10012
+ return ColumnLazyImpl.fromId(createGlobalPObjectId(ref.blockId, ref.name));
10013
+ }
10014
+ /**
10015
+ * Bind directly to an accessor-backed {@link LeafEntry} — no registry.
10016
+ * Throws {@link ColumnAbsentError} if the leaf has no spec field and its
10017
+ * accessor is `inputsLocked`. Returns `undefined` while still resolving.
10018
+ */
10019
+ static fromAccessor(entry) {
10020
+ const spec = readSpecAccessor(entry);
10021
+ if (isNil(spec)) {
10022
+ if (entry.accessor.getInputsLocked()) throw new ColumnAbsentError(entry.id);
10023
+ return;
10024
+ }
10025
+ if (!spec.hasData()) return void 0;
10026
+ return new ColumnLazyImpl(entry.id, {
10027
+ getSpec: () => spec.getDataAsJson(),
10028
+ getData: () => readDataAccessor(entry),
10029
+ getDataStatus: () => readDataStatus(entry)
10030
+ });
10031
+ }
10032
+ /**
10033
+ * Wrap a materialised {@link PColumn}. If the input is already a
10034
+ * {@link ColumnLazy} it is returned as-is.
10035
+ */
10036
+ static fromColumn(column) {
10037
+ if (column instanceof ColumnLazyImpl) return column;
10038
+ return new ColumnLazyImpl(column.id, {
10039
+ getSpec: () => column.spec,
10040
+ getData: () => column.data,
10041
+ getDataStatus: () => "present"
10042
+ });
10043
+ }
10044
+ /**
10045
+ * Distinguishes `present` / `resolving` / `absent` for a {@link PObjectId}
10046
+ * in the active render ctx. Falls back to the registry's `isFinal()`
10047
+ * when the id has no entry — only then we can say `absent` instead of
10048
+ * `resolving`.
10049
+ */
10050
+ static getStatusById(id, { ctx } = {}) {
10051
+ const registry = new ColumnRegistry(getCtxProviders({ ctx }));
10052
+ const leaf = registry.resolve(id);
10053
+ if (isNil(leaf)) return registry.isFinal() ? "absent" : "resolving";
10054
+ return getLeafEntryStatus(leaf);
10055
+ }
10056
+ /** {@link PlRef} wrapper over {@link getStatusById}. */
10057
+ static getStatusByPlRef(ref, opts = {}) {
10058
+ return ColumnLazyImpl.getStatusById(createGlobalPObjectId(ref.blockId, ref.name), opts);
10059
+ }
10060
+ /** No registry — reads straight off the entry's accessor. */
10061
+ static getStatusByAccessor(entry) {
10062
+ return getLeafEntryStatus(entry);
10063
+ }
10064
+ };
10065
+ /**
10066
+ * Unified dispatcher — picks the right `ColumnLazyImpl.fromX` by source
10067
+ * shape. For ambiguous inputs callers can still use the explicit factories
10068
+ * (also attached as properties: `ColumnLazy.fromId`, `.fromPlRef`,
10069
+ * `.fromAccessor`, `.fromColumn`).
10070
+ */
10071
+ function ColumnLazyDispatch(source, opts = {}) {
10072
+ if (typeof source === "string") return ColumnLazyImpl.fromId(source, opts);
10073
+ if (source instanceof ColumnLazyImpl) return source;
10074
+ if ("accessor" in source) return ColumnLazyImpl.fromAccessor(source);
10075
+ if (isPlRef(source)) return ColumnLazyImpl.fromPlRef(source);
10076
+ if (isPColumn(source)) return ColumnLazyImpl.fromColumn(source);
10077
+ throw new Error("ColumnLazy: unknown source shape");
10078
+ }
10079
+ /**
10080
+ * Polymorphic counterpart to {@link ColumnLazyDispatch}: returns the
10081
+ * {@link ColumnResolutionStatus} for any factory input without constructing
10082
+ * the recipe. For already-materialised sources ({@link PColumn} value,
10083
+ * existing {@link ColumnLazy}) status is `present` by construction.
10084
+ */
10085
+ function ColumnLazyGetStatus(source, opts = {}) {
10086
+ if (typeof source === "string") return ColumnLazyImpl.getStatusById(source, opts);
10087
+ if (source instanceof ColumnLazyImpl) return "present";
10088
+ if ("accessor" in source) return ColumnLazyImpl.getStatusByAccessor(source);
10089
+ if (isPlRef(source)) return ColumnLazyImpl.getStatusByPlRef(source, opts);
10090
+ if (isPColumn(source)) return "present";
10091
+ throw new Error("ColumnLazy.getStatus: unknown source shape");
10092
+ }
10093
+ const ColumnLazy = Object.assign(ColumnLazyDispatch, {
10094
+ fromId: ColumnLazyImpl.fromId,
10095
+ fromPlRef: ColumnLazyImpl.fromPlRef,
10096
+ fromAccessor: ColumnLazyImpl.fromAccessor,
10097
+ fromColumn: ColumnLazyImpl.fromColumn,
10098
+ getStatus: ColumnLazyGetStatus,
10099
+ getStatusById: ColumnLazyImpl.getStatusById,
10100
+ getStatusByPlRef: ColumnLazyImpl.getStatusByPlRef,
10101
+ getStatusByAccessor: ColumnLazyImpl.getStatusByAccessor
10102
+ });
10103
+ const readSpecAccessor = memoizeByEntry(({ accessor, name }) => accessor.traverse({
10104
+ field: `${name}.spec`,
10105
+ assertFieldType: "Input",
10106
+ ignoreError: true
10107
+ }));
10108
+ /**
10109
+ * Per-entry counterpart to {@link readDataStatus}: tells whether the leaf's
10110
+ * **spec** can be read in this ctx, and — for the negative cases —
10111
+ * distinguishes `resolving` from `absent` via `getInputsLocked()`.
10112
+ *
10113
+ * - spec field not yet on the entry's accessor + inputs locked → `absent`
10114
+ * - spec field not yet on the entry's accessor + still resolving → `resolving`
10115
+ * - spec resource present but bytes not yet written → `resolving`
10116
+ * (transient — the spec resource is connected, just unfilled)
10117
+ * - spec resource present and `hasData()` → `present`
10118
+ */
10119
+ function getLeafEntryStatus(entry) {
10120
+ const spec = readSpecAccessor(entry);
10121
+ if (isNil(spec)) return entry.accessor.getInputsLocked() ? "absent" : "resolving";
10122
+ if (!spec.hasData()) return "resolving";
10123
+ return "present";
10124
+ }
10125
+ const readDataAccessor = memoizeByEntry(({ accessor, name }) => accessor.traverse({
10126
+ field: `${name}.data`,
10127
+ assertFieldType: "Input",
10128
+ ignoreError: true
10129
+ }));
10130
+ const readDataStatus = memoizeByEntry(({ accessor, name }) => {
10131
+ if (accessor.listInputFields().includes(`${name}.data`)) return "present";
10132
+ return accessor.getInputsLocked() ? "absent" : "resolving";
10133
+ });
10134
+ function memoizeByEntry(fn) {
10135
+ const cache = new U({ max: 1e3 });
10136
+ return (entry) => {
10137
+ const key = `${entry.accessor.handle}:${entry.name}`;
10138
+ let hit = cache.get(key);
10139
+ if (!hit) cache.set(key, hit = { value: fn(entry) });
10140
+ return hit.value;
10141
+ };
10142
+ }
10143
+ //#endregion
10144
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
10145
+ /**
10146
+ * Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
10147
+ * concrete recipe variant based on the id's encoding and recurses on
10148
+ * wrappers' inner `source`:
10149
+ *
10150
+ * - bare {@link PObjectId} (non-JSON) → `ColumnLazy.fromId`
10151
+ * - `ColumnDiscoveredKey` → {@link ColumnDiscoveredRecipe}
10152
+ * - `ColumnOverriddenKey { source, specOverrides }` → recurse on `source`,
10153
+ * then {@link ColumnOverriddenRecipe.wrap}
10154
+ * - `ColumnFilteredKey { source, axisFilters }` → recurse on `source`,
10155
+ * then {@link ColumnFilteredRecipe.wrap}
10156
+ *
10157
+ * Returns `undefined` for unsupported variants (e.g. AnchoredPColumnId,
10158
+ * which needs an anchor map to resolve) or when a nested source itself
10159
+ * cannot be built.
10160
+ */
10161
+ function ColumnRecipeBuild(id, opts = {}) {
10162
+ const parsed = parseColumnIdSafely(id);
10163
+ if (isPObjectKey(parsed)) return ColumnLazyImpl.fromId(id, opts);
10164
+ if (isColumnDiscoveredKey(parsed)) return ColumnDiscoveredRecipe.fromKey(parsed, opts);
10165
+ if (isColumnOverriddenKey(parsed)) {
10166
+ const inner = ColumnRecipe(parsed.source, opts);
10167
+ if (inner === void 0) return void 0;
10168
+ return ColumnOverriddenRecipe.wrap(inner, parsed.specOverrides);
10169
+ }
10170
+ if (isColumnFilteredKey(parsed)) {
10171
+ if (typeof parsed.source !== "string") throw new Error(`Unsupported ColumnRecipe id variant: filtered column with non-string source (${JSON.stringify(parsed.source)})`);
10172
+ const inner = ColumnRecipe(parsed.source, opts);
10173
+ if (inner === void 0) return void 0;
10174
+ return ColumnFilteredRecipe.wrap(inner, parsed.axisFilters);
10175
+ }
10176
+ throw new Error(`Unsupported ColumnRecipe id variant: ${id}`);
10177
+ }
10178
+ /**
10179
+ * Resolution status counterpart to {@link ColumnRecipeBuild}. Dispatches on
10180
+ * the parsed id shape to the matching `getStatusBy*` static — never
10181
+ * constructs the recipe. Use this at boundaries (resolver, filter/sort
10182
+ * targets) to throw early on `absent` instead of silently producing an empty
10183
+ * recipe via {@link ColumnRecipeBuild}.
10184
+ */
10185
+ function ColumnRecipeGetStatus(id, opts = {}) {
10186
+ const parsed = parseColumnIdSafely(id);
10187
+ if (isPObjectKey(parsed)) return ColumnLazyImpl.getStatusById(id, opts);
10188
+ if (isColumnDiscoveredKey(parsed)) return ColumnDiscoveredRecipe.getStatusByKey(parsed, opts);
10189
+ if (isColumnOverriddenKey(parsed)) return ColumnOverriddenRecipe.getStatusByKey(parsed, opts);
10190
+ if (isColumnFilteredKey(parsed)) return ColumnFilteredRecipe.getStatusByKey(parsed, opts);
10191
+ throw new Error(`Unsupported ColumnRecipe id variant: ${id}`);
10192
+ }
10193
+ const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
10194
+ //#endregion
10195
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column.js
10196
+ /**
10197
+ * Unified entry point — routes between the two top-level dispatchers:
10198
+ * - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
10199
+ * - object source (`PlRef` / `LeafEntry` / `PColumn` / `ColumnLazy`) → {@link ColumnLazy}
10200
+ *
10201
+ * `ColumnLazy` is itself a `ColumnRecipe<PObjectId>`, so the return type is
10202
+ * the common `ColumnRecipe`.
10203
+ */
10204
+ function Column(source, opts) {
10205
+ if (typeof source === "string") return ColumnRecipe(source, opts);
10206
+ return ColumnLazy(source, opts);
10207
+ }
8250
10208
  (/* @__PURE__ */ __commonJSMin(((exports, module) => {
8251
10209
  exports = module.exports = stringify;
8252
10210
  exports.getSerialize = serializer;
@@ -8319,8 +10277,7 @@ function migrateV1ToV2(v1) {
8319
10277
  receptor: "IG"
8320
10278
  },
8321
10279
  model: "esm2",
8322
- fidelity: v1.fidelity,
8323
- isExpanded: false
10280
+ fidelity: v1.fidelity
8324
10281
  })),
8325
10282
  embeddingsInitializedForAnchor: v1.scopesInitializedForAnchor,
8326
10283
  mem: v1.mem,
@@ -8328,11 +10285,28 @@ function migrateV1ToV2(v1) {
8328
10285
  defaultBlockLabel: v1.defaultBlockLabel
8329
10286
  };
8330
10287
  }
8331
- const blockDataModel = new DataModelBuilder().from("Ver_2026_05_29").migrate("Ver_2026_06_23_models", migrateV1ToV2).init(() => ({
8332
- embeddings: [],
8333
- mem: 32,
8334
- cpu: 16
8335
- }));
10288
+ /**
10289
+ * V2 (per-card model list) → V3 (single selection). The card list collapses to one
10290
+ * selection: take the first card (existing projects seeded at least one), dropping
10291
+ * the now-unused `id`. Empty list → blank selection (`{}`), so the UI re-seeds a
10292
+ * default on the next input connection.
10293
+ */
10294
+ function migrateV2ToV3(v2) {
10295
+ const first = v2.embeddings[0];
10296
+ return {
10297
+ inputAnchor: v2.inputAnchor,
10298
+ embedding: first ? {
10299
+ scope: first.scope,
10300
+ model: first.model,
10301
+ fidelity: first.fidelity
10302
+ } : {},
10303
+ embeddingInitializedForAnchor: v2.embeddingsInitializedForAnchor,
10304
+ mem: v2.mem,
10305
+ cpu: v2.cpu,
10306
+ defaultBlockLabel: v2.defaultBlockLabel
10307
+ };
10308
+ }
10309
+ const blockDataModel = new DataModelBuilder().from("Ver_2026_05_29").migrate("Ver_2026_06_23_models", migrateV1ToV2).migrate("Ver_2026_07_03_single_selection", migrateV2ToV3).init(() => ({ embedding: {} }));
8336
10310
  //#endregion
8337
10311
  //#region ../model/dist/scopes.js
8338
10312
  /**
@@ -8565,31 +10539,22 @@ const inputAnchorSpecs = [
8565
10539
  ];
8566
10540
  const platforma$1 = BlockModelV3.create(blockDataModel).args((data) => {
8567
10541
  if (data.inputAnchor === void 0) throw new Error("Select an input dataset");
8568
- if (data.embeddings.length === 0) throw new Error("Add at least one embedding");
8569
- const tasks = data.embeddings.map((card) => {
8570
- if (card.scope === void 0) throw new Error("Each embedding needs a sequence selected");
8571
- if (card.model === void 0) throw new Error("Each embedding needs a model selected");
8572
- if (!isCompatible(card.scope.feature, card.scope.isHeavy, card.scope.receptor, card.model)) throw new Error(`${card.model} cannot embed "${card.scope.label}"`);
8573
- return {
8574
- scope: card.scope,
8575
- model: card.model,
8576
- fidelity: card.model === "esm2" ? card.fidelity ?? "standard" : void 0
8577
- };
8578
- });
8579
- const seen = /* @__PURE__ */ new Set();
8580
- for (const t of tasks) {
8581
- const key = `${t.scope.id}|${t.model}|${t.fidelity ?? ""}`;
8582
- if (seen.has(key)) throw new Error(`"${t.scope.label}" is already being embedded with this model — remove the duplicate embedding.`);
8583
- seen.add(key);
8584
- }
8585
- tasks.sort((a, b) => a.scope.id.localeCompare(b.scope.id) || a.model.localeCompare(b.model) || (a.fidelity ?? "").localeCompare(b.fidelity ?? ""));
10542
+ const sel = data.embedding;
10543
+ if (sel.scope === void 0) throw new Error("Select a sequence to embed");
10544
+ if (sel.model === void 0) throw new Error("Select a model");
10545
+ if (!isCompatible(sel.scope.feature, sel.scope.isHeavy, sel.scope.receptor, sel.model)) throw new Error(`${sel.model} cannot embed "${sel.scope.label}"`);
10546
+ const task = {
10547
+ scope: sel.scope,
10548
+ model: sel.model,
10549
+ fidelity: sel.model === "esm2" ? sel.fidelity ?? "standard" : void 0
10550
+ };
8586
10551
  return {
8587
10552
  inputAnchor: data.inputAnchor,
8588
- embeddings: tasks,
10553
+ embeddings: [task],
8589
10554
  mem: data.mem,
8590
10555
  cpu: data.cpu
8591
10556
  };
8592
- }).prerunArgs(() => ({})).output("inputOptions", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs)).output("inputSpec", (ctx) => ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : void 0).output("availableScopes", (ctx) => {
10557
+ }).prerunArgs(() => ({})).output("inputOptions", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs)).output("availableScopes", (ctx) => {
8593
10558
  const ref = ctx.data.inputAnchor;
8594
10559
  if (ref === void 0) return void 0;
8595
10560
  const spec = ctx.resultPool.getPColumnSpecByRef(ref);
@@ -8617,7 +10582,14 @@ const platforma$1 = BlockModelV3.create(blockDataModel).args((data) => {
8617
10582
  field: "gpuAvailable",
8618
10583
  assertFieldType: "Input",
8619
10584
  allowPermanentAbsence: true
8620
- })?.getDataAsJson()).title(() => "Sequence Embeddings").subtitle((ctx) => ctx.data.defaultBlockLabel ?? "").sections(() => [{
10585
+ })?.getDataAsJson()).title(() => "Sequence Embeddings").subtitle((ctx) => {
10586
+ const parts = [];
10587
+ if (ctx.data.defaultBlockLabel) parts.push(ctx.data.defaultBlockLabel);
10588
+ const sel = ctx.data.embedding;
10589
+ if (sel.scope?.label) parts.push(sel.scope.label);
10590
+ if (sel.model) parts.push(EMBEDDING_MODELS[sel.model].label);
10591
+ return parts.join(" · ");
10592
+ }).sections(() => [{
8621
10593
  type: "link",
8622
10594
  href: "/",
8623
10595
  label: "Main"