@platforma-open/milaboratories.mixcr-clonotyping-2 2.21.0 → 2.21.2
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/block-pack/CHANGELOG.md +12 -0
- package/block-pack/main.plj.gz +0 -0
- package/block-pack/manifest.json +1 -1
- package/block-pack/model.json +1 -1
- package/block-pack/published.json +1 -1
- package/block-pack/ui.tgz +0 -0
- package/dist/AGENTS.d.ts +5808 -1489
- package/dist/AGENTS.d.ts.map +1 -1
- package/dist/index.d.ts +5808 -1489
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3703 -467
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -21,14 +21,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
24
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/plugin_handle.js
|
|
25
25
|
const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
|
|
26
26
|
/** Construct the output key for a plugin output in the block outputs map. */
|
|
27
27
|
function pluginOutputKey(handle, outputKey) {
|
|
28
28
|
return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
31
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage.js
|
|
32
32
|
/**
|
|
33
33
|
* Discriminator key for BlockStorage format detection.
|
|
34
34
|
* This unique hash-based key identifies data as BlockStorage vs legacy formats.
|
|
@@ -270,7 +270,7 @@ function getPluginData(rawStorage, handle) {
|
|
|
270
270
|
return pluginEntry.__data;
|
|
271
271
|
}
|
|
272
272
|
//#endregion
|
|
273
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
273
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_migrations.js
|
|
274
274
|
/** Create a DataVersioned wrapper with correct shape */
|
|
275
275
|
function makeVersionedData(version, data) {
|
|
276
276
|
return {
|
|
@@ -765,7 +765,7 @@ var DataModel = class DataModel {
|
|
|
765
765
|
}
|
|
766
766
|
};
|
|
767
767
|
//#endregion
|
|
768
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
768
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/internal.js
|
|
769
769
|
/** Utility code helping to identify whether the code is running in actual UI environment */
|
|
770
770
|
function isInUI() {
|
|
771
771
|
return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
|
|
@@ -835,7 +835,7 @@ function registerFutureAwait(handle, onResolve) {
|
|
|
835
835
|
futureResolves.get(handle).push(onResolve);
|
|
836
836
|
}
|
|
837
837
|
//#endregion
|
|
838
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
838
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
|
|
839
839
|
/**
|
|
840
840
|
* All facade callback names as constants.
|
|
841
841
|
* These are the source of truth - the interface is derived from these.
|
|
@@ -870,7 +870,7 @@ function registerFacadeCallbacks(callbacks) {
|
|
|
870
870
|
for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
|
|
871
871
|
}
|
|
872
872
|
//#endregion
|
|
873
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
873
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/future.js
|
|
874
874
|
var FutureRef = class FutureRef {
|
|
875
875
|
handle;
|
|
876
876
|
postProcess;
|
|
@@ -4471,7 +4471,7 @@ objectType({
|
|
|
4471
4471
|
to: numberType().min(1)
|
|
4472
4472
|
});
|
|
4473
4473
|
//#endregion
|
|
4474
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
4474
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/util.js
|
|
4475
4475
|
function assertNever(x) {
|
|
4476
4476
|
throw new Error("Unexpected object: " + x);
|
|
4477
4477
|
}
|
|
@@ -4483,7 +4483,7 @@ function uniqueBy(array, makeId) {
|
|
|
4483
4483
|
return [...new Map(array.map((e) => [makeId(e), e])).values()];
|
|
4484
4484
|
}
|
|
4485
4485
|
//#endregion
|
|
4486
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
4486
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
|
|
4487
4487
|
/**
|
|
4488
4488
|
* Type guard function that checks if the given value is a valid DataInfo.
|
|
4489
4489
|
*
|
|
@@ -4674,7 +4674,7 @@ function entriesToDataInfo(dataInfoEntries) {
|
|
|
4674
4674
|
}
|
|
4675
4675
|
}
|
|
4676
4676
|
//#endregion
|
|
4677
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
4677
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/errors.js
|
|
4678
4678
|
var ServiceError = class extends Error {
|
|
4679
4679
|
name = "ServiceError";
|
|
4680
4680
|
};
|
|
@@ -4698,7 +4698,7 @@ function ensureError(value) {
|
|
|
4698
4698
|
return new Error(stringifyValue(value));
|
|
4699
4699
|
}
|
|
4700
4700
|
//#endregion
|
|
4701
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
4701
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/json.js
|
|
4702
4702
|
var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
4703
4703
|
module.exports = function serialize(object) {
|
|
4704
4704
|
if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
|
|
@@ -4731,7 +4731,7 @@ function parseJsonSafely(value, fallback) {
|
|
|
4731
4731
|
}
|
|
4732
4732
|
}
|
|
4733
4733
|
//#endregion
|
|
4734
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
4734
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
|
|
4735
4735
|
function readMetadata(metadata, key) {
|
|
4736
4736
|
return metadata?.[key];
|
|
4737
4737
|
}
|
|
@@ -4982,9 +4982,6 @@ const PColumnName = {
|
|
|
4982
4982
|
Sequence: "pl7.app/vdj/sequence"
|
|
4983
4983
|
}
|
|
4984
4984
|
};
|
|
4985
|
-
function isLabelColumn(column) {
|
|
4986
|
-
return column.axesSpec.length === 1 && column.name === PColumnName.Label;
|
|
4987
|
-
}
|
|
4988
4985
|
/** Get column id and spec from a column */
|
|
4989
4986
|
function getColumnIdAndSpec(column) {
|
|
4990
4987
|
return {
|
|
@@ -5023,7 +5020,7 @@ function matchAxisId(query, target) {
|
|
|
5023
5020
|
return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
|
|
5024
5021
|
}
|
|
5025
5022
|
//#endregion
|
|
5026
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5023
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
|
|
5027
5024
|
const BOOLEAN_TYPES = /* @__PURE__ */ new Set([
|
|
5028
5025
|
"numericComparison",
|
|
5029
5026
|
"stringEquals",
|
|
@@ -5088,20 +5085,23 @@ function traverseQuerySpec(query, visitor) {
|
|
|
5088
5085
|
secondary: query.secondary.map(traverseEntry)
|
|
5089
5086
|
};
|
|
5090
5087
|
break;
|
|
5091
|
-
case "linkerJoin":
|
|
5088
|
+
case "linkerJoin": {
|
|
5089
|
+
const linker = "type" in query.linker ? query.linker : {
|
|
5090
|
+
type: "column",
|
|
5091
|
+
column: query.linker.column
|
|
5092
|
+
};
|
|
5092
5093
|
result = {
|
|
5093
5094
|
...query,
|
|
5094
|
-
linker:
|
|
5095
|
-
...query.linker,
|
|
5096
|
-
column: visitor.column(query.linker.column)
|
|
5097
|
-
},
|
|
5095
|
+
linker: traverseQuerySpec(linker, visitor),
|
|
5098
5096
|
secondary: query.secondary.map(traverseEntry)
|
|
5099
5097
|
};
|
|
5100
5098
|
break;
|
|
5099
|
+
}
|
|
5101
5100
|
case "filter":
|
|
5102
5101
|
case "sort":
|
|
5103
5102
|
case "sliceAxes":
|
|
5104
5103
|
case "transformColumns":
|
|
5104
|
+
case "specOverride":
|
|
5105
5105
|
result = {
|
|
5106
5106
|
...query,
|
|
5107
5107
|
input: traverseQuerySpec(query.input, visitor)
|
|
@@ -5112,19 +5112,28 @@ function traverseQuerySpec(query, visitor) {
|
|
|
5112
5112
|
return visitor.node ? visitor.node(result) : result;
|
|
5113
5113
|
}
|
|
5114
5114
|
/** Recursively maps all column references in a SpecQuery tree. */
|
|
5115
|
-
function mapSpecQueryColumns(query,
|
|
5116
|
-
return traverseQuerySpec(query,
|
|
5115
|
+
function mapSpecQueryColumns(query, visitor) {
|
|
5116
|
+
return traverseQuerySpec(query, visitor);
|
|
5117
|
+
}
|
|
5118
|
+
/** Collects all column references from a SpecQuery tree. */
|
|
5119
|
+
function collectSpecQueryColumns(query) {
|
|
5120
|
+
const result = [];
|
|
5121
|
+
traverseQuerySpec(query, { column: (c) => {
|
|
5122
|
+
result.push(c);
|
|
5123
|
+
return c;
|
|
5124
|
+
} });
|
|
5125
|
+
return result;
|
|
5117
5126
|
}
|
|
5118
5127
|
//#endregion
|
|
5119
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5128
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
|
|
5120
5129
|
function mapPTableDef(def, cb) {
|
|
5121
5130
|
return {
|
|
5122
5131
|
...def,
|
|
5123
5132
|
src: mapJoinEntry(def.src, cb)
|
|
5124
5133
|
};
|
|
5125
5134
|
}
|
|
5126
|
-
function mapPTableDefV2(def,
|
|
5127
|
-
return { query: mapSpecQueryColumns(def.query,
|
|
5135
|
+
function mapPTableDefV2(def, visitor) {
|
|
5136
|
+
return { query: mapSpecQueryColumns(def.query, visitor) };
|
|
5128
5137
|
}
|
|
5129
5138
|
function mapJoinEntry(entry, cb) {
|
|
5130
5139
|
switch (entry.type) {
|
|
@@ -5159,7 +5168,7 @@ function mapJoinEntry(entry, cb) {
|
|
|
5159
5168
|
}
|
|
5160
5169
|
}
|
|
5161
5170
|
//#endregion
|
|
5162
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5171
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
|
|
5163
5172
|
function getPTableColumnId(spec) {
|
|
5164
5173
|
switch (spec.type) {
|
|
5165
5174
|
case "axis": return {
|
|
@@ -5173,17 +5182,366 @@ function getPTableColumnId(spec) {
|
|
|
5173
5182
|
}
|
|
5174
5183
|
}
|
|
5175
5184
|
//#endregion
|
|
5176
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5185
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
|
|
5186
|
+
function stringifyColumnFilteredId(key) {
|
|
5187
|
+
return canonicalizeJson(createColumnFilteredKey(key));
|
|
5188
|
+
}
|
|
5189
|
+
function isColumnFilteredKey(obj) {
|
|
5190
|
+
return typeof obj === "object" && obj !== null && "__isFiltered" in obj;
|
|
5191
|
+
}
|
|
5192
|
+
function createColumnFilteredKey(props) {
|
|
5193
|
+
const axisFilters = props.axisFilters.toSorted((a, b) => a[0] - b[0]);
|
|
5194
|
+
return {
|
|
5195
|
+
__isFiltered: true,
|
|
5196
|
+
source: props.source,
|
|
5197
|
+
axisFilters
|
|
5198
|
+
};
|
|
5199
|
+
}
|
|
5200
|
+
/**
|
|
5201
|
+
* Drop the axes pinned by `axisFilters` from a {@link PColumnSpec}'s
|
|
5202
|
+
* `axesSpec`. Indices are positional against `spec.axesSpec`. Returns `spec`
|
|
5203
|
+
* unchanged when there are no filters.
|
|
5204
|
+
*
|
|
5205
|
+
* Single source of the Filtered-layer spec math — shared by
|
|
5206
|
+
* `reconstructSpecFromId` (host, id-walking) and `ColumnFilteredRecipe.getSpec`
|
|
5207
|
+
* (sandbox, recipe-graph walking).
|
|
5208
|
+
*/
|
|
5209
|
+
function applyAxisFilters(spec, axisFilters) {
|
|
5210
|
+
if (axisFilters.length === 0) return spec;
|
|
5211
|
+
const fixed = new Set(axisFilters.map(([i]) => i));
|
|
5212
|
+
return {
|
|
5213
|
+
...spec,
|
|
5214
|
+
axesSpec: spec.axesSpec.filter((_, i) => !fixed.has(i))
|
|
5215
|
+
};
|
|
5216
|
+
}
|
|
5217
|
+
//#endregion
|
|
5218
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
|
|
5219
|
+
function isPObjectId(value) {
|
|
5220
|
+
if (typeof value !== "string") return false;
|
|
5221
|
+
return isPObjectKey(parseJsonSafely(value));
|
|
5222
|
+
}
|
|
5223
|
+
function isPObjectKey(value) {
|
|
5224
|
+
return isLocalPObjectKey(value) || isGlobalPObjectKey(value);
|
|
5225
|
+
}
|
|
5226
|
+
function createPObjectId(obj) {
|
|
5227
|
+
if (isLocalPObjectKey(obj)) return createLocalPObjectId(obj.resolvePath, obj.name);
|
|
5228
|
+
if (isGlobalPObjectKey(obj)) return createGlobalPObjectId(obj.blockId, obj.name);
|
|
5229
|
+
throw new Error(`createPObjectId: unrecognized object key structure: ${JSON.stringify(obj)}`);
|
|
5230
|
+
}
|
|
5231
|
+
function createLocalPObjectId(resolvePath, name) {
|
|
5232
|
+
return canonicalizeJson({
|
|
5233
|
+
resolvePath,
|
|
5234
|
+
name
|
|
5235
|
+
});
|
|
5236
|
+
}
|
|
5237
|
+
function isLocalPObjectKey(value) {
|
|
5238
|
+
if (typeof value !== "object" || value === null) return false;
|
|
5239
|
+
const v = value;
|
|
5240
|
+
return Array.isArray(v.resolvePath) && typeof v.name === "string";
|
|
5241
|
+
}
|
|
5242
|
+
function createGlobalPObjectId(blockId, exportName) {
|
|
5243
|
+
return canonicalizeJson({
|
|
5244
|
+
__isRef: true,
|
|
5245
|
+
blockId,
|
|
5246
|
+
name: exportName
|
|
5247
|
+
});
|
|
5248
|
+
}
|
|
5249
|
+
function isGlobalPObjectKey(value) {
|
|
5250
|
+
if (typeof value !== "object" || value === null) return false;
|
|
5251
|
+
return "__isRef" in value && "blockId" in value && "name" in value;
|
|
5252
|
+
}
|
|
5253
|
+
function isPObject(obj) {
|
|
5254
|
+
return typeof obj === "object" && obj !== null && "id" in obj && "spec" in obj && "data" in obj;
|
|
5255
|
+
}
|
|
5256
|
+
function isPColumn(obj) {
|
|
5257
|
+
return isPObject(obj) && isPColumnSpec(obj.spec);
|
|
5258
|
+
}
|
|
5259
|
+
function isPColumnSpec(spec) {
|
|
5260
|
+
return spec.kind === "PColumn";
|
|
5261
|
+
}
|
|
5262
|
+
function ensurePColumn(obj) {
|
|
5263
|
+
if (!isPColumn(obj)) throw new Error(`not a PColumn (kind = ${obj.spec.kind})`);
|
|
5264
|
+
return obj;
|
|
5265
|
+
}
|
|
5266
|
+
function mapPObjectData(pObj, cb) {
|
|
5267
|
+
return pObj === void 0 ? void 0 : {
|
|
5268
|
+
...pObj,
|
|
5269
|
+
data: cb(pObj.data)
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
5272
|
+
function extractAllColumns(entry) {
|
|
5273
|
+
const columns = /* @__PURE__ */ new Map();
|
|
5274
|
+
const addAllColumns = (entry) => {
|
|
5275
|
+
switch (entry.type) {
|
|
5276
|
+
case "column":
|
|
5277
|
+
columns.set(entry.column.id, entry.column);
|
|
5278
|
+
return;
|
|
5279
|
+
case "slicedColumn":
|
|
5280
|
+
columns.set(entry.column.id, entry.column);
|
|
5281
|
+
return;
|
|
5282
|
+
case "artificialColumn":
|
|
5283
|
+
columns.set(entry.column.id, entry.column);
|
|
5284
|
+
return;
|
|
5285
|
+
case "inlineColumn": return;
|
|
5286
|
+
case "full":
|
|
5287
|
+
case "inner":
|
|
5288
|
+
for (const e of entry.entries) addAllColumns(e);
|
|
5289
|
+
return;
|
|
5290
|
+
case "outer":
|
|
5291
|
+
addAllColumns(entry.primary);
|
|
5292
|
+
for (const e of entry.secondary) addAllColumns(e);
|
|
5293
|
+
return;
|
|
5294
|
+
default: assertNever(entry);
|
|
5295
|
+
}
|
|
5296
|
+
};
|
|
5297
|
+
addAllColumns(entry);
|
|
5298
|
+
return [...columns.values()];
|
|
5299
|
+
}
|
|
5300
|
+
//#endregion
|
|
5301
|
+
//#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.4/node_modules/@milaboratories/helpers/dist/utils.js
|
|
5302
|
+
function isNil$1(v) {
|
|
5303
|
+
return v === null || v === void 0;
|
|
5304
|
+
}
|
|
5305
|
+
Array.isArray;
|
|
5306
|
+
function isObject(value) {
|
|
5307
|
+
return typeof value === "object" && value !== null;
|
|
5308
|
+
}
|
|
5309
|
+
/**
|
|
5310
|
+
* Checks if the given value is a plain object.
|
|
5311
|
+
*
|
|
5312
|
+
* A plain object is defined as an object created by the `{}` literal,
|
|
5313
|
+
* an object created with `Object.create(null)`, or an object with a
|
|
5314
|
+
* prototype that resolves to `Object.prototype`.
|
|
5315
|
+
*
|
|
5316
|
+
* @param value - The value to check.
|
|
5317
|
+
* @returns `true` if the value is a plain object, otherwise `false`.
|
|
5318
|
+
*
|
|
5319
|
+
* @example
|
|
5320
|
+
* ```typescript
|
|
5321
|
+
* isPlainObject({}); // true
|
|
5322
|
+
* isPlainObject(Object.create(null)); // true
|
|
5323
|
+
* isPlainObject(new Date()); // false
|
|
5324
|
+
* isPlainObject(null); // false
|
|
5325
|
+
* isPlainObject([]); // false
|
|
5326
|
+
* ```
|
|
5327
|
+
*/
|
|
5328
|
+
function isPlainObject(value) {
|
|
5329
|
+
if (!isObject(value)) return false;
|
|
5330
|
+
const prototype = Object.getPrototypeOf(value);
|
|
5331
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
5332
|
+
}
|
|
5333
|
+
//#endregion
|
|
5334
|
+
//#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.4/node_modules/@milaboratories/helpers/dist/error.js
|
|
5335
|
+
function throwError(v) {
|
|
5336
|
+
if (typeof v === "string") throw new Error(v);
|
|
5337
|
+
else throw v;
|
|
5338
|
+
}
|
|
5339
|
+
//#endregion
|
|
5340
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
|
|
5341
|
+
function isColumnDiscoveredKey(obj) {
|
|
5342
|
+
return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
|
|
5343
|
+
}
|
|
5344
|
+
function distillColumnDiscoveredKey(props) {
|
|
5345
|
+
return {
|
|
5346
|
+
__isDiscovered: true,
|
|
5347
|
+
column: props.column,
|
|
5348
|
+
path: Array.isArray(props.path) && props.path.length > 0 ? props.path : void 0,
|
|
5349
|
+
columnQualifications: Array.isArray(props.columnQualifications) && props.columnQualifications.length > 0 ? props.columnQualifications : void 0,
|
|
5350
|
+
queriesQualifications: props.queriesQualifications && Object.keys(props.queriesQualifications).length > 0 ? props.queriesQualifications : void 0
|
|
5351
|
+
};
|
|
5352
|
+
}
|
|
5353
|
+
function stringifyColumnDiscoveredId(id) {
|
|
5354
|
+
return canonicalizeJson(distillColumnDiscoveredKey({
|
|
5355
|
+
__isDiscovered: true,
|
|
5356
|
+
...id
|
|
5357
|
+
}));
|
|
5358
|
+
}
|
|
5359
|
+
//#endregion
|
|
5360
|
+
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/array/uniq.mjs
|
|
5361
|
+
function uniq(arr) {
|
|
5362
|
+
return [...new Set(arr)];
|
|
5363
|
+
}
|
|
5364
|
+
//#endregion
|
|
5365
|
+
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/array/uniqBy.mjs
|
|
5366
|
+
function uniqBy(arr, mapper) {
|
|
5367
|
+
const map = /* @__PURE__ */ new Map();
|
|
5368
|
+
for (let i = 0; i < arr.length; i++) {
|
|
5369
|
+
const item = arr[i];
|
|
5370
|
+
const key = mapper(item);
|
|
5371
|
+
if (!map.has(key)) map.set(key, item);
|
|
5372
|
+
}
|
|
5373
|
+
return Array.from(map.values());
|
|
5374
|
+
}
|
|
5375
|
+
//#endregion
|
|
5376
|
+
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/predicate/isFunction.mjs
|
|
5377
|
+
function isFunction(value) {
|
|
5378
|
+
return typeof value === "function";
|
|
5379
|
+
}
|
|
5380
|
+
//#endregion
|
|
5381
|
+
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/predicate/isNil.mjs
|
|
5382
|
+
function isNil(x) {
|
|
5383
|
+
return x == null;
|
|
5384
|
+
}
|
|
5385
|
+
//#endregion
|
|
5386
|
+
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/predicate/isString.mjs
|
|
5387
|
+
function isString(value) {
|
|
5388
|
+
return typeof value === "string";
|
|
5389
|
+
}
|
|
5390
|
+
//#endregion
|
|
5391
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
|
|
5177
5392
|
/**
|
|
5178
|
-
* Canonically serializes a
|
|
5179
|
-
* @
|
|
5180
|
-
*
|
|
5393
|
+
* Canonically serializes a column key to a branded string id. Accepts both
|
|
5394
|
+
* the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
|
|
5395
|
+
* (anchored / old filtered object form).
|
|
5181
5396
|
*/
|
|
5182
5397
|
function stringifyColumnId(id) {
|
|
5183
|
-
return (
|
|
5398
|
+
return canonicalizeJson(id);
|
|
5399
|
+
}
|
|
5400
|
+
function parseColumnIdSafely(str, fallback = void 0) {
|
|
5401
|
+
try {
|
|
5402
|
+
return JSON.parse(str);
|
|
5403
|
+
} catch {
|
|
5404
|
+
return fallback;
|
|
5405
|
+
}
|
|
5406
|
+
}
|
|
5407
|
+
/**
|
|
5408
|
+
* Walk a rich column id down to its terminal leaf {@link PObjectId}.
|
|
5409
|
+
*/
|
|
5410
|
+
function extractPObjectId(id) {
|
|
5411
|
+
if (isString(id)) {
|
|
5412
|
+
if (isPObjectId(id)) return id;
|
|
5413
|
+
return extractPObjectId(parseColumnIdSafely(id) ?? throwError(`extractPObjectId: id "${id}" is not a valid canonical column id`));
|
|
5414
|
+
}
|
|
5415
|
+
if (isPObjectKey(id)) return createPObjectId(id);
|
|
5416
|
+
if (isColumnFilteredKey(id)) return extractPObjectId(id.source);
|
|
5417
|
+
if (isColumnOverriddenKey(id)) return extractPObjectId(id.source);
|
|
5418
|
+
if (isColumnDiscoveredKey(id)) return extractPObjectId(id.column);
|
|
5419
|
+
throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
|
|
5420
|
+
}
|
|
5421
|
+
//#endregion
|
|
5422
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
|
|
5423
|
+
function isColumnOverriddenKey(obj) {
|
|
5424
|
+
return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
|
|
5425
|
+
}
|
|
5426
|
+
function distillColumnOverriddenKey(props) {
|
|
5427
|
+
return {
|
|
5428
|
+
__isOverridden: true,
|
|
5429
|
+
source: props.source,
|
|
5430
|
+
specOverrides: props.specOverrides
|
|
5431
|
+
};
|
|
5432
|
+
}
|
|
5433
|
+
function createColumnOverriddenId(props) {
|
|
5434
|
+
return stringifyColumnOverriddenId(createColumnOverriddenKey(props));
|
|
5435
|
+
}
|
|
5436
|
+
function createColumnOverriddenKey(props) {
|
|
5437
|
+
const { source, specOverrides } = props;
|
|
5438
|
+
const unwrapped = unwrapOverrides(source);
|
|
5439
|
+
return {
|
|
5440
|
+
__isOverridden: true,
|
|
5441
|
+
source: unwrapped ? unwrapped.source : source,
|
|
5442
|
+
specOverrides: unwrapped ? mergeSpecOverrides(unwrapped.specOverrides, specOverrides) : specOverrides
|
|
5443
|
+
};
|
|
5444
|
+
}
|
|
5445
|
+
function stringifyColumnOverriddenId(id) {
|
|
5446
|
+
return canonicalizeJson(distillColumnOverriddenKey(id));
|
|
5447
|
+
}
|
|
5448
|
+
/**
|
|
5449
|
+
* Peel one override-wrap layer.
|
|
5450
|
+
*
|
|
5451
|
+
* Invariant: `{source, specOverrides}` can only appear at the top level —
|
|
5452
|
+
* the inner `source` is never itself an override-wrap. Anything else throws.
|
|
5453
|
+
*/
|
|
5454
|
+
function unwrapOverrides(id) {
|
|
5455
|
+
const parsed = parseColumnIdSafely(id);
|
|
5456
|
+
if (parsed === void 0 || !isColumnOverriddenKey(parsed)) return void 0;
|
|
5457
|
+
const inner = parseColumnIdSafely(parsed.source);
|
|
5458
|
+
if (inner !== void 0 && isColumnOverriddenKey(inner)) throw new Error("nested override-wrap detected — invariant broken");
|
|
5459
|
+
return parsed;
|
|
5460
|
+
}
|
|
5461
|
+
/**
|
|
5462
|
+
* Apply `specOverrides` from a rich id (`SUniversalPColumnId`) on top of a
|
|
5463
|
+
* resolved {@link PColumnSpec}. Returns `base` unchanged when the id carries
|
|
5464
|
+
* no overrides.
|
|
5465
|
+
*/
|
|
5466
|
+
function applySpecOverrides(base, idOrOverride) {
|
|
5467
|
+
if (isNil(idOrOverride)) return base;
|
|
5468
|
+
const overrides = isString(idOrOverride) ? unwrapOverrides(idOrOverride)?.specOverrides : idOrOverride;
|
|
5469
|
+
if (isNil(overrides)) return base;
|
|
5470
|
+
const result = { ...base };
|
|
5471
|
+
if (overrides.annotations) result.annotations = mergeRecord(base.annotations, overrides.annotations);
|
|
5472
|
+
if (overrides.domain) result.domain = mergeRecord(base.domain, overrides.domain);
|
|
5473
|
+
if (overrides.contextDomain) result.contextDomain = mergeRecord(base.contextDomain, overrides.contextDomain);
|
|
5474
|
+
if (overrides.axesSpec) result.axesSpec = applyAxesPatches(base.axesSpec, overrides.axesSpec);
|
|
5475
|
+
return result;
|
|
5476
|
+
}
|
|
5477
|
+
/**
|
|
5478
|
+
* Compose two override patches: applying `mergeSpecOverrides(prior, next)` on
|
|
5479
|
+
* top of a base spec produces the same result as applying `prior` then `next`.
|
|
5480
|
+
*/
|
|
5481
|
+
function mergeSpecOverrides(prior, next) {
|
|
5482
|
+
const result = {};
|
|
5483
|
+
const axesSpec = mergeAxesPatches(prior.axesSpec, next.axesSpec);
|
|
5484
|
+
if (axesSpec !== void 0) result.axesSpec = axesSpec;
|
|
5485
|
+
const annotations = mergeRecord(prior.annotations, next.annotations);
|
|
5486
|
+
if (annotations !== void 0) result.annotations = annotations;
|
|
5487
|
+
const domain = mergeRecord(prior.domain, next.domain);
|
|
5488
|
+
if (domain !== void 0) result.domain = domain;
|
|
5489
|
+
const contextDomain = mergeRecord(prior.contextDomain, next.contextDomain);
|
|
5490
|
+
if (contextDomain !== void 0) result.contextDomain = contextDomain;
|
|
5491
|
+
return result;
|
|
5492
|
+
}
|
|
5493
|
+
/**
|
|
5494
|
+
* Apply positional `patches` onto `base.axesSpec`. Patches deep-merge
|
|
5495
|
+
* `annotations` / `domain` / `contextDomain` and shallow-override `name` /
|
|
5496
|
+
* `type` at their slot. Indices `>= base.length` append new axes; intermediate
|
|
5497
|
+
* gaps (if any) are filled with the patch itself, so callers should not leave
|
|
5498
|
+
* holes between base.length and the highest patched index.
|
|
5499
|
+
*/
|
|
5500
|
+
function applyAxesPatches(base, patches) {
|
|
5501
|
+
const result = base.slice();
|
|
5502
|
+
for (const [k, p] of Object.entries(patches)) {
|
|
5503
|
+
const i = Number(k);
|
|
5504
|
+
const existing = result[i];
|
|
5505
|
+
result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
|
|
5506
|
+
}
|
|
5507
|
+
return result;
|
|
5508
|
+
}
|
|
5509
|
+
/**
|
|
5510
|
+
* Compose two positional patch maps: `mergeAxesPatches(prior, next)` applied to
|
|
5511
|
+
* a base spec must equal applying `prior` then `next`. Patches sharing an
|
|
5512
|
+
* index deep-merge field-by-field.
|
|
5513
|
+
*/
|
|
5514
|
+
function mergeAxesPatches(prior, next) {
|
|
5515
|
+
if (!prior || Object.keys(prior).length === 0) return next;
|
|
5516
|
+
if (!next || Object.keys(next).length === 0) return prior;
|
|
5517
|
+
const result = { ...prior };
|
|
5518
|
+
for (const [k, p] of Object.entries(next)) {
|
|
5519
|
+
const i = Number(k);
|
|
5520
|
+
const existing = result[i];
|
|
5521
|
+
result[i] = existing === void 0 ? p : mergeAxisPatch(existing, p);
|
|
5522
|
+
}
|
|
5523
|
+
return result;
|
|
5524
|
+
}
|
|
5525
|
+
function mergeAxisPatch(axis, patch) {
|
|
5526
|
+
const result = {
|
|
5527
|
+
...axis,
|
|
5528
|
+
...patch
|
|
5529
|
+
};
|
|
5530
|
+
if (patch.annotations) result.annotations = mergeRecord(axis.annotations, patch.annotations);
|
|
5531
|
+
if (patch.domain) result.domain = mergeRecord(axis.domain, patch.domain);
|
|
5532
|
+
if (patch.contextDomain) result.contextDomain = mergeRecord(axis.contextDomain, patch.contextDomain);
|
|
5533
|
+
return result;
|
|
5534
|
+
}
|
|
5535
|
+
function mergeRecord(a, b) {
|
|
5536
|
+
if (!b) return a;
|
|
5537
|
+
if (!a) return b;
|
|
5538
|
+
return {
|
|
5539
|
+
...a,
|
|
5540
|
+
...b
|
|
5541
|
+
};
|
|
5184
5542
|
}
|
|
5185
5543
|
//#endregion
|
|
5186
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5544
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
|
|
5187
5545
|
function axisKey(axis) {
|
|
5188
5546
|
return (0, import_canonicalize.default)(getAxisId(axis));
|
|
5189
5547
|
}
|
|
@@ -5429,53 +5787,7 @@ function isAnchorAxisRef(value) {
|
|
|
5429
5787
|
return typeof value === "object" && "anchor" in value;
|
|
5430
5788
|
}
|
|
5431
5789
|
//#endregion
|
|
5432
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5433
|
-
function isPColumnSpec(spec) {
|
|
5434
|
-
return spec.kind === "PColumn";
|
|
5435
|
-
}
|
|
5436
|
-
function isPColumn(obj) {
|
|
5437
|
-
return isPColumnSpec(obj.spec);
|
|
5438
|
-
}
|
|
5439
|
-
function ensurePColumn(obj) {
|
|
5440
|
-
if (!isPColumn(obj)) throw new Error(`not a PColumn (kind = ${obj.spec.kind})`);
|
|
5441
|
-
return obj;
|
|
5442
|
-
}
|
|
5443
|
-
function mapPObjectData(pObj, cb) {
|
|
5444
|
-
return pObj === void 0 ? void 0 : {
|
|
5445
|
-
...pObj,
|
|
5446
|
-
data: cb(typeof pObj.data === "function" ? pObj.data() : pObj.data)
|
|
5447
|
-
};
|
|
5448
|
-
}
|
|
5449
|
-
function extractAllColumns(entry) {
|
|
5450
|
-
const columns = /* @__PURE__ */ new Map();
|
|
5451
|
-
const addAllColumns = (entry) => {
|
|
5452
|
-
switch (entry.type) {
|
|
5453
|
-
case "column":
|
|
5454
|
-
columns.set(entry.column.id, entry.column);
|
|
5455
|
-
return;
|
|
5456
|
-
case "slicedColumn":
|
|
5457
|
-
columns.set(entry.column.id, entry.column);
|
|
5458
|
-
return;
|
|
5459
|
-
case "artificialColumn":
|
|
5460
|
-
columns.set(entry.column.id, entry.column);
|
|
5461
|
-
return;
|
|
5462
|
-
case "inlineColumn": return;
|
|
5463
|
-
case "full":
|
|
5464
|
-
case "inner":
|
|
5465
|
-
for (const e of entry.entries) addAllColumns(e);
|
|
5466
|
-
return;
|
|
5467
|
-
case "outer":
|
|
5468
|
-
addAllColumns(entry.primary);
|
|
5469
|
-
for (const e of entry.secondary) addAllColumns(e);
|
|
5470
|
-
return;
|
|
5471
|
-
default: assertNever(entry);
|
|
5472
|
-
}
|
|
5473
|
-
};
|
|
5474
|
-
addAllColumns(entry);
|
|
5475
|
-
return [...columns.values()];
|
|
5476
|
-
}
|
|
5477
|
-
//#endregion
|
|
5478
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.4/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
|
|
5790
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
|
|
5479
5791
|
/**
|
|
5480
5792
|
* Determines if an axis ID matches an axis selector.
|
|
5481
5793
|
*
|
|
@@ -5556,7 +5868,7 @@ function legacyColumnSelectorsToPredicate(predicateOrSelectors) {
|
|
|
5556
5868
|
else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);
|
|
5557
5869
|
}
|
|
5558
5870
|
//#endregion
|
|
5559
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
5871
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
|
|
5560
5872
|
function deriveNativeId(spec) {
|
|
5561
5873
|
const result = {
|
|
5562
5874
|
kind: spec.kind,
|
|
@@ -5568,19 +5880,7 @@ function deriveNativeId(spec) {
|
|
|
5568
5880
|
return (0, import_canonicalize.default)(result);
|
|
5569
5881
|
}
|
|
5570
5882
|
//#endregion
|
|
5571
|
-
//#region ../node_modules/.pnpm/@milaboratories+
|
|
5572
|
-
function isNil$1(v) {
|
|
5573
|
-
return v === null || v === void 0;
|
|
5574
|
-
}
|
|
5575
|
-
Array.isArray;
|
|
5576
|
-
//#endregion
|
|
5577
|
-
//#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.3/node_modules/@milaboratories/helpers/dist/error.js
|
|
5578
|
-
function throwError(v) {
|
|
5579
|
-
if (typeof v === "string") throw new Error(v);
|
|
5580
|
-
else throw v;
|
|
5581
|
-
}
|
|
5582
|
-
//#endregion
|
|
5583
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.46.4/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
|
|
5883
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
|
|
5584
5884
|
var LinkerMap = class LinkerMap {
|
|
5585
5885
|
/** Graph of linkers connected by axes (single or grouped by parents) */
|
|
5586
5886
|
data;
|
|
@@ -5758,7 +6058,7 @@ var LinkerMap = class LinkerMap {
|
|
|
5758
6058
|
}
|
|
5759
6059
|
};
|
|
5760
6060
|
//#endregion
|
|
5761
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6061
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
|
|
5762
6062
|
/**
|
|
5763
6063
|
* Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
|
|
5764
6064
|
* version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
|
|
@@ -5767,7 +6067,7 @@ var LinkerMap = class LinkerMap {
|
|
|
5767
6067
|
const REQUIRES_PFRAMES_VERSION = 1001031;
|
|
5768
6068
|
stringType().length(24).regex(/[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]/).brand("PlId");
|
|
5769
6069
|
//#endregion
|
|
5770
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6070
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/ref.js
|
|
5771
6071
|
const PlRef = objectType({
|
|
5772
6072
|
__isRef: literalType(true).describe("Crucial marker for the block dependency tree reconstruction"),
|
|
5773
6073
|
blockId: stringType().describe("Upstream block id"),
|
|
@@ -5803,7 +6103,7 @@ function withEnrichments(ref, requireEnrichments = true) {
|
|
|
5803
6103
|
}
|
|
5804
6104
|
}
|
|
5805
6105
|
//#endregion
|
|
5806
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6106
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
|
|
5807
6107
|
function mapValueInVOE(voe, cb) {
|
|
5808
6108
|
return voe.ok ? {
|
|
5809
6109
|
ok: true,
|
|
@@ -5811,7 +6111,51 @@ function mapValueInVOE(voe, cb) {
|
|
|
5811
6111
|
} : voe;
|
|
5812
6112
|
}
|
|
5813
6113
|
//#endregion
|
|
5814
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6114
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
|
|
6115
|
+
/** Well-known resource type names used across the platform. */
|
|
6116
|
+
const ResourceTypeName = {
|
|
6117
|
+
StreamManager: "StreamManager",
|
|
6118
|
+
StdMap: "StdMap",
|
|
6119
|
+
StdMapSlash: "std/map",
|
|
6120
|
+
EphStdMap: "EphStdMap",
|
|
6121
|
+
PFrame: "PFrame",
|
|
6122
|
+
ParquetChunk: "ParquetChunk",
|
|
6123
|
+
BContext: "BContext",
|
|
6124
|
+
BlockPackCustom: "BlockPackCustom",
|
|
6125
|
+
BinaryMap: "BinaryMap",
|
|
6126
|
+
BinaryValue: "BinaryValue",
|
|
6127
|
+
BlobMap: "BlobMap",
|
|
6128
|
+
BResolveSingle: "BResolveSingle",
|
|
6129
|
+
BResolveSingleNoResult: "BResolveSingleNoResult",
|
|
6130
|
+
BQueryResult: "BQueryResult",
|
|
6131
|
+
TengoTemplate: "TengoTemplate",
|
|
6132
|
+
TengoLib: "TengoLib",
|
|
6133
|
+
SoftwareInfo: "SoftwareInfo",
|
|
6134
|
+
Dummy: "Dummy",
|
|
6135
|
+
JsonResourceError: "json/resourceError",
|
|
6136
|
+
JsonObject: "json/object",
|
|
6137
|
+
JsonGzObject: "json-gz/object",
|
|
6138
|
+
JsonString: "json/string",
|
|
6139
|
+
JsonArray: "json/array",
|
|
6140
|
+
JsonNumber: "json/number",
|
|
6141
|
+
BContextEnd: "BContextEnd",
|
|
6142
|
+
FrontendFromUrl: "Frontend/FromUrl",
|
|
6143
|
+
FrontendFromFolder: "Frontend/FromFolder",
|
|
6144
|
+
BObjectSpec: "BObjectSpec",
|
|
6145
|
+
Blob: "Blob",
|
|
6146
|
+
Null: "Null",
|
|
6147
|
+
Binary: "binary",
|
|
6148
|
+
LSProvider: "LSProvider",
|
|
6149
|
+
WorkingDirectory: "WorkingDirectory",
|
|
6150
|
+
UserProject: "UserProject",
|
|
6151
|
+
Projects: "Projects",
|
|
6152
|
+
ClientRoot: "ClientRoot",
|
|
6153
|
+
SharingOutbox: "SharingOutbox",
|
|
6154
|
+
SharingState: "SharingState",
|
|
6155
|
+
SharedEnvelope: "SharedEnvelope"
|
|
6156
|
+
};
|
|
6157
|
+
//#endregion
|
|
6158
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
|
|
5815
6159
|
const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
|
5816
6160
|
const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
|
|
5817
6161
|
const typeMap = /* @__PURE__ */ new Map();
|
|
@@ -5850,7 +6194,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
|
|
|
5850
6194
|
};
|
|
5851
6195
|
})();
|
|
5852
6196
|
//#endregion
|
|
5853
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6197
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
|
|
5854
6198
|
const Services = {
|
|
5855
6199
|
PFrameSpec: service()({
|
|
5856
6200
|
type: "wasm",
|
|
@@ -5908,6 +6252,28 @@ const Services = {
|
|
|
5908
6252
|
name: "dialog",
|
|
5909
6253
|
modelMethods: [],
|
|
5910
6254
|
uiMethods: ["showSaveDialog"]
|
|
6255
|
+
}),
|
|
6256
|
+
ColumnsCollection: service()({
|
|
6257
|
+
type: "wasm",
|
|
6258
|
+
name: "columnsCollection",
|
|
6259
|
+
modelMethods: [
|
|
6260
|
+
"create",
|
|
6261
|
+
"isEmpty",
|
|
6262
|
+
"isFinal",
|
|
6263
|
+
"getColumns",
|
|
6264
|
+
"addSource",
|
|
6265
|
+
"discover",
|
|
6266
|
+
"filter"
|
|
6267
|
+
],
|
|
6268
|
+
uiMethods: [
|
|
6269
|
+
"create",
|
|
6270
|
+
"isEmpty",
|
|
6271
|
+
"isFinal",
|
|
6272
|
+
"getColumns",
|
|
6273
|
+
"addSource",
|
|
6274
|
+
"discover",
|
|
6275
|
+
"filter"
|
|
6276
|
+
]
|
|
5911
6277
|
})
|
|
5912
6278
|
};
|
|
5913
6279
|
Object.keys(Services).map((key) => `requires${key}`);
|
|
@@ -5922,7 +6288,7 @@ function resolveRequiredServices(flags) {
|
|
|
5922
6288
|
}
|
|
5923
6289
|
Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
|
|
5924
6290
|
//#endregion
|
|
5925
|
-
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.
|
|
6291
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
|
|
5926
6292
|
function buildMethodMap(pick) {
|
|
5927
6293
|
const result = {};
|
|
5928
6294
|
for (const id of Object.values(Services)) result[id] = [...pick(id)];
|
|
@@ -5931,26 +6297,269 @@ function buildMethodMap(pick) {
|
|
|
5931
6297
|
buildMethodMap(getServiceUiMethods);
|
|
5932
6298
|
buildMethodMap(getServiceModelMethods);
|
|
5933
6299
|
//#endregion
|
|
5934
|
-
//#region ../node_modules/.pnpm/@
|
|
5935
|
-
|
|
5936
|
-
|
|
6300
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
|
|
6301
|
+
/** Resource types that hold column collections — DFS stops here and collects. */
|
|
6302
|
+
const COLLECT_TYPES = [ResourceTypeName.PFrame];
|
|
6303
|
+
/** Resource types DFS descends through when looking for PFrames. */
|
|
6304
|
+
const DESCEND_TYPES = [ResourceTypeName.StdMap, ResourceTypeName.StdMapSlash];
|
|
6305
|
+
/**
|
|
6306
|
+
* Enumerate column names backing a PFrame accessor — derived from
|
|
6307
|
+
* `<name>.spec` field names, without resolving the spec resources.
|
|
6308
|
+
*/
|
|
6309
|
+
function listColumnNames(accessor, prefix = "") {
|
|
6310
|
+
if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];
|
|
6311
|
+
const out = [];
|
|
6312
|
+
for (const field of accessor.listInputFields()) {
|
|
6313
|
+
if (!field.endsWith(".spec")) continue;
|
|
6314
|
+
const raw = field.slice(0, -5);
|
|
6315
|
+
if (!raw.startsWith(prefix)) continue;
|
|
6316
|
+
out.push(raw.slice(prefix.length));
|
|
6317
|
+
}
|
|
6318
|
+
return out;
|
|
5937
6319
|
}
|
|
5938
6320
|
/**
|
|
5939
|
-
*
|
|
5940
|
-
*
|
|
5941
|
-
*
|
|
5942
|
-
*
|
|
6321
|
+
* DFS over the input-field subtree of `root`. Collects nodes whose resource
|
|
6322
|
+
* type ∈ `collectTypes`. Descends only through `descendTypes`
|
|
6323
|
+
* (default: StdMap / StdMapSlash). Collected nodes are not descended into.
|
|
6324
|
+
*
|
|
6325
|
+
* Threads the field-name path from `rootPath` to each hit, so callers can
|
|
6326
|
+
* build canonical {@link createLocalPObjectId}s without relying on the
|
|
6327
|
+
* accessor itself to remember its path.
|
|
6328
|
+
*
|
|
6329
|
+
* Includes `root` itself in the walk.
|
|
5943
6330
|
*/
|
|
5944
|
-
function
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
6331
|
+
function findDescendantsByType(opts) {
|
|
6332
|
+
const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
|
|
6333
|
+
const collectSet = new Set(collectTypes);
|
|
6334
|
+
const descendSet = new Set(descendTypes);
|
|
6335
|
+
const result = [];
|
|
6336
|
+
const stack = [{
|
|
6337
|
+
node: root,
|
|
6338
|
+
path: rootPath
|
|
6339
|
+
}];
|
|
6340
|
+
while (stack.length > 0) {
|
|
6341
|
+
const { node, path } = stack.pop();
|
|
6342
|
+
const typeName = node.resourceType.name;
|
|
6343
|
+
if (collectSet.has(typeName)) {
|
|
6344
|
+
result.push({
|
|
6345
|
+
node,
|
|
6346
|
+
path
|
|
6347
|
+
});
|
|
6348
|
+
continue;
|
|
6349
|
+
}
|
|
6350
|
+
if (!descendSet.has(typeName)) continue;
|
|
6351
|
+
const fields = node.listInputFields();
|
|
6352
|
+
for (let i = fields.length - 1; i >= 0; i--) {
|
|
6353
|
+
const child = node.traverse({
|
|
6354
|
+
field: fields[i],
|
|
6355
|
+
assertFieldType: "Input",
|
|
6356
|
+
ignoreError: true
|
|
6357
|
+
});
|
|
6358
|
+
if (child !== void 0) stack.push({
|
|
6359
|
+
node: child,
|
|
6360
|
+
path: [...path, fields[i]]
|
|
6361
|
+
});
|
|
6362
|
+
}
|
|
6363
|
+
}
|
|
6364
|
+
return result;
|
|
5950
6365
|
}
|
|
5951
|
-
/**
|
|
5952
|
-
|
|
5953
|
-
|
|
6366
|
+
/**
|
|
6367
|
+
* Walk an accessor root and return one {@link LeafEntry} per discovered column.
|
|
6368
|
+
* Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
|
|
6369
|
+
* `resolvePath` is derived from `rootPath` extended by the DFS traversal.
|
|
6370
|
+
*/
|
|
6371
|
+
function indexAccessorRoot(root, rootPath) {
|
|
6372
|
+
const result = [];
|
|
6373
|
+
for (const { node, path } of findDescendantsByType({
|
|
6374
|
+
root,
|
|
6375
|
+
rootPath,
|
|
6376
|
+
collectTypes: COLLECT_TYPES,
|
|
6377
|
+
descendTypes: DESCEND_TYPES
|
|
6378
|
+
})) for (const name of listColumnNames(node)) result.push({
|
|
6379
|
+
accessor: node,
|
|
6380
|
+
name,
|
|
6381
|
+
id: createLocalPObjectId([...path], name)
|
|
6382
|
+
});
|
|
6383
|
+
return result;
|
|
6384
|
+
}
|
|
6385
|
+
/**
|
|
6386
|
+
* Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
|
|
6387
|
+
* {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
|
|
6388
|
+
* Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
|
|
6389
|
+
*/
|
|
6390
|
+
function indexPoolBlock(block) {
|
|
6391
|
+
const accessors = [];
|
|
6392
|
+
if (block.prodCtx) accessors.push(block.prodCtx);
|
|
6393
|
+
if (block.stagingCtx) accessors.push(block.stagingCtx);
|
|
6394
|
+
const result = [];
|
|
6395
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6396
|
+
for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
|
|
6397
|
+
if (seen.has(name)) continue;
|
|
6398
|
+
seen.add(name);
|
|
6399
|
+
result.push({
|
|
6400
|
+
accessor,
|
|
6401
|
+
name,
|
|
6402
|
+
id: createGlobalPObjectId(block.blockId, name)
|
|
6403
|
+
});
|
|
6404
|
+
}
|
|
6405
|
+
return result;
|
|
6406
|
+
}
|
|
6407
|
+
//#endregion
|
|
6408
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
|
|
6409
|
+
/**
|
|
6410
|
+
* Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
|
|
6411
|
+
* {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
|
|
6412
|
+
* the same class backs both sandbox (`TreeNodeAccessor`) and host
|
|
6413
|
+
* (`PlTreeNodeAccessor`) usage.
|
|
6414
|
+
*
|
|
6415
|
+
* Stateless beyond the provider list — every lookup goes through each
|
|
6416
|
+
* provider's `getPObjectEntries()` (cached inside the provider). Instantiate
|
|
6417
|
+
* directly at the call site that has the providers; there is no ambient
|
|
6418
|
+
* singleton.
|
|
6419
|
+
*/
|
|
6420
|
+
var ColumnRegistry = class {
|
|
6421
|
+
providers;
|
|
6422
|
+
constructor(providers) {
|
|
6423
|
+
this.providers = providers;
|
|
6424
|
+
}
|
|
6425
|
+
/**
|
|
6426
|
+
* Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
|
|
6427
|
+
* `undefined` if the column is not reachable from any provider — caller
|
|
6428
|
+
* decides whether that's `absent` or `resolving` via {@link isFinal}.
|
|
6429
|
+
*/
|
|
6430
|
+
resolve(id) {
|
|
6431
|
+
return this.lookupById(id);
|
|
6432
|
+
}
|
|
6433
|
+
/** Whether every indexed source has finished enumerating its columns. */
|
|
6434
|
+
isFinal() {
|
|
6435
|
+
return this.providers.every((p) => p.isFinal());
|
|
6436
|
+
}
|
|
6437
|
+
lookupById(id) {
|
|
6438
|
+
for (const p of this.providers) {
|
|
6439
|
+
const hit = p.getPObjectEntries().get(id);
|
|
6440
|
+
if (hit !== void 0) return hit;
|
|
6441
|
+
}
|
|
6442
|
+
}
|
|
6443
|
+
};
|
|
6444
|
+
//#endregion
|
|
6445
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
|
|
6446
|
+
/**
|
|
6447
|
+
* Two-track dedup over an item stream keyed by `ColumnUniversalId`:
|
|
6448
|
+
*
|
|
6449
|
+
* - **Raw `PObjectId`s** are deduped by `deriveNativeId(spec)`. The same
|
|
6450
|
+
* physical column reached via outputs vs. result_pool has different
|
|
6451
|
+
* id shapes but identical nativeId — first occurrence wins so the
|
|
6452
|
+
* provider order (outputs before pool) decides which id is canonical.
|
|
6453
|
+
* - **Non-`PObjectId` ids** (e.g. `SUniversalPColumnUniversalId`,
|
|
6454
|
+
* `ColumnDiscoveredId`) keep raw-id dedup — they legitimately share
|
|
6455
|
+
* nativeId with siblings.
|
|
6456
|
+
*
|
|
6457
|
+
* When `getSpec` returns `undefined` for a `PObjectId`, falls back to raw-id
|
|
6458
|
+
* dedup (so an unresolvable id still survives instead of dropping silently).
|
|
6459
|
+
*
|
|
6460
|
+
* Shared by sandbox-side `extractColumns` (column_providers) and host-side
|
|
6461
|
+
* `ColumnsCollectionDriverImpl.getColumns` — both layers need identical
|
|
6462
|
+
* dedup semantics, but operate on different concrete item types (ColumnLazy
|
|
6463
|
+
* vs. raw ColumnUniversalId).
|
|
6464
|
+
*/
|
|
6465
|
+
function dedupColumns(items, getId, getSpec) {
|
|
6466
|
+
const seenNative = /* @__PURE__ */ new Set();
|
|
6467
|
+
const seenId = /* @__PURE__ */ new Set();
|
|
6468
|
+
const out = [];
|
|
6469
|
+
for (const item of items) {
|
|
6470
|
+
const id = getId(item);
|
|
6471
|
+
if (seenId.has(id)) continue;
|
|
6472
|
+
if (isPObjectId(id)) {
|
|
6473
|
+
const spec = getSpec(item);
|
|
6474
|
+
if (spec !== void 0) {
|
|
6475
|
+
const nativeId = deriveNativeId(spec);
|
|
6476
|
+
if (seenNative.has(nativeId)) continue;
|
|
6477
|
+
seenNative.add(nativeId);
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
seenId.add(id);
|
|
6481
|
+
out.push(item);
|
|
6482
|
+
}
|
|
6483
|
+
return out;
|
|
6484
|
+
}
|
|
6485
|
+
//#endregion
|
|
6486
|
+
//#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.1/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
|
|
6487
|
+
/**
|
|
6488
|
+
* Generic entries provider over a single accessor root. Walks `<root>` once
|
|
6489
|
+
* from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
|
|
6490
|
+
* exposes `isFinal()` via the root's `getInputsLocked()`.
|
|
6491
|
+
*
|
|
6492
|
+
* Used directly on the host side; sandbox extends it with `getColumns()`
|
|
6493
|
+
* returning {@link ColumnLazy}s — see `AccessorColumnsProvider` in
|
|
6494
|
+
* `@platforma-sdk/model`.
|
|
6495
|
+
*/
|
|
6496
|
+
var AccessorEntriesProvider = class {
|
|
6497
|
+
root;
|
|
6498
|
+
entries;
|
|
6499
|
+
constructor(root, rootPath) {
|
|
6500
|
+
this.root = root;
|
|
6501
|
+
const map = /* @__PURE__ */ new Map();
|
|
6502
|
+
for (const entry of indexAccessorRoot(root, rootPath)) if (!map.has(entry.id)) map.set(entry.id, entry);
|
|
6503
|
+
this.entries = map;
|
|
6504
|
+
}
|
|
6505
|
+
getPObjectEntries() {
|
|
6506
|
+
return this.entries;
|
|
6507
|
+
}
|
|
6508
|
+
isFinal() {
|
|
6509
|
+
return this.root.getInputsLocked();
|
|
6510
|
+
}
|
|
6511
|
+
};
|
|
6512
|
+
/**
|
|
6513
|
+
* Generic entries provider over a list of upstream-block ctx pairs.
|
|
6514
|
+
*
|
|
6515
|
+
* Per-block merge: iterate `prod` then `staging`, dedupe by name with
|
|
6516
|
+
* first-wins semantics (prod takes precedence).
|
|
6517
|
+
*
|
|
6518
|
+
* `isFinal()` is the AND of `getInputsLocked()` over every present ctx
|
|
6519
|
+
* accessor and `!prodIncomplete && !stagingIncomplete` over every block.
|
|
6520
|
+
*/
|
|
6521
|
+
var ResultPoolEntriesProvider = class {
|
|
6522
|
+
blocks;
|
|
6523
|
+
cachedEntries;
|
|
6524
|
+
constructor(blocks) {
|
|
6525
|
+
this.blocks = blocks;
|
|
6526
|
+
}
|
|
6527
|
+
getPObjectEntries() {
|
|
6528
|
+
if (this.cachedEntries !== void 0) return this.cachedEntries;
|
|
6529
|
+
const map = /* @__PURE__ */ new Map();
|
|
6530
|
+
for (const block of this.blocks) for (const entry of indexPoolBlock(block)) if (!map.has(entry.id)) map.set(entry.id, entry);
|
|
6531
|
+
return this.cachedEntries = map;
|
|
6532
|
+
}
|
|
6533
|
+
isFinal() {
|
|
6534
|
+
for (const block of this.blocks) {
|
|
6535
|
+
if (block.prodIncomplete || block.stagingIncomplete) return false;
|
|
6536
|
+
if (block.prodCtx && !block.prodCtx.getInputsLocked()) return false;
|
|
6537
|
+
if (block.stagingCtx && !block.stagingCtx.getInputsLocked()) return false;
|
|
6538
|
+
}
|
|
6539
|
+
return true;
|
|
6540
|
+
}
|
|
6541
|
+
};
|
|
6542
|
+
//#endregion
|
|
6543
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/accessor.js
|
|
6544
|
+
function ifDef(value, cb) {
|
|
6545
|
+
return value === void 0 ? void 0 : cb(value);
|
|
6546
|
+
}
|
|
6547
|
+
/**
|
|
6548
|
+
* Decode an error node's content into a display message. The backend serializes
|
|
6549
|
+
* a resource error as `{"message": "..."}` (`ResourceError`); unwrap that to the
|
|
6550
|
+
* human-readable message. Falls back to the raw string when the content is not
|
|
6551
|
+
* that envelope (e.g. plain text, or an unexpected shape).
|
|
6552
|
+
*/
|
|
6553
|
+
function decodeErrorMessage(raw) {
|
|
6554
|
+
try {
|
|
6555
|
+
const parsed = JSON.parse(raw);
|
|
6556
|
+
if (typeof parsed?.message === "string") return parsed.message;
|
|
6557
|
+
} catch {}
|
|
6558
|
+
return raw;
|
|
6559
|
+
}
|
|
6560
|
+
/** Represent resource tree node accessor */
|
|
6561
|
+
var TreeNodeAccessor = class TreeNodeAccessor {
|
|
6562
|
+
handle;
|
|
5954
6563
|
resolvePath;
|
|
5955
6564
|
constructor(handle, resolvePath) {
|
|
5956
6565
|
this.handle = handle;
|
|
@@ -5977,7 +6586,7 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
5977
6586
|
}));
|
|
5978
6587
|
return this.resolveWithCommon({}, ...transformedSteps);
|
|
5979
6588
|
}
|
|
5980
|
-
|
|
6589
|
+
traverse(...steps) {
|
|
5981
6590
|
return this.resolveWithCommon({}, ...steps);
|
|
5982
6591
|
}
|
|
5983
6592
|
resolveWithCommon(commonOptions, ...steps) {
|
|
@@ -6023,6 +6632,9 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
6023
6632
|
if (content == void 0) throw new Error("Resource has no content.");
|
|
6024
6633
|
return JSON.parse(content);
|
|
6025
6634
|
}
|
|
6635
|
+
hasData() {
|
|
6636
|
+
return getCfgRenderCtx().hasData(this.handle);
|
|
6637
|
+
}
|
|
6026
6638
|
getDataBase64() {
|
|
6027
6639
|
return getCfgRenderCtx().getDataBase64(this.handle);
|
|
6028
6640
|
}
|
|
@@ -6059,9 +6671,16 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
6059
6671
|
}
|
|
6060
6672
|
return this.getDataAsJson();
|
|
6061
6673
|
}
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6674
|
+
getFileContentAsBase64(range) {
|
|
6675
|
+
return new FutureRef(getCfgRenderCtx().getBlobContentAsBase64(this.handle, range));
|
|
6676
|
+
}
|
|
6677
|
+
getFileContentAsString(range) {
|
|
6678
|
+
return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range));
|
|
6679
|
+
}
|
|
6680
|
+
getFileContentAsJson(range) {
|
|
6681
|
+
return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range)).mapDefined((v) => JSON.parse(v));
|
|
6682
|
+
}
|
|
6683
|
+
/** @deprecated */
|
|
6065
6684
|
getPColumns(errorOnUnknownField = false, prefix = "") {
|
|
6066
6685
|
const result = this.parsePObjectCollection(errorOnUnknownField, prefix);
|
|
6067
6686
|
if (result === void 0) return void 0;
|
|
@@ -6070,9 +6689,7 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
6070
6689
|
return obj;
|
|
6071
6690
|
});
|
|
6072
6691
|
}
|
|
6073
|
-
/**
|
|
6074
|
-
*
|
|
6075
|
-
*/
|
|
6692
|
+
/** @deprecated */
|
|
6076
6693
|
parsePObjectCollection(errorOnUnknownField = false, prefix = "") {
|
|
6077
6694
|
const pObjects = getCfgRenderCtx().parsePObjectCollection(this.handle, errorOnUnknownField, prefix, ...this.resolvePath);
|
|
6078
6695
|
if (pObjects === void 0) return void 0;
|
|
@@ -6083,15 +6700,6 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
6083
6700
|
}
|
|
6084
6701
|
return result;
|
|
6085
6702
|
}
|
|
6086
|
-
getFileContentAsBase64(range) {
|
|
6087
|
-
return new FutureRef(getCfgRenderCtx().getBlobContentAsBase64(this.handle, range));
|
|
6088
|
-
}
|
|
6089
|
-
getFileContentAsString(range) {
|
|
6090
|
-
return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range));
|
|
6091
|
-
}
|
|
6092
|
-
getFileContentAsJson(range) {
|
|
6093
|
-
return new FutureRef(getCfgRenderCtx().getBlobContentAsString(this.handle, range)).mapDefined((v) => JSON.parse(v));
|
|
6094
|
-
}
|
|
6095
6703
|
/**
|
|
6096
6704
|
* @deprecated use getFileContentAsBase64
|
|
6097
6705
|
*/
|
|
@@ -6182,11 +6790,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
|
|
|
6182
6790
|
}
|
|
6183
6791
|
};
|
|
6184
6792
|
//#endregion
|
|
6185
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
6186
|
-
const StagingAccessorName = "staging";
|
|
6793
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/internal.js
|
|
6187
6794
|
const MainAccessorName = "main";
|
|
6795
|
+
const StagingAccessorName = "staging";
|
|
6188
6796
|
//#endregion
|
|
6189
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
6797
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
|
|
6190
6798
|
function filterDataInfoEntries(dataInfoEntries, axisFilters) {
|
|
6191
6799
|
const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
|
|
6192
6800
|
const { type } = dataInfoEntries;
|
|
@@ -6250,22 +6858,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
|
|
|
6250
6858
|
}
|
|
6251
6859
|
}
|
|
6252
6860
|
//#endregion
|
|
6253
|
-
//#region ../node_modules/.pnpm
|
|
6254
|
-
function identity(x) {
|
|
6255
|
-
return x;
|
|
6256
|
-
}
|
|
6257
|
-
//#endregion
|
|
6258
|
-
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/predicate/isFunction.mjs
|
|
6259
|
-
function isFunction(value) {
|
|
6260
|
-
return typeof value === "function";
|
|
6261
|
-
}
|
|
6262
|
-
//#endregion
|
|
6263
|
-
//#region ../node_modules/.pnpm/es-toolkit@1.42.0/node_modules/es-toolkit/dist/predicate/isNil.mjs
|
|
6264
|
-
function isNil(x) {
|
|
6265
|
-
return x == null;
|
|
6266
|
-
}
|
|
6267
|
-
//#endregion
|
|
6268
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.27/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
|
|
6861
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
|
|
6269
6862
|
const DISTANCE_PENALTY = .001;
|
|
6270
6863
|
const LABEL_TYPE = "__LABEL__";
|
|
6271
6864
|
const LABEL_TYPE_FULL = "__LABEL__@1";
|
|
@@ -6531,7 +7124,7 @@ function minimizeTypeSet(typeSet, records, stats, forceTraceElements, forcedSet,
|
|
|
6531
7124
|
return result;
|
|
6532
7125
|
}
|
|
6533
7126
|
//#endregion
|
|
6534
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7127
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/label.js
|
|
6535
7128
|
/** @deprecated Use deriveDistinctLabels */
|
|
6536
7129
|
function deriveLabels(values, getSpec, options = {}) {
|
|
6537
7130
|
return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
|
|
@@ -6540,7 +7133,7 @@ function deriveLabels(values, getSpec, options = {}) {
|
|
|
6540
7133
|
}));
|
|
6541
7134
|
}
|
|
6542
7135
|
//#endregion
|
|
6543
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7136
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
|
|
6544
7137
|
const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
|
|
6545
7138
|
const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
|
|
6546
7139
|
const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
|
|
@@ -6872,7 +7465,7 @@ function isPColumnReady(c) {
|
|
|
6872
7465
|
const isValues = (d) => Array.isArray(d);
|
|
6873
7466
|
const isAccessor = (d) => d instanceof TreeNodeAccessor;
|
|
6874
7467
|
let ready = true;
|
|
6875
|
-
const data =
|
|
7468
|
+
const data = c.data;
|
|
6876
7469
|
if (data == null) return false;
|
|
6877
7470
|
else if (isAccessor(data)) ready &&= data.getIsReadyOrError();
|
|
6878
7471
|
else if (isDataInfo(data)) visitDataInfo(data, (v) => ready &&= v.getIsReadyOrError());
|
|
@@ -6883,7 +7476,7 @@ function allPColumnsReady(columns) {
|
|
|
6883
7476
|
return columns.every(isPColumnReady);
|
|
6884
7477
|
}
|
|
6885
7478
|
//#endregion
|
|
6886
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7479
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
|
|
6887
7480
|
function isPColumnValues(value) {
|
|
6888
7481
|
if (!Array.isArray(value)) return false;
|
|
6889
7482
|
if (value.length === 0) return true;
|
|
@@ -6893,7 +7486,7 @@ function isPColumnValues(value) {
|
|
|
6893
7486
|
/**
|
|
6894
7487
|
* A simple implementation of {@link ColumnProvider} backed by a pre-defined array of columns.
|
|
6895
7488
|
*/
|
|
6896
|
-
var
|
|
7489
|
+
var ArrayColumnsProvider = class {
|
|
6897
7490
|
columns;
|
|
6898
7491
|
constructor(columns) {
|
|
6899
7492
|
this.columns = columns;
|
|
@@ -6945,7 +7538,7 @@ function getSplitAxisIndices(selector) {
|
|
|
6945
7538
|
}
|
|
6946
7539
|
var PColumnCollection = class {
|
|
6947
7540
|
defaultProviderStore = [];
|
|
6948
|
-
providers = [new
|
|
7541
|
+
providers = [new ArrayColumnsProvider(this.defaultProviderStore)];
|
|
6949
7542
|
axisLabelProviders = [];
|
|
6950
7543
|
constructor() {}
|
|
6951
7544
|
addColumnProvider(provider) {
|
|
@@ -7108,7 +7701,9 @@ var PColumnCollection = class {
|
|
|
7108
7701
|
result.push({
|
|
7109
7702
|
id: finalId,
|
|
7110
7703
|
spec: finalSpec,
|
|
7111
|
-
data
|
|
7704
|
+
get data() {
|
|
7705
|
+
return entry.type === "split" ? entriesToDataInfo(filterDataInfoEntries(entry.dataEntries, axisFiltersTuple)) : entry.originalColumn.data;
|
|
7706
|
+
},
|
|
7112
7707
|
label
|
|
7113
7708
|
});
|
|
7114
7709
|
}
|
|
@@ -7144,7 +7739,7 @@ var PColumnCollection = class {
|
|
|
7144
7739
|
if (!entries) return void 0;
|
|
7145
7740
|
const columns = [];
|
|
7146
7741
|
for (const entry of entries) {
|
|
7147
|
-
const data = entry.data
|
|
7742
|
+
const data = entry.data;
|
|
7148
7743
|
if (!data) {
|
|
7149
7744
|
if (opts?.dontWaitAllData) continue;
|
|
7150
7745
|
return;
|
|
@@ -7159,7 +7754,7 @@ var PColumnCollection = class {
|
|
|
7159
7754
|
}
|
|
7160
7755
|
};
|
|
7161
7756
|
//#endregion
|
|
7162
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7757
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/block_services.js
|
|
7163
7758
|
/**
|
|
7164
7759
|
* Services required by all V3 blocks by default.
|
|
7165
7760
|
* Edit this when a new service should be available to all blocks.
|
|
@@ -7170,11 +7765,12 @@ var PColumnCollection = class {
|
|
|
7170
7765
|
const BLOCK_SERVICE_FLAGS = {
|
|
7171
7766
|
requiresPFrameSpec: true,
|
|
7172
7767
|
requiresPFrame: true,
|
|
7173
|
-
requiresDialog: true
|
|
7768
|
+
requiresDialog: true,
|
|
7769
|
+
requiresColumnsCollection: true
|
|
7174
7770
|
};
|
|
7175
7771
|
resolveRequiredServices(BLOCK_SERVICE_FLAGS);
|
|
7176
7772
|
//#endregion
|
|
7177
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7773
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
|
|
7178
7774
|
/**
|
|
7179
7775
|
* Builds a ServiceProxy from a ServiceDispatch.
|
|
7180
7776
|
* Each service method call is forwarded to dispatch.callServiceMethod.
|
|
@@ -7183,10 +7779,10 @@ function createServiceProxy(dispatch) {
|
|
|
7183
7779
|
return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
|
|
7184
7780
|
}
|
|
7185
7781
|
//#endregion
|
|
7186
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7782
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/services/get_services.js
|
|
7187
7783
|
const cachedServices = /* @__PURE__ */ new WeakMap();
|
|
7188
|
-
function getService(name) {
|
|
7189
|
-
const ctx = getCfgRenderCtx();
|
|
7784
|
+
function getService(name, deps) {
|
|
7785
|
+
const ctx = deps?.ctx ?? getCfgRenderCtx();
|
|
7190
7786
|
const map = cachedServices.has(ctx) ? cachedServices.get(ctx) : (() => {
|
|
7191
7787
|
cachedServices.set(ctx, /* @__PURE__ */ new Map());
|
|
7192
7788
|
return cachedServices.get(ctx);
|
|
@@ -7197,7 +7793,7 @@ function getService(name) {
|
|
|
7197
7793
|
})();
|
|
7198
7794
|
}
|
|
7199
7795
|
//#endregion
|
|
7200
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7796
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
|
|
7201
7797
|
function patchInSetFilters(filters) {
|
|
7202
7798
|
const inSetToOrEqual = (predicate) => {
|
|
7203
7799
|
if (predicate.operator !== "InSet") return predicate;
|
|
@@ -7235,7 +7831,7 @@ function patchInSetFilters(filters) {
|
|
|
7235
7831
|
return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
|
|
7236
7832
|
}
|
|
7237
7833
|
//#endregion
|
|
7238
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7834
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/render/api.js
|
|
7239
7835
|
/**
|
|
7240
7836
|
* Helper function to match domain objects
|
|
7241
7837
|
* @param query Optional domain to match against
|
|
@@ -7250,24 +7846,35 @@ function matchDomain(query, target) {
|
|
|
7250
7846
|
}
|
|
7251
7847
|
/**
|
|
7252
7848
|
* Transforms PColumn data into the internal representation expected by the platform
|
|
7253
|
-
* @param
|
|
7849
|
+
* @param column Data from a PColumn to transform
|
|
7254
7850
|
* @returns Transformed data compatible with platform API
|
|
7255
7851
|
*/
|
|
7256
|
-
function
|
|
7257
|
-
return mapPObjectData(
|
|
7258
|
-
if (
|
|
7259
|
-
else if (isDataInfo(
|
|
7260
|
-
|
|
7852
|
+
function finalizePColumnData(column) {
|
|
7853
|
+
return mapPObjectData(column, (data) => {
|
|
7854
|
+
if (data instanceof TreeNodeAccessor) return data.handle;
|
|
7855
|
+
else if (isDataInfo(data)) {
|
|
7856
|
+
let ready = true;
|
|
7857
|
+
visitDataInfo(data, (accessor) => ready &&= accessor?.getIsReadyOrError() ?? false);
|
|
7858
|
+
if (!ready) return [];
|
|
7859
|
+
return mapDataInfo(data, (accessor) => accessor?.handle ?? throwError("Accessor handle is undefined"));
|
|
7860
|
+
} else return data ?? [];
|
|
7261
7861
|
});
|
|
7262
7862
|
}
|
|
7863
|
+
/**
|
|
7864
|
+
* @deprecated use the direct `ctx.*` methods on `RenderCtxBase` instead.
|
|
7865
|
+
*
|
|
7866
|
+
* Migration map:
|
|
7867
|
+
* - `getSpecs` → `ctx.getSpecs`
|
|
7868
|
+
* - `getSpecByRef` / `getPColumnSpecByRef` → `ctx.getSpecByRef` / `ctx.getPColumnSpecByRef`
|
|
7869
|
+
* - `getDataByRef` / `getPColumnByRef` → `ctx.getDataByRef` / `ctx.getPColumnByRef`
|
|
7870
|
+
* - `getOptions` → `ctx.getOptions`
|
|
7871
|
+
*
|
|
7872
|
+
* Eager methods `selectColumns` / `getData` / `getDataWithErrors` should be
|
|
7873
|
+
* replaced by `ctx.getSpecs` + on-demand `ctx.getStatusByRef` /
|
|
7874
|
+
* `ctx.getPColumnByRef` so that the data resource is not subscribed up-front.
|
|
7875
|
+
*/
|
|
7263
7876
|
var ResultPool = class {
|
|
7264
7877
|
ctx = getCfgRenderCtx();
|
|
7265
|
-
/**
|
|
7266
|
-
* @deprecated use getOptions()
|
|
7267
|
-
*/
|
|
7268
|
-
calculateOptions(predicate) {
|
|
7269
|
-
return this.ctx.calculateOptions(predicate);
|
|
7270
|
-
}
|
|
7271
7878
|
getOptions(predicateOrSelector, opts) {
|
|
7272
7879
|
const predicate = typeof predicateOrSelector === "function" ? predicateOrSelector : legacyColumnSelectorsToPredicate(predicateOrSelector);
|
|
7273
7880
|
const filtered = this.getSpecs().entries.filter((s) => predicate(s.obj));
|
|
@@ -7411,7 +8018,6 @@ var ResultPool = class {
|
|
|
7411
8018
|
* @returns data associated with the ref
|
|
7412
8019
|
*/
|
|
7413
8020
|
getDataByRef(ref) {
|
|
7414
|
-
if (typeof this.ctx.getDataFromResultPoolByRef === "undefined") return this.getData().entries.find((f) => f.ref.blockId === ref.blockId && f.ref.name === ref.name)?.obj;
|
|
7415
8021
|
const data = this.ctx.getDataFromResultPoolByRef(ref.blockId, ref.name);
|
|
7416
8022
|
if (!data) return void 0;
|
|
7417
8023
|
return mapPObjectData(data, (handle) => new TreeNodeAccessor(handle, [ref.blockId, ref.name]));
|
|
@@ -7492,6 +8098,9 @@ var ResultPool = class {
|
|
|
7492
8098
|
*
|
|
7493
8099
|
* @param selectors - A predicate function, a single selector, or an array of selectors.
|
|
7494
8100
|
* @returns An array of PColumn objects matching the selectors. Data is loaded on first access.
|
|
8101
|
+
* @deprecated use `RenderCtxBase.rawResultPool` + `ResultPoolColumnsProvider` +
|
|
8102
|
+
* `discoverColumns` instead. This eager path materializes column data
|
|
8103
|
+
* unnecessarily for callers that only filter by spec.
|
|
7495
8104
|
*/
|
|
7496
8105
|
selectColumns(selectors) {
|
|
7497
8106
|
const predicate = typeof selectors === "function" ? selectors : legacyColumnSelectorsToPredicate(selectors);
|
|
@@ -7569,20 +8178,8 @@ var RenderCtxBase = class {
|
|
|
7569
8178
|
get outputs() {
|
|
7570
8179
|
return this.getNamedAccessor(MainAccessorName);
|
|
7571
8180
|
}
|
|
8181
|
+
/** @deprecated use `rawResultPool` + `ResultPoolColumnsProvider` instead. */
|
|
7572
8182
|
resultPool = new ResultPool();
|
|
7573
|
-
/**
|
|
7574
|
-
* Find labels data for a given axis id. It will search for a label column and return its data as a map.
|
|
7575
|
-
* @returns a map of axis value => label
|
|
7576
|
-
* @deprecated Use resultPool.findLabels instead
|
|
7577
|
-
*/
|
|
7578
|
-
findLabels(axis) {
|
|
7579
|
-
return this.resultPool.findLabels(axis);
|
|
7580
|
-
}
|
|
7581
|
-
verifyInlineAndExplicitColumnsSupport(columns) {
|
|
7582
|
-
const hasInlineColumns = columns.some((c) => !(c.data instanceof TreeNodeAccessor) || isDataInfo(c.data));
|
|
7583
|
-
const inlineColumnsSupport = this.ctx.featureFlags?.inlineColumnsSupport === true;
|
|
7584
|
-
if (hasInlineColumns && !inlineColumnsSupport) throw Error(`Inline or explicit columns not supported`);
|
|
7585
|
-
}
|
|
7586
8183
|
patchPTableDef(def) {
|
|
7587
8184
|
if (!this.ctx.featureFlags?.pTablePartitionFiltersSupport) def = {
|
|
7588
8185
|
...def,
|
|
@@ -7597,7 +8194,7 @@ var RenderCtxBase = class {
|
|
|
7597
8194
|
return def;
|
|
7598
8195
|
}
|
|
7599
8196
|
createPFrame(def) {
|
|
7600
|
-
return this.ctx.createPFrame(def.map((
|
|
8197
|
+
return this.ctx.createPFrame(def.map((v) => isString(v) ? v : finalizePColumnData(v)));
|
|
7601
8198
|
}
|
|
7602
8199
|
createPTable(def) {
|
|
7603
8200
|
let rawDef;
|
|
@@ -7614,17 +8211,11 @@ var RenderCtxBase = class {
|
|
|
7614
8211
|
sorting: def.sorting ?? []
|
|
7615
8212
|
});
|
|
7616
8213
|
else rawDef = this.patchPTableDef(def);
|
|
7617
|
-
|
|
7618
|
-
this.
|
|
7619
|
-
if (!allPColumnsReady(columns)) return void 0;
|
|
7620
|
-
return this.ctx.createPTable(mapPTableDef(rawDef, (po) => transformPColumnData(po)));
|
|
8214
|
+
if (!allPColumnsReady(extractAllColumns(rawDef.src))) return void 0;
|
|
8215
|
+
return this.ctx.createPTable(mapPTableDef(rawDef, finalizePColumnData));
|
|
7621
8216
|
}
|
|
7622
8217
|
createPTableV2(def) {
|
|
7623
|
-
return this.ctx.createPTableV2(mapPTableDefV2(def, (
|
|
7624
|
-
}
|
|
7625
|
-
/** @deprecated scheduled for removal from SDK */
|
|
7626
|
-
getBlockLabel(blockId) {
|
|
7627
|
-
return this.ctx.getBlockLabel(blockId);
|
|
8218
|
+
return this.ctx.createPTableV2(mapPTableDefV2(def, { column: (v) => isString(v) ? v : finalizePColumnData(v) }));
|
|
7628
8219
|
}
|
|
7629
8220
|
getCurrentUnstableMarker() {
|
|
7630
8221
|
return this.ctx.getCurrentUnstableMarker();
|
|
@@ -7689,27 +8280,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
|
|
|
7689
8280
|
}
|
|
7690
8281
|
};
|
|
7691
8282
|
//#endregion
|
|
7692
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
7693
|
-
const PlatformaSDKVersion = "1.
|
|
8283
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/version.js
|
|
8284
|
+
const PlatformaSDKVersion = "1.80.2";
|
|
7694
8285
|
//#endregion
|
|
7695
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8286
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/bconfig/types.js
|
|
7696
8287
|
function isConfigLambda(cfgOrFh) {
|
|
7697
8288
|
return cfgOrFh.__renderLambda === true;
|
|
7698
8289
|
}
|
|
7699
8290
|
//#endregion
|
|
7700
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8291
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
|
|
7701
8292
|
function downgradeCfgOrLambda(data) {
|
|
7702
8293
|
if (data === void 0) return void 0;
|
|
7703
8294
|
if (isConfigLambda(data)) return data.handle;
|
|
7704
8295
|
return data;
|
|
7705
8296
|
}
|
|
7706
8297
|
//#endregion
|
|
7707
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8298
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/plugin_model.js
|
|
7708
8299
|
/** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
|
|
7709
8300
|
* identical across multiple `@platforma-sdk/model` copies in one process. */
|
|
7710
8301
|
const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
|
|
7711
8302
|
//#endregion
|
|
7712
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8303
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
|
|
7713
8304
|
/**
|
|
7714
8305
|
* BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
|
|
7715
8306
|
*
|
|
@@ -7886,7 +8477,7 @@ function derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFuncti
|
|
|
7886
8477
|
}
|
|
7887
8478
|
}
|
|
7888
8479
|
//#endregion
|
|
7889
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8480
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/block_model.js
|
|
7890
8481
|
/**
|
|
7891
8482
|
* Merges two feature flag objects with type-aware logic:
|
|
7892
8483
|
* - `supports*` (boolean): OR — `true` if either side is `true`
|
|
@@ -8143,62 +8734,2320 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
8143
8734
|
[BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) => deriveArgsFromStorage(storageJson, argsFunction),
|
|
8144
8735
|
[BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) => derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction)
|
|
8145
8736
|
});
|
|
8146
|
-
const pluginOutputs = {};
|
|
8147
|
-
for (const handle of pluginHandles) {
|
|
8148
|
-
const { model, inputs } = plugins[handle];
|
|
8149
|
-
const wrappedInputs = {};
|
|
8150
|
-
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());
|
|
8151
|
-
const outputs = model.outputs;
|
|
8152
|
-
for (const [outputKey, outputFn] of Object.entries(outputs)) {
|
|
8153
|
-
const key = pluginOutputKey(handle, outputKey);
|
|
8154
|
-
pluginOutputs[key] = createAndRegisterRenderLambda({
|
|
8155
|
-
handle: key,
|
|
8156
|
-
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),
|
|
8157
|
-
withStatus: true
|
|
8158
|
-
});
|
|
8159
|
-
}
|
|
8737
|
+
const pluginOutputs = {};
|
|
8738
|
+
for (const handle of pluginHandles) {
|
|
8739
|
+
const { model, inputs } = plugins[handle];
|
|
8740
|
+
const wrappedInputs = {};
|
|
8741
|
+
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());
|
|
8742
|
+
const outputs = model.outputs;
|
|
8743
|
+
for (const [outputKey, outputFn] of Object.entries(outputs)) {
|
|
8744
|
+
const key = pluginOutputKey(handle, outputKey);
|
|
8745
|
+
pluginOutputs[key] = createAndRegisterRenderLambda({
|
|
8746
|
+
handle: key,
|
|
8747
|
+
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),
|
|
8748
|
+
withStatus: true
|
|
8749
|
+
});
|
|
8750
|
+
}
|
|
8751
|
+
}
|
|
8752
|
+
const allOutputs = {
|
|
8753
|
+
...this.config.outputs,
|
|
8754
|
+
...pluginOutputs
|
|
8755
|
+
};
|
|
8756
|
+
globalThis.platformaApiVersion = apiVersion;
|
|
8757
|
+
if (!isInUI()) return { config: {
|
|
8758
|
+
v4: {
|
|
8759
|
+
configVersion: 4,
|
|
8760
|
+
modelAPIVersion: 2,
|
|
8761
|
+
sdkVersion: PlatformaSDKVersion,
|
|
8762
|
+
renderingMode: this.config.renderingMode,
|
|
8763
|
+
sections: this.config.sections,
|
|
8764
|
+
title: this.config.title,
|
|
8765
|
+
subtitle: this.config.subtitle,
|
|
8766
|
+
tags: this.config.tags,
|
|
8767
|
+
outputs: allOutputs,
|
|
8768
|
+
enrichmentTargets: this.config.enrichmentTargets,
|
|
8769
|
+
featureFlags: this.config.featureFlags,
|
|
8770
|
+
blockLifecycleCallbacks: { ...BlockStorageFacadeHandles }
|
|
8771
|
+
},
|
|
8772
|
+
sdkVersion: PlatformaSDKVersion,
|
|
8773
|
+
renderingMode: this.config.renderingMode,
|
|
8774
|
+
sections: this.config.sections,
|
|
8775
|
+
outputs: Object.fromEntries(Object.entries(this.config.outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)]))
|
|
8776
|
+
} };
|
|
8777
|
+
else return {
|
|
8778
|
+
...getPlatformaInstance({
|
|
8779
|
+
sdkVersion: PlatformaSDKVersion,
|
|
8780
|
+
apiVersion
|
|
8781
|
+
}),
|
|
8782
|
+
blockModelInfo: {
|
|
8783
|
+
outputs: Object.fromEntries(Object.entries(allOutputs).map(([key, value]) => [key, { withStatus: Boolean(isConfigLambda(value) && value.withStatus) }])),
|
|
8784
|
+
pluginIds: pluginHandles,
|
|
8785
|
+
featureFlags: this.config.featureFlags,
|
|
8786
|
+
pluginPublicOutputs: Object.fromEntries(pluginHandles.map((handle) => [handle, plugins[handle].model.publicOutputDef]))
|
|
8787
|
+
}
|
|
8788
|
+
};
|
|
8789
|
+
}
|
|
8790
|
+
};
|
|
8791
|
+
//#endregion
|
|
8792
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
|
|
8793
|
+
/**
|
|
8794
|
+
* Replace every column leaf whose id equals `fromId` with `toId`, leaving
|
|
8795
|
+
* other column refs (linkers, sub-anchors) intact. Wrapper recipes
|
|
8796
|
+
* (Overridden / Filtered) and Discovered use this to lift their own id onto
|
|
8797
|
+
* the hit leaf, so per-variant uniqueness propagates to the engine and
|
|
8798
|
+
* resolver-emitted ids match leaves in the emitted SpecQuery.
|
|
8799
|
+
*
|
|
8800
|
+
* Generic over all SpecQuery node shapes — including `linkerJoin`, which
|
|
8801
|
+
* occurs when a wrapper sits over a {@link ColumnDiscoveredRecipe}: only
|
|
8802
|
+
* the deepest hit leaf carries `fromId`, every linker leaf has a different
|
|
8803
|
+
* id and is left untouched.
|
|
8804
|
+
*/
|
|
8805
|
+
function rebrandLeafId(node, fromId, toId) {
|
|
8806
|
+
if (fromId === toId) return node;
|
|
8807
|
+
return mapSpecQueryColumns(node, { column: (id) => id === fromId ? toId : id });
|
|
8808
|
+
}
|
|
8809
|
+
//#endregion
|
|
8810
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
|
|
8811
|
+
/**
|
|
8812
|
+
* Recipe wrapper that overlays {@link SpecOverrides} on top of any other
|
|
8813
|
+
* recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
|
|
8814
|
+
*
|
|
8815
|
+
* Flat-merge invariant: `inner` is never another {@link ColumnOverriddenRecipe}.
|
|
8816
|
+
* Repeated overrides go through {@link wrap} / {@link withSpecs}, which merge
|
|
8817
|
+
* `specOverrides` at the current level and keep wrapper depth constant.
|
|
8818
|
+
*
|
|
8819
|
+
* This invariant matches the one enforced inside `unwrapOverrides` from
|
|
8820
|
+
* pl-model-common: it explicitly throws on a nested override-wrap.
|
|
8821
|
+
*/
|
|
8822
|
+
var ColumnOverriddenRecipe = class ColumnOverriddenRecipe {
|
|
8823
|
+
inner;
|
|
8824
|
+
overrides;
|
|
8825
|
+
/**
|
|
8826
|
+
* Wrap any recipe with overrides. If `inner` is already a
|
|
8827
|
+
* {@link ColumnOverriddenRecipe}, merges `overrides` into the existing ones
|
|
8828
|
+
* and returns a new Overridden sharing the original `inner`. No
|
|
8829
|
+
* `Overridden<Overridden<X>>` is produced.
|
|
8830
|
+
*/
|
|
8831
|
+
static wrap(col, overrides) {
|
|
8832
|
+
if (col instanceof ColumnOverriddenRecipe) return new ColumnOverriddenRecipe(col.inner, mergeSpecOverrides(col.overrides, overrides));
|
|
8833
|
+
return new ColumnOverriddenRecipe(col, overrides);
|
|
8834
|
+
}
|
|
8835
|
+
/**
|
|
8836
|
+
* Static counterpart to {@link wrap}: returns the resolution status of a
|
|
8837
|
+
* {@link ColumnOverriddenKey} without constructing the recipe. Overrides
|
|
8838
|
+
* do not add references — status collapses to the source's status.
|
|
8839
|
+
*/
|
|
8840
|
+
static getStatusByKey(key, opts = {}) {
|
|
8841
|
+
return ColumnRecipe.getStatus(key.source, opts);
|
|
8842
|
+
}
|
|
8843
|
+
id;
|
|
8844
|
+
specCache;
|
|
8845
|
+
queryCache;
|
|
8846
|
+
dataStatusCache;
|
|
8847
|
+
constructor(inner, overrides) {
|
|
8848
|
+
this.inner = inner;
|
|
8849
|
+
this.overrides = overrides;
|
|
8850
|
+
this.id = createColumnOverriddenId({
|
|
8851
|
+
source: inner.id,
|
|
8852
|
+
specOverrides: overrides
|
|
8853
|
+
});
|
|
8854
|
+
}
|
|
8855
|
+
/** Wrapped recipe — exposed so external walkers can descend. */
|
|
8856
|
+
getInner() {
|
|
8857
|
+
return this.inner;
|
|
8858
|
+
}
|
|
8859
|
+
/**
|
|
8860
|
+
* `inner` owns all references; overrides are a pure spec patch and do not
|
|
8861
|
+
* introduce new column refs.
|
|
8862
|
+
*/
|
|
8863
|
+
getReferencedIds() {
|
|
8864
|
+
return this.inner.getReferencedIds();
|
|
8865
|
+
}
|
|
8866
|
+
getDataStatus() {
|
|
8867
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
|
|
8868
|
+
return this.dataStatusCache.value;
|
|
8869
|
+
}
|
|
8870
|
+
/**
|
|
8871
|
+
* Take the inner spec and overlay our overrides. `applySpecOverrides`
|
|
8872
|
+
* extracts the overrides from `this.id` itself.
|
|
8873
|
+
*/
|
|
8874
|
+
getSpec() {
|
|
8875
|
+
if (this.specCache === void 0) this.specCache = { value: applySpecOverrides(this.inner.getSpec(), this.id) };
|
|
8876
|
+
return this.specCache.value;
|
|
8877
|
+
}
|
|
8878
|
+
/**
|
|
8879
|
+
* Emit a client-side `specOverride` node wrapping the inner query.
|
|
8880
|
+
*
|
|
8881
|
+
* This is a structural-but-collapsible node: it carries the override
|
|
8882
|
+
* patch through the query tree so consumers see the full recipe shape,
|
|
8883
|
+
* but it is collapsed at the host boundary (`resolvePColumn`) before
|
|
8884
|
+
* the query reaches pframe-engine. The engine never sees this node.
|
|
8885
|
+
*
|
|
8886
|
+
* Overrides do not change query topology — they are a pure spec patch.
|
|
8887
|
+
*/
|
|
8888
|
+
getQuery() {
|
|
8889
|
+
if (this.queryCache === void 0) this.queryCache = { value: {
|
|
8890
|
+
type: "specOverride",
|
|
8891
|
+
input: rebrandLeafId(this.inner.getQuery(), this.inner.id, this.id),
|
|
8892
|
+
override: this.overrides
|
|
8893
|
+
} };
|
|
8894
|
+
return this.queryCache.value;
|
|
8895
|
+
}
|
|
8896
|
+
/**
|
|
8897
|
+
* Flat merge: new overrides merge with existing ones; `inner` is unchanged.
|
|
8898
|
+
* The result is an Overridden of the same depth.
|
|
8899
|
+
*/
|
|
8900
|
+
withSpecs(overrides) {
|
|
8901
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
8902
|
+
}
|
|
8903
|
+
};
|
|
8904
|
+
//#endregion
|
|
8905
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
|
|
8906
|
+
/**
|
|
8907
|
+
* Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
|
|
8908
|
+
* column + a `path` of linkers + qualifications.
|
|
8909
|
+
*
|
|
8910
|
+
* Specifics:
|
|
8911
|
+
* - References more than one column (`column` + each `path[i].column`);
|
|
8912
|
+
* {@link getDataStatus} aggregates across the whole set.
|
|
8913
|
+
* - {@link getQuery} assembles the {@link SpecQuery} locally
|
|
8914
|
+
* ({@link buildSpecQuery}) — the hit is inlined as its own recipe's query
|
|
8915
|
+
* tree, linkers fold inside-out into nested `linkerJoin` nodes.
|
|
8916
|
+
* - {@link getSpec} passes through to the hit column's own spec: the linker
|
|
8917
|
+
* chain only enables co-indexing and does not remap the hit's `axesSpec`, so
|
|
8918
|
+
* no engine round-trip is needed (mirrors the Discovered branch of
|
|
8919
|
+
* `reconstructSpecFromId` on the host side).
|
|
8920
|
+
*/
|
|
8921
|
+
var ColumnDiscoveredRecipe = class ColumnDiscoveredRecipe {
|
|
8922
|
+
key;
|
|
8923
|
+
columns;
|
|
8924
|
+
/**
|
|
8925
|
+
* Validate the key + resolve every referenced column via
|
|
8926
|
+
* {@link ColumnLazy.fromId} (which itself checks the leaf accessor reports
|
|
8927
|
+
* `hasData()`). Returns `undefined` if the key is malformed or any
|
|
8928
|
+
* referenced column is not yet spec-resolvable.
|
|
8929
|
+
*
|
|
8930
|
+
* Spec JSON is deserialized lazily on first {@link getSpec}/{@link getQuery}.
|
|
8931
|
+
*/
|
|
8932
|
+
static fromKey(key, opts = {}) {
|
|
8933
|
+
const distilled = distillColumnDiscoveredKey(key);
|
|
8934
|
+
const columns = {};
|
|
8935
|
+
for (const uniId of referencedUniIdsOf(distilled)) {
|
|
8936
|
+
const recipe = Column(uniId, opts);
|
|
8937
|
+
if (recipe === void 0) return void 0;
|
|
8938
|
+
columns[uniId] = recipe;
|
|
8939
|
+
}
|
|
8940
|
+
return new ColumnDiscoveredRecipe(distilled, columns);
|
|
8941
|
+
}
|
|
8942
|
+
/**
|
|
8943
|
+
* Static counterpart to {@link fromKey}: returns the resolution status of
|
|
8944
|
+
* a {@link ColumnDiscoveredKey} without constructing the recipe. Worst-wins
|
|
8945
|
+
* across every referenced {@link ColumnUniversalId} (hit + path linkers),
|
|
8946
|
+
* each resolved via the top-level {@link ColumnRecipe.getStatus} dispatcher.
|
|
8947
|
+
*/
|
|
8948
|
+
static getStatusByKey(key, opts = {}) {
|
|
8949
|
+
const distilled = distillColumnDiscoveredKey(key);
|
|
8950
|
+
let worst = "present";
|
|
8951
|
+
for (const uniId of referencedUniIdsOf(distilled)) {
|
|
8952
|
+
const s = ColumnRecipe.getStatus(uniId, opts);
|
|
8953
|
+
if (s === "absent") return "absent";
|
|
8954
|
+
if (s === "resolving") worst = "resolving";
|
|
8955
|
+
}
|
|
8956
|
+
return worst;
|
|
8957
|
+
}
|
|
8958
|
+
id;
|
|
8959
|
+
specCache;
|
|
8960
|
+
queryCache;
|
|
8961
|
+
dataStatusCache;
|
|
8962
|
+
constructor(key, columns) {
|
|
8963
|
+
this.key = key;
|
|
8964
|
+
this.columns = columns;
|
|
8965
|
+
this.id = stringifyColumnDiscoveredId(this.key);
|
|
8966
|
+
}
|
|
8967
|
+
/**
|
|
8968
|
+
* Universal id of the hit column (excluding path/qualifications on top).
|
|
8969
|
+
* May itself be a wrapped id (Overridden / Filtered / nested Discovered) —
|
|
8970
|
+
* preserves projections applied to the underlying column.
|
|
8971
|
+
*/
|
|
8972
|
+
getHitId() {
|
|
8973
|
+
return this.key.column;
|
|
8974
|
+
}
|
|
8975
|
+
/**
|
|
8976
|
+
* Axis qualifications attached to the hit column itself — applied to the
|
|
8977
|
+
* outer-join entry that wraps this column at the consumer boundary.
|
|
8978
|
+
*/
|
|
8979
|
+
getColumnQualifications() {
|
|
8980
|
+
return this.key.columnQualifications ?? [];
|
|
8981
|
+
}
|
|
8982
|
+
/**
|
|
8983
|
+
* Per-primary-column qualifications applied to the primary anchors on
|
|
8984
|
+
* this group's side. Keyed by the external primary column id.
|
|
8985
|
+
*/
|
|
8986
|
+
getQueriesQualifications() {
|
|
8987
|
+
return this.key.queriesQualifications ?? {};
|
|
8988
|
+
}
|
|
8989
|
+
/**
|
|
8990
|
+
* Leaf {@link PObjectId}s the recipe physically depends on: hit column +
|
|
8991
|
+
* each linker in `path`, with any projection wrappers unwrapped down to
|
|
8992
|
+
* their underlying storage column. Used to track real-data dependencies
|
|
8993
|
+
* (e.g. {@link getDataStatus}), not projected identities.
|
|
8994
|
+
*/
|
|
8995
|
+
getReferencedIds() {
|
|
8996
|
+
return [...new Set([...referencedUniIdsOf(this.key)].map((uniId) => extractPObjectId(uniId)))];
|
|
8997
|
+
}
|
|
8998
|
+
/**
|
|
8999
|
+
* Final spec of a discovered hit is just the hit column's own spec: the
|
|
9000
|
+
* linker chain only enables co-indexing, it does not remap the hit's
|
|
9001
|
+
* `axesSpec`, and axis qualifications live on the outer join entry (see
|
|
9002
|
+
* {@link buildSpecQuery}), not in the spec. So pass through to the hit
|
|
9003
|
+
* recipe's `getSpec()` — no engine round-trip needed. This mirrors the
|
|
9004
|
+
* Discovered branch of `reconstructSpecFromId` on the host side.
|
|
9005
|
+
*/
|
|
9006
|
+
getSpec() {
|
|
9007
|
+
if (this.specCache === void 0) {
|
|
9008
|
+
const hit = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.getSpec: missing column ${this.key.column}`);
|
|
9009
|
+
this.specCache = { value: hit.getSpec() };
|
|
9010
|
+
}
|
|
9011
|
+
return this.specCache.value;
|
|
9012
|
+
}
|
|
9013
|
+
/** IR for building the final spec — see {@link buildSpecQuery}. */
|
|
9014
|
+
getQuery() {
|
|
9015
|
+
if (this.queryCache === void 0) this.queryCache = { value: this.buildSpecQuery() };
|
|
9016
|
+
return this.queryCache.value;
|
|
9017
|
+
}
|
|
9018
|
+
getDataStatus() {
|
|
9019
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: Object.values(this.columns).reduce((worst, lazy) => {
|
|
9020
|
+
const s = lazy.getDataStatus();
|
|
9021
|
+
if (s === "absent" || worst === "absent") return "absent";
|
|
9022
|
+
if (s === "resolving") return "resolving";
|
|
9023
|
+
return worst;
|
|
9024
|
+
}, "present") };
|
|
9025
|
+
return this.dataStatusCache.value;
|
|
9026
|
+
}
|
|
9027
|
+
/**
|
|
9028
|
+
* Discovered + overrides → Overridden<Discovered>. Delegates to the
|
|
9029
|
+
* flat-merge factory of ColumnOverriddenRecipe; subsequent `withSpecs`
|
|
9030
|
+
* calls merge at the Overridden level (one wrapper, no nesting).
|
|
9031
|
+
*/
|
|
9032
|
+
withSpecs(overrides) {
|
|
9033
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
9034
|
+
}
|
|
9035
|
+
/**
|
|
9036
|
+
* Assembles the SpecQuery for this discovered hit by folding `key.path`
|
|
9037
|
+
* around the hit column.
|
|
9038
|
+
*
|
|
9039
|
+
* The hit (innermost) is built by inlining `columns[key.column].getQuery()`
|
|
9040
|
+
* — recursing into the hit's own recipe — so wrapping layers on the hit
|
|
9041
|
+
* (Overridden / Filtered / nested Discovered) appear in the produced tree.
|
|
9042
|
+
* The previous `pframeSpec.buildQuery` path was a flat
|
|
9043
|
+
* {@link PObjectId}-only call and could not express that.
|
|
9044
|
+
*
|
|
9045
|
+
* Linkers stay as plain column references on the linker side of
|
|
9046
|
+
* `linkerJoin` (the spec node has no slot for a query-side linker); the
|
|
9047
|
+
* linker's recipe id is used directly. The frame registered in
|
|
9048
|
+
* {@link getSpec} carries each recipe's final spec under that same id, so
|
|
9049
|
+
* the engine resolves linker axes from the post-projection spec.
|
|
9050
|
+
*
|
|
9051
|
+
* Path ordering matches {@link ColumnDiscoveredKey.path}: `path[0]` is
|
|
9052
|
+
* outermost, `path[N-1]` is closest to the hit. We fold from the inside
|
|
9053
|
+
* out — innermost wrap first — so the result lines up with that convention.
|
|
9054
|
+
*
|
|
9055
|
+
* `columnQualifications` / `queriesQualifications` are not emitted here —
|
|
9056
|
+
* qualifications live on a {@link SpecQueryJoinEntry} wrapper (lost on
|
|
9057
|
+
* unwrapping to {@link SpecQuery}). External consumers apply them at the
|
|
9058
|
+
* outer join via {@link getColumnQualifications} / {@link getQueriesQualifications}.
|
|
9059
|
+
*/
|
|
9060
|
+
buildSpecQuery() {
|
|
9061
|
+
const hitRecipe = this.columns[this.key.column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing column ${this.key.column}`);
|
|
9062
|
+
let query = rebrandLeafId(hitRecipe.getQuery(), hitRecipe.id, this.id);
|
|
9063
|
+
const path = this.key.path ?? [];
|
|
9064
|
+
for (let i = path.length - 1; i >= 0; i--) query = {
|
|
9065
|
+
type: "linkerJoin",
|
|
9066
|
+
linker: (this.columns[path[i].column] ?? throwError(`ColumnDiscoveredRecipe.buildSpecQuery: missing linker column ${path[i].column}`)).getQuery(),
|
|
9067
|
+
secondary: [{ entry: query }]
|
|
9068
|
+
};
|
|
9069
|
+
return query;
|
|
9070
|
+
}
|
|
9071
|
+
};
|
|
9072
|
+
function referencedUniIdsOf(key) {
|
|
9073
|
+
return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
|
|
9074
|
+
}
|
|
9075
|
+
//#endregion
|
|
9076
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
|
|
9077
|
+
/**
|
|
9078
|
+
* Recipe wrapper that fixes the values of selected axes of an inner recipe
|
|
9079
|
+
* (axis slicing). The id is `FilteredPColumnId { source: inner.id,
|
|
9080
|
+
* axisFilters }`.
|
|
9081
|
+
*
|
|
9082
|
+
* Flat-merge invariant: `inner` is never another {@link ColumnFilteredRecipe}.
|
|
9083
|
+
* Repeated {@link wrap} concatenates `axisFilters` at the current level.
|
|
9084
|
+
*
|
|
9085
|
+
* Layering: `withSpecs` on a Filtered recipe yields
|
|
9086
|
+
* `Overridden<Filtered<inner>>` — Overridden is always the outermost layer.
|
|
9087
|
+
* The reverse layering (`Filtered<Overridden<...>>`) is not reachable via
|
|
9088
|
+
* the public interface.
|
|
9089
|
+
*/
|
|
9090
|
+
var ColumnFilteredRecipe = class ColumnFilteredRecipe {
|
|
9091
|
+
inner;
|
|
9092
|
+
axisFilters;
|
|
9093
|
+
/**
|
|
9094
|
+
* Wrap any recipe with axis filters. If `inner` is already a
|
|
9095
|
+
* {@link ColumnFilteredRecipe}, concatenates `axisFilters` and returns a
|
|
9096
|
+
* new Filtered sharing the original `inner`.
|
|
9097
|
+
*
|
|
9098
|
+
* Validates every axis index against `inner.getSpec().axesSpec` at
|
|
9099
|
+
* construction — throws on an out-of-range index. After {@link wrap}, the
|
|
9100
|
+
* recipe is guaranteed to be spec-complete.
|
|
9101
|
+
*
|
|
9102
|
+
* Order semantics: new filters are appended after existing ones, preserving
|
|
9103
|
+
* their relative order. AND composition is otherwise commutative; order
|
|
9104
|
+
* only affects canonicalize/equality.
|
|
9105
|
+
*/
|
|
9106
|
+
static wrap(col, axisFilters) {
|
|
9107
|
+
const combined = col instanceof ColumnFilteredRecipe ? [...col.axisFilters, ...axisFilters] : axisFilters;
|
|
9108
|
+
const base = col instanceof ColumnFilteredRecipe ? col.inner : col;
|
|
9109
|
+
if (combined.length === 0) throw new Error("ColumnFilteredRecipe.wrap: at least one axis filter must be provided");
|
|
9110
|
+
const innerSpec = base.getSpec();
|
|
9111
|
+
const fixed = /* @__PURE__ */ new Set();
|
|
9112
|
+
for (const [idx] of combined) {
|
|
9113
|
+
if (innerSpec.axesSpec[idx] === void 0) throw new Error(`ColumnFilteredRecipe.wrap: axis index ${idx} out of range (inner has ${innerSpec.axesSpec.length} axes)`);
|
|
9114
|
+
fixed.add(idx);
|
|
9115
|
+
}
|
|
9116
|
+
if (fixed.size >= innerSpec.axesSpec.length) throw new Error(`ColumnFilteredRecipe.wrap: filters fix all ${innerSpec.axesSpec.length} axes — at least one axis must remain`);
|
|
9117
|
+
return new ColumnFilteredRecipe(base, combined);
|
|
9118
|
+
}
|
|
9119
|
+
/**
|
|
9120
|
+
* Static counterpart to {@link wrap}: returns the resolution status of a
|
|
9121
|
+
* {@link ColumnFilteredKey} without constructing the recipe. Axis filters
|
|
9122
|
+
* do not add references — status collapses to the source's status.
|
|
9123
|
+
*/
|
|
9124
|
+
static getStatusByKey(key, opts = {}) {
|
|
9125
|
+
if (typeof key.source !== "string") throw new Error("ColumnFilteredRecipe.getStatusByKey: filtered column with non-string source");
|
|
9126
|
+
return ColumnRecipe.getStatus(key.source, opts);
|
|
9127
|
+
}
|
|
9128
|
+
id;
|
|
9129
|
+
specCache;
|
|
9130
|
+
queryCache;
|
|
9131
|
+
dataStatusCache;
|
|
9132
|
+
constructor(inner, axisFilters) {
|
|
9133
|
+
this.inner = inner;
|
|
9134
|
+
this.axisFilters = axisFilters;
|
|
9135
|
+
this.id = stringifyColumnFilteredId({
|
|
9136
|
+
source: inner.id,
|
|
9137
|
+
axisFilters
|
|
9138
|
+
});
|
|
9139
|
+
}
|
|
9140
|
+
/** Wrapped recipe — exposed so external walkers can descend. */
|
|
9141
|
+
getInner() {
|
|
9142
|
+
return this.inner;
|
|
9143
|
+
}
|
|
9144
|
+
/** Axis filters do not introduce references to other columns. */
|
|
9145
|
+
getReferencedIds() {
|
|
9146
|
+
return this.inner.getReferencedIds();
|
|
9147
|
+
}
|
|
9148
|
+
getDataStatus() {
|
|
9149
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.inner.getDataStatus() };
|
|
9150
|
+
return this.dataStatusCache.value;
|
|
9151
|
+
}
|
|
9152
|
+
/**
|
|
9153
|
+
* Final spec — the inner spec with fixed axes removed. Indices in
|
|
9154
|
+
* `axisFilters` are positional against `inner.getSpec().axesSpec` and were
|
|
9155
|
+
* validated at {@link wrap} time.
|
|
9156
|
+
*/
|
|
9157
|
+
getSpec() {
|
|
9158
|
+
if (this.specCache === void 0) this.specCache = { value: applyAxisFilters(this.inner.getSpec(), this.axisFilters) };
|
|
9159
|
+
return this.specCache.value;
|
|
9160
|
+
}
|
|
9161
|
+
/**
|
|
9162
|
+
* Wraps the inner query in `SpecQuerySliceAxes`. Index→selector resolution
|
|
9163
|
+
* goes through the inner spec — guaranteed available since {@link wrap}
|
|
9164
|
+
* validated all indices at construction.
|
|
9165
|
+
*/
|
|
9166
|
+
getQuery() {
|
|
9167
|
+
if (this.queryCache === void 0) {
|
|
9168
|
+
const innerQuery = this.inner.getQuery();
|
|
9169
|
+
if (this.axisFilters.length === 0) this.queryCache = { value: rebrandLeafId(innerQuery, this.inner.id, this.id) };
|
|
9170
|
+
else {
|
|
9171
|
+
const innerSpec = this.inner.getSpec();
|
|
9172
|
+
this.queryCache = { value: {
|
|
9173
|
+
type: "sliceAxes",
|
|
9174
|
+
input: rebrandLeafId(innerQuery, this.inner.id, this.id),
|
|
9175
|
+
axisFilters: this.axisFilters.map(([idx, value]) => ({
|
|
9176
|
+
axisSelector: toAxisSelector(innerSpec.axesSpec[idx]),
|
|
9177
|
+
constant: value
|
|
9178
|
+
}))
|
|
9179
|
+
} };
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
9182
|
+
return this.queryCache.value;
|
|
9183
|
+
}
|
|
9184
|
+
/**
|
|
9185
|
+
* Filtered + overrides → Overridden<Filtered>. Overridden is always the
|
|
9186
|
+
* outermost layer.
|
|
9187
|
+
*/
|
|
9188
|
+
withSpecs(overrides) {
|
|
9189
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
9190
|
+
}
|
|
9191
|
+
};
|
|
9192
|
+
function toAxisSelector(axis) {
|
|
9193
|
+
const selector = {
|
|
9194
|
+
name: axis.name,
|
|
9195
|
+
type: axis.type
|
|
9196
|
+
};
|
|
9197
|
+
if (axis.domain !== void 0 && Object.keys(axis.domain).length > 0) selector.domain = axis.domain;
|
|
9198
|
+
if (axis.contextDomain !== void 0 && Object.keys(axis.contextDomain).length > 0) selector.contextDomain = axis.contextDomain;
|
|
9199
|
+
return selector;
|
|
9200
|
+
}
|
|
9201
|
+
//#endregion
|
|
9202
|
+
//#region ../node_modules/.pnpm/lru-cache@11.2.4/node_modules/lru-cache/dist/esm/index.js
|
|
9203
|
+
/**
|
|
9204
|
+
* @module LRUCache
|
|
9205
|
+
*/
|
|
9206
|
+
const defaultPerf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
|
|
9207
|
+
const warned = /* @__PURE__ */ new Set();
|
|
9208
|
+
/* c8 ignore start */
|
|
9209
|
+
const PROCESS = typeof process === "object" && !!process ? process : {};
|
|
9210
|
+
/* c8 ignore start */
|
|
9211
|
+
const emitWarning = (msg, type, code, fn) => {
|
|
9212
|
+
typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`);
|
|
9213
|
+
};
|
|
9214
|
+
let AC = globalThis.AbortController;
|
|
9215
|
+
let AS = globalThis.AbortSignal;
|
|
9216
|
+
/* c8 ignore start */
|
|
9217
|
+
if (typeof AC === "undefined") {
|
|
9218
|
+
AS = class AbortSignal {
|
|
9219
|
+
onabort;
|
|
9220
|
+
_onabort = [];
|
|
9221
|
+
reason;
|
|
9222
|
+
aborted = false;
|
|
9223
|
+
addEventListener(_, fn) {
|
|
9224
|
+
this._onabort.push(fn);
|
|
9225
|
+
}
|
|
9226
|
+
};
|
|
9227
|
+
AC = class AbortController {
|
|
9228
|
+
constructor() {
|
|
9229
|
+
warnACPolyfill();
|
|
9230
|
+
}
|
|
9231
|
+
signal = new AS();
|
|
9232
|
+
abort(reason) {
|
|
9233
|
+
if (this.signal.aborted) return;
|
|
9234
|
+
this.signal.reason = reason;
|
|
9235
|
+
this.signal.aborted = true;
|
|
9236
|
+
for (const fn of this.signal._onabort) fn(reason);
|
|
9237
|
+
this.signal.onabort?.(reason);
|
|
9238
|
+
}
|
|
9239
|
+
};
|
|
9240
|
+
let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== "1";
|
|
9241
|
+
const warnACPolyfill = () => {
|
|
9242
|
+
if (!printACPolyfillWarning) return;
|
|
9243
|
+
printACPolyfillWarning = false;
|
|
9244
|
+
emitWarning("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.", "NO_ABORT_CONTROLLER", "ENOTSUP", warnACPolyfill);
|
|
9245
|
+
};
|
|
9246
|
+
}
|
|
9247
|
+
/* c8 ignore stop */
|
|
9248
|
+
const shouldWarn = (code) => !warned.has(code);
|
|
9249
|
+
const isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);
|
|
9250
|
+
/* c8 ignore start */
|
|
9251
|
+
const getUintArray = (max) => !isPosInt(max) ? null : max <= Math.pow(2, 8) ? Uint8Array : max <= Math.pow(2, 16) ? Uint16Array : max <= Math.pow(2, 32) ? Uint32Array : max <= Number.MAX_SAFE_INTEGER ? ZeroArray : null;
|
|
9252
|
+
/* c8 ignore stop */
|
|
9253
|
+
var ZeroArray = class extends Array {
|
|
9254
|
+
constructor(size) {
|
|
9255
|
+
super(size);
|
|
9256
|
+
this.fill(0);
|
|
9257
|
+
}
|
|
9258
|
+
};
|
|
9259
|
+
var Stack = class Stack {
|
|
9260
|
+
heap;
|
|
9261
|
+
length;
|
|
9262
|
+
static #constructing = false;
|
|
9263
|
+
static create(max) {
|
|
9264
|
+
const HeapCls = getUintArray(max);
|
|
9265
|
+
if (!HeapCls) return [];
|
|
9266
|
+
Stack.#constructing = true;
|
|
9267
|
+
const s = new Stack(max, HeapCls);
|
|
9268
|
+
Stack.#constructing = false;
|
|
9269
|
+
return s;
|
|
9270
|
+
}
|
|
9271
|
+
constructor(max, HeapCls) {
|
|
9272
|
+
/* c8 ignore start */
|
|
9273
|
+
if (!Stack.#constructing) throw new TypeError("instantiate Stack using Stack.create(n)");
|
|
9274
|
+
/* c8 ignore stop */
|
|
9275
|
+
this.heap = new HeapCls(max);
|
|
9276
|
+
this.length = 0;
|
|
9277
|
+
}
|
|
9278
|
+
push(n) {
|
|
9279
|
+
this.heap[this.length++] = n;
|
|
9280
|
+
}
|
|
9281
|
+
pop() {
|
|
9282
|
+
return this.heap[--this.length];
|
|
9283
|
+
}
|
|
9284
|
+
};
|
|
9285
|
+
/**
|
|
9286
|
+
* Default export, the thing you're using this module to get.
|
|
9287
|
+
*
|
|
9288
|
+
* The `K` and `V` types define the key and value types, respectively. The
|
|
9289
|
+
* optional `FC` type defines the type of the `context` object passed to
|
|
9290
|
+
* `cache.fetch()` and `cache.memo()`.
|
|
9291
|
+
*
|
|
9292
|
+
* Keys and values **must not** be `null` or `undefined`.
|
|
9293
|
+
*
|
|
9294
|
+
* All properties from the options object (with the exception of `max`,
|
|
9295
|
+
* `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are
|
|
9296
|
+
* added as normal public members. (The listed options are read-only getters.)
|
|
9297
|
+
*
|
|
9298
|
+
* Changing any of these will alter the defaults for subsequent method calls.
|
|
9299
|
+
*/
|
|
9300
|
+
var LRUCache = class LRUCache {
|
|
9301
|
+
#max;
|
|
9302
|
+
#maxSize;
|
|
9303
|
+
#dispose;
|
|
9304
|
+
#onInsert;
|
|
9305
|
+
#disposeAfter;
|
|
9306
|
+
#fetchMethod;
|
|
9307
|
+
#memoMethod;
|
|
9308
|
+
#perf;
|
|
9309
|
+
/**
|
|
9310
|
+
* {@link LRUCache.OptionsBase.perf}
|
|
9311
|
+
*/
|
|
9312
|
+
get perf() {
|
|
9313
|
+
return this.#perf;
|
|
9314
|
+
}
|
|
9315
|
+
/**
|
|
9316
|
+
* {@link LRUCache.OptionsBase.ttl}
|
|
9317
|
+
*/
|
|
9318
|
+
ttl;
|
|
9319
|
+
/**
|
|
9320
|
+
* {@link LRUCache.OptionsBase.ttlResolution}
|
|
9321
|
+
*/
|
|
9322
|
+
ttlResolution;
|
|
9323
|
+
/**
|
|
9324
|
+
* {@link LRUCache.OptionsBase.ttlAutopurge}
|
|
9325
|
+
*/
|
|
9326
|
+
ttlAutopurge;
|
|
9327
|
+
/**
|
|
9328
|
+
* {@link LRUCache.OptionsBase.updateAgeOnGet}
|
|
9329
|
+
*/
|
|
9330
|
+
updateAgeOnGet;
|
|
9331
|
+
/**
|
|
9332
|
+
* {@link LRUCache.OptionsBase.updateAgeOnHas}
|
|
9333
|
+
*/
|
|
9334
|
+
updateAgeOnHas;
|
|
9335
|
+
/**
|
|
9336
|
+
* {@link LRUCache.OptionsBase.allowStale}
|
|
9337
|
+
*/
|
|
9338
|
+
allowStale;
|
|
9339
|
+
/**
|
|
9340
|
+
* {@link LRUCache.OptionsBase.noDisposeOnSet}
|
|
9341
|
+
*/
|
|
9342
|
+
noDisposeOnSet;
|
|
9343
|
+
/**
|
|
9344
|
+
* {@link LRUCache.OptionsBase.noUpdateTTL}
|
|
9345
|
+
*/
|
|
9346
|
+
noUpdateTTL;
|
|
9347
|
+
/**
|
|
9348
|
+
* {@link LRUCache.OptionsBase.maxEntrySize}
|
|
9349
|
+
*/
|
|
9350
|
+
maxEntrySize;
|
|
9351
|
+
/**
|
|
9352
|
+
* {@link LRUCache.OptionsBase.sizeCalculation}
|
|
9353
|
+
*/
|
|
9354
|
+
sizeCalculation;
|
|
9355
|
+
/**
|
|
9356
|
+
* {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}
|
|
9357
|
+
*/
|
|
9358
|
+
noDeleteOnFetchRejection;
|
|
9359
|
+
/**
|
|
9360
|
+
* {@link LRUCache.OptionsBase.noDeleteOnStaleGet}
|
|
9361
|
+
*/
|
|
9362
|
+
noDeleteOnStaleGet;
|
|
9363
|
+
/**
|
|
9364
|
+
* {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}
|
|
9365
|
+
*/
|
|
9366
|
+
allowStaleOnFetchAbort;
|
|
9367
|
+
/**
|
|
9368
|
+
* {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}
|
|
9369
|
+
*/
|
|
9370
|
+
allowStaleOnFetchRejection;
|
|
9371
|
+
/**
|
|
9372
|
+
* {@link LRUCache.OptionsBase.ignoreFetchAbort}
|
|
9373
|
+
*/
|
|
9374
|
+
ignoreFetchAbort;
|
|
9375
|
+
#size;
|
|
9376
|
+
#calculatedSize;
|
|
9377
|
+
#keyMap;
|
|
9378
|
+
#keyList;
|
|
9379
|
+
#valList;
|
|
9380
|
+
#next;
|
|
9381
|
+
#prev;
|
|
9382
|
+
#head;
|
|
9383
|
+
#tail;
|
|
9384
|
+
#free;
|
|
9385
|
+
#disposed;
|
|
9386
|
+
#sizes;
|
|
9387
|
+
#starts;
|
|
9388
|
+
#ttls;
|
|
9389
|
+
#autopurgeTimers;
|
|
9390
|
+
#hasDispose;
|
|
9391
|
+
#hasFetchMethod;
|
|
9392
|
+
#hasDisposeAfter;
|
|
9393
|
+
#hasOnInsert;
|
|
9394
|
+
/**
|
|
9395
|
+
* Do not call this method unless you need to inspect the
|
|
9396
|
+
* inner workings of the cache. If anything returned by this
|
|
9397
|
+
* object is modified in any way, strange breakage may occur.
|
|
9398
|
+
*
|
|
9399
|
+
* These fields are private for a reason!
|
|
9400
|
+
*
|
|
9401
|
+
* @internal
|
|
9402
|
+
*/
|
|
9403
|
+
static unsafeExposeInternals(c) {
|
|
9404
|
+
return {
|
|
9405
|
+
starts: c.#starts,
|
|
9406
|
+
ttls: c.#ttls,
|
|
9407
|
+
autopurgeTimers: c.#autopurgeTimers,
|
|
9408
|
+
sizes: c.#sizes,
|
|
9409
|
+
keyMap: c.#keyMap,
|
|
9410
|
+
keyList: c.#keyList,
|
|
9411
|
+
valList: c.#valList,
|
|
9412
|
+
next: c.#next,
|
|
9413
|
+
prev: c.#prev,
|
|
9414
|
+
get head() {
|
|
9415
|
+
return c.#head;
|
|
9416
|
+
},
|
|
9417
|
+
get tail() {
|
|
9418
|
+
return c.#tail;
|
|
9419
|
+
},
|
|
9420
|
+
free: c.#free,
|
|
9421
|
+
isBackgroundFetch: (p) => c.#isBackgroundFetch(p),
|
|
9422
|
+
backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context),
|
|
9423
|
+
moveToTail: (index) => c.#moveToTail(index),
|
|
9424
|
+
indexes: (options) => c.#indexes(options),
|
|
9425
|
+
rindexes: (options) => c.#rindexes(options),
|
|
9426
|
+
isStale: (index) => c.#isStale(index)
|
|
9427
|
+
};
|
|
9428
|
+
}
|
|
9429
|
+
/**
|
|
9430
|
+
* {@link LRUCache.OptionsBase.max} (read-only)
|
|
9431
|
+
*/
|
|
9432
|
+
get max() {
|
|
9433
|
+
return this.#max;
|
|
9434
|
+
}
|
|
9435
|
+
/**
|
|
9436
|
+
* {@link LRUCache.OptionsBase.maxSize} (read-only)
|
|
9437
|
+
*/
|
|
9438
|
+
get maxSize() {
|
|
9439
|
+
return this.#maxSize;
|
|
9440
|
+
}
|
|
9441
|
+
/**
|
|
9442
|
+
* The total computed size of items in the cache (read-only)
|
|
9443
|
+
*/
|
|
9444
|
+
get calculatedSize() {
|
|
9445
|
+
return this.#calculatedSize;
|
|
9446
|
+
}
|
|
9447
|
+
/**
|
|
9448
|
+
* The number of items stored in the cache (read-only)
|
|
9449
|
+
*/
|
|
9450
|
+
get size() {
|
|
9451
|
+
return this.#size;
|
|
9452
|
+
}
|
|
9453
|
+
/**
|
|
9454
|
+
* {@link LRUCache.OptionsBase.fetchMethod} (read-only)
|
|
9455
|
+
*/
|
|
9456
|
+
get fetchMethod() {
|
|
9457
|
+
return this.#fetchMethod;
|
|
9458
|
+
}
|
|
9459
|
+
get memoMethod() {
|
|
9460
|
+
return this.#memoMethod;
|
|
9461
|
+
}
|
|
9462
|
+
/**
|
|
9463
|
+
* {@link LRUCache.OptionsBase.dispose} (read-only)
|
|
9464
|
+
*/
|
|
9465
|
+
get dispose() {
|
|
9466
|
+
return this.#dispose;
|
|
9467
|
+
}
|
|
9468
|
+
/**
|
|
9469
|
+
* {@link LRUCache.OptionsBase.onInsert} (read-only)
|
|
9470
|
+
*/
|
|
9471
|
+
get onInsert() {
|
|
9472
|
+
return this.#onInsert;
|
|
9473
|
+
}
|
|
9474
|
+
/**
|
|
9475
|
+
* {@link LRUCache.OptionsBase.disposeAfter} (read-only)
|
|
9476
|
+
*/
|
|
9477
|
+
get disposeAfter() {
|
|
9478
|
+
return this.#disposeAfter;
|
|
9479
|
+
}
|
|
9480
|
+
constructor(options) {
|
|
9481
|
+
const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, perf } = options;
|
|
9482
|
+
if (perf !== void 0) {
|
|
9483
|
+
if (typeof perf?.now !== "function") throw new TypeError("perf option must have a now() method if specified");
|
|
9484
|
+
}
|
|
9485
|
+
this.#perf = perf ?? defaultPerf;
|
|
9486
|
+
if (max !== 0 && !isPosInt(max)) throw new TypeError("max option must be a nonnegative integer");
|
|
9487
|
+
const UintArray = max ? getUintArray(max) : Array;
|
|
9488
|
+
if (!UintArray) throw new Error("invalid max value: " + max);
|
|
9489
|
+
this.#max = max;
|
|
9490
|
+
this.#maxSize = maxSize;
|
|
9491
|
+
this.maxEntrySize = maxEntrySize || this.#maxSize;
|
|
9492
|
+
this.sizeCalculation = sizeCalculation;
|
|
9493
|
+
if (this.sizeCalculation) {
|
|
9494
|
+
if (!this.#maxSize && !this.maxEntrySize) throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
|
|
9495
|
+
if (typeof this.sizeCalculation !== "function") throw new TypeError("sizeCalculation set to non-function");
|
|
9496
|
+
}
|
|
9497
|
+
if (memoMethod !== void 0 && typeof memoMethod !== "function") throw new TypeError("memoMethod must be a function if defined");
|
|
9498
|
+
this.#memoMethod = memoMethod;
|
|
9499
|
+
if (fetchMethod !== void 0 && typeof fetchMethod !== "function") throw new TypeError("fetchMethod must be a function if specified");
|
|
9500
|
+
this.#fetchMethod = fetchMethod;
|
|
9501
|
+
this.#hasFetchMethod = !!fetchMethod;
|
|
9502
|
+
this.#keyMap = /* @__PURE__ */ new Map();
|
|
9503
|
+
this.#keyList = new Array(max).fill(void 0);
|
|
9504
|
+
this.#valList = new Array(max).fill(void 0);
|
|
9505
|
+
this.#next = new UintArray(max);
|
|
9506
|
+
this.#prev = new UintArray(max);
|
|
9507
|
+
this.#head = 0;
|
|
9508
|
+
this.#tail = 0;
|
|
9509
|
+
this.#free = Stack.create(max);
|
|
9510
|
+
this.#size = 0;
|
|
9511
|
+
this.#calculatedSize = 0;
|
|
9512
|
+
if (typeof dispose === "function") this.#dispose = dispose;
|
|
9513
|
+
if (typeof onInsert === "function") this.#onInsert = onInsert;
|
|
9514
|
+
if (typeof disposeAfter === "function") {
|
|
9515
|
+
this.#disposeAfter = disposeAfter;
|
|
9516
|
+
this.#disposed = [];
|
|
9517
|
+
} else {
|
|
9518
|
+
this.#disposeAfter = void 0;
|
|
9519
|
+
this.#disposed = void 0;
|
|
9520
|
+
}
|
|
9521
|
+
this.#hasDispose = !!this.#dispose;
|
|
9522
|
+
this.#hasOnInsert = !!this.#onInsert;
|
|
9523
|
+
this.#hasDisposeAfter = !!this.#disposeAfter;
|
|
9524
|
+
this.noDisposeOnSet = !!noDisposeOnSet;
|
|
9525
|
+
this.noUpdateTTL = !!noUpdateTTL;
|
|
9526
|
+
this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection;
|
|
9527
|
+
this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection;
|
|
9528
|
+
this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort;
|
|
9529
|
+
this.ignoreFetchAbort = !!ignoreFetchAbort;
|
|
9530
|
+
if (this.maxEntrySize !== 0) {
|
|
9531
|
+
if (this.#maxSize !== 0) {
|
|
9532
|
+
if (!isPosInt(this.#maxSize)) throw new TypeError("maxSize must be a positive integer if specified");
|
|
9533
|
+
}
|
|
9534
|
+
if (!isPosInt(this.maxEntrySize)) throw new TypeError("maxEntrySize must be a positive integer if specified");
|
|
9535
|
+
this.#initializeSizeTracking();
|
|
9536
|
+
}
|
|
9537
|
+
this.allowStale = !!allowStale;
|
|
9538
|
+
this.noDeleteOnStaleGet = !!noDeleteOnStaleGet;
|
|
9539
|
+
this.updateAgeOnGet = !!updateAgeOnGet;
|
|
9540
|
+
this.updateAgeOnHas = !!updateAgeOnHas;
|
|
9541
|
+
this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1;
|
|
9542
|
+
this.ttlAutopurge = !!ttlAutopurge;
|
|
9543
|
+
this.ttl = ttl || 0;
|
|
9544
|
+
if (this.ttl) {
|
|
9545
|
+
if (!isPosInt(this.ttl)) throw new TypeError("ttl must be a positive integer if specified");
|
|
9546
|
+
this.#initializeTTLTracking();
|
|
9547
|
+
}
|
|
9548
|
+
if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) throw new TypeError("At least one of max, maxSize, or ttl is required");
|
|
9549
|
+
if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {
|
|
9550
|
+
const code = "LRU_CACHE_UNBOUNDED";
|
|
9551
|
+
if (shouldWarn(code)) {
|
|
9552
|
+
warned.add(code);
|
|
9553
|
+
emitWarning("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", code, LRUCache);
|
|
9554
|
+
}
|
|
9555
|
+
}
|
|
9556
|
+
}
|
|
9557
|
+
/**
|
|
9558
|
+
* Return the number of ms left in the item's TTL. If item is not in cache,
|
|
9559
|
+
* returns `0`. Returns `Infinity` if item is in cache without a defined TTL.
|
|
9560
|
+
*/
|
|
9561
|
+
getRemainingTTL(key) {
|
|
9562
|
+
return this.#keyMap.has(key) ? Infinity : 0;
|
|
9563
|
+
}
|
|
9564
|
+
#initializeTTLTracking() {
|
|
9565
|
+
const ttls = new ZeroArray(this.#max);
|
|
9566
|
+
const starts = new ZeroArray(this.#max);
|
|
9567
|
+
this.#ttls = ttls;
|
|
9568
|
+
this.#starts = starts;
|
|
9569
|
+
const purgeTimers = this.ttlAutopurge ? new Array(this.#max) : void 0;
|
|
9570
|
+
this.#autopurgeTimers = purgeTimers;
|
|
9571
|
+
this.#setItemTTL = (index, ttl, start = this.#perf.now()) => {
|
|
9572
|
+
starts[index] = ttl !== 0 ? start : 0;
|
|
9573
|
+
ttls[index] = ttl;
|
|
9574
|
+
if (purgeTimers?.[index]) {
|
|
9575
|
+
clearTimeout(purgeTimers[index]);
|
|
9576
|
+
purgeTimers[index] = void 0;
|
|
9577
|
+
}
|
|
9578
|
+
if (ttl !== 0 && purgeTimers) {
|
|
9579
|
+
const t = setTimeout(() => {
|
|
9580
|
+
if (this.#isStale(index)) this.#delete(this.#keyList[index], "expire");
|
|
9581
|
+
}, ttl + 1);
|
|
9582
|
+
/* c8 ignore start */
|
|
9583
|
+
if (t.unref) t.unref();
|
|
9584
|
+
/* c8 ignore stop */
|
|
9585
|
+
purgeTimers[index] = t;
|
|
9586
|
+
}
|
|
9587
|
+
};
|
|
9588
|
+
this.#updateItemAge = (index) => {
|
|
9589
|
+
starts[index] = ttls[index] !== 0 ? this.#perf.now() : 0;
|
|
9590
|
+
};
|
|
9591
|
+
this.#statusTTL = (status, index) => {
|
|
9592
|
+
if (ttls[index]) {
|
|
9593
|
+
const ttl = ttls[index];
|
|
9594
|
+
const start = starts[index];
|
|
9595
|
+
/* c8 ignore next */
|
|
9596
|
+
if (!ttl || !start) return;
|
|
9597
|
+
status.ttl = ttl;
|
|
9598
|
+
status.start = start;
|
|
9599
|
+
status.now = cachedNow || getNow();
|
|
9600
|
+
status.remainingTTL = ttl - (status.now - start);
|
|
9601
|
+
}
|
|
9602
|
+
};
|
|
9603
|
+
let cachedNow = 0;
|
|
9604
|
+
const getNow = () => {
|
|
9605
|
+
const n = this.#perf.now();
|
|
9606
|
+
if (this.ttlResolution > 0) {
|
|
9607
|
+
cachedNow = n;
|
|
9608
|
+
const t = setTimeout(() => cachedNow = 0, this.ttlResolution);
|
|
9609
|
+
/* c8 ignore start */
|
|
9610
|
+
if (t.unref) t.unref();
|
|
9611
|
+
}
|
|
9612
|
+
return n;
|
|
9613
|
+
};
|
|
9614
|
+
this.getRemainingTTL = (key) => {
|
|
9615
|
+
const index = this.#keyMap.get(key);
|
|
9616
|
+
if (index === void 0) return 0;
|
|
9617
|
+
const ttl = ttls[index];
|
|
9618
|
+
const start = starts[index];
|
|
9619
|
+
if (!ttl || !start) return Infinity;
|
|
9620
|
+
return ttl - ((cachedNow || getNow()) - start);
|
|
9621
|
+
};
|
|
9622
|
+
this.#isStale = (index) => {
|
|
9623
|
+
const s = starts[index];
|
|
9624
|
+
const t = ttls[index];
|
|
9625
|
+
return !!t && !!s && (cachedNow || getNow()) - s > t;
|
|
9626
|
+
};
|
|
9627
|
+
}
|
|
9628
|
+
#updateItemAge = () => {};
|
|
9629
|
+
#statusTTL = () => {};
|
|
9630
|
+
#setItemTTL = () => {};
|
|
9631
|
+
/* c8 ignore stop */
|
|
9632
|
+
#isStale = () => false;
|
|
9633
|
+
#initializeSizeTracking() {
|
|
9634
|
+
const sizes = new ZeroArray(this.#max);
|
|
9635
|
+
this.#calculatedSize = 0;
|
|
9636
|
+
this.#sizes = sizes;
|
|
9637
|
+
this.#removeItemSize = (index) => {
|
|
9638
|
+
this.#calculatedSize -= sizes[index];
|
|
9639
|
+
sizes[index] = 0;
|
|
9640
|
+
};
|
|
9641
|
+
this.#requireSize = (k, v, size, sizeCalculation) => {
|
|
9642
|
+
if (this.#isBackgroundFetch(v)) return 0;
|
|
9643
|
+
if (!isPosInt(size)) if (sizeCalculation) {
|
|
9644
|
+
if (typeof sizeCalculation !== "function") throw new TypeError("sizeCalculation must be a function");
|
|
9645
|
+
size = sizeCalculation(v, k);
|
|
9646
|
+
if (!isPosInt(size)) throw new TypeError("sizeCalculation return invalid (expect positive integer)");
|
|
9647
|
+
} else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");
|
|
9648
|
+
return size;
|
|
9649
|
+
};
|
|
9650
|
+
this.#addItemSize = (index, size, status) => {
|
|
9651
|
+
sizes[index] = size;
|
|
9652
|
+
if (this.#maxSize) {
|
|
9653
|
+
const maxSize = this.#maxSize - sizes[index];
|
|
9654
|
+
while (this.#calculatedSize > maxSize) this.#evict(true);
|
|
9655
|
+
}
|
|
9656
|
+
this.#calculatedSize += sizes[index];
|
|
9657
|
+
if (status) {
|
|
9658
|
+
status.entrySize = size;
|
|
9659
|
+
status.totalCalculatedSize = this.#calculatedSize;
|
|
9660
|
+
}
|
|
9661
|
+
};
|
|
9662
|
+
}
|
|
9663
|
+
#removeItemSize = (_i) => {};
|
|
9664
|
+
#addItemSize = (_i, _s, _st) => {};
|
|
9665
|
+
#requireSize = (_k, _v, size, sizeCalculation) => {
|
|
9666
|
+
if (size || sizeCalculation) throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
|
|
9667
|
+
return 0;
|
|
9668
|
+
};
|
|
9669
|
+
*#indexes({ allowStale = this.allowStale } = {}) {
|
|
9670
|
+
if (this.#size) for (let i = this.#tail;;) {
|
|
9671
|
+
if (!this.#isValidIndex(i)) break;
|
|
9672
|
+
if (allowStale || !this.#isStale(i)) yield i;
|
|
9673
|
+
if (i === this.#head) break;
|
|
9674
|
+
else i = this.#prev[i];
|
|
9675
|
+
}
|
|
9676
|
+
}
|
|
9677
|
+
*#rindexes({ allowStale = this.allowStale } = {}) {
|
|
9678
|
+
if (this.#size) for (let i = this.#head;;) {
|
|
9679
|
+
if (!this.#isValidIndex(i)) break;
|
|
9680
|
+
if (allowStale || !this.#isStale(i)) yield i;
|
|
9681
|
+
if (i === this.#tail) break;
|
|
9682
|
+
else i = this.#next[i];
|
|
9683
|
+
}
|
|
9684
|
+
}
|
|
9685
|
+
#isValidIndex(index) {
|
|
9686
|
+
return index !== void 0 && this.#keyMap.get(this.#keyList[index]) === index;
|
|
9687
|
+
}
|
|
9688
|
+
/**
|
|
9689
|
+
* Return a generator yielding `[key, value]` pairs,
|
|
9690
|
+
* in order from most recently used to least recently used.
|
|
9691
|
+
*/
|
|
9692
|
+
*entries() {
|
|
9693
|
+
for (const i of this.#indexes()) if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield [this.#keyList[i], this.#valList[i]];
|
|
9694
|
+
}
|
|
9695
|
+
/**
|
|
9696
|
+
* Inverse order version of {@link LRUCache.entries}
|
|
9697
|
+
*
|
|
9698
|
+
* Return a generator yielding `[key, value]` pairs,
|
|
9699
|
+
* in order from least recently used to most recently used.
|
|
9700
|
+
*/
|
|
9701
|
+
*rentries() {
|
|
9702
|
+
for (const i of this.#rindexes()) if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield [this.#keyList[i], this.#valList[i]];
|
|
9703
|
+
}
|
|
9704
|
+
/**
|
|
9705
|
+
* Return a generator yielding the keys in the cache,
|
|
9706
|
+
* in order from most recently used to least recently used.
|
|
9707
|
+
*/
|
|
9708
|
+
*keys() {
|
|
9709
|
+
for (const i of this.#indexes()) {
|
|
9710
|
+
const k = this.#keyList[i];
|
|
9711
|
+
if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield k;
|
|
9712
|
+
}
|
|
9713
|
+
}
|
|
9714
|
+
/**
|
|
9715
|
+
* Inverse order version of {@link LRUCache.keys}
|
|
9716
|
+
*
|
|
9717
|
+
* Return a generator yielding the keys in the cache,
|
|
9718
|
+
* in order from least recently used to most recently used.
|
|
9719
|
+
*/
|
|
9720
|
+
*rkeys() {
|
|
9721
|
+
for (const i of this.#rindexes()) {
|
|
9722
|
+
const k = this.#keyList[i];
|
|
9723
|
+
if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield k;
|
|
9724
|
+
}
|
|
9725
|
+
}
|
|
9726
|
+
/**
|
|
9727
|
+
* Return a generator yielding the values in the cache,
|
|
9728
|
+
* in order from most recently used to least recently used.
|
|
9729
|
+
*/
|
|
9730
|
+
*values() {
|
|
9731
|
+
for (const i of this.#indexes()) if (this.#valList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield this.#valList[i];
|
|
9732
|
+
}
|
|
9733
|
+
/**
|
|
9734
|
+
* Inverse order version of {@link LRUCache.values}
|
|
9735
|
+
*
|
|
9736
|
+
* Return a generator yielding the values in the cache,
|
|
9737
|
+
* in order from least recently used to most recently used.
|
|
9738
|
+
*/
|
|
9739
|
+
*rvalues() {
|
|
9740
|
+
for (const i of this.#rindexes()) if (this.#valList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield this.#valList[i];
|
|
9741
|
+
}
|
|
9742
|
+
/**
|
|
9743
|
+
* Iterating over the cache itself yields the same results as
|
|
9744
|
+
* {@link LRUCache.entries}
|
|
9745
|
+
*/
|
|
9746
|
+
[Symbol.iterator]() {
|
|
9747
|
+
return this.entries();
|
|
9748
|
+
}
|
|
9749
|
+
/**
|
|
9750
|
+
* A String value that is used in the creation of the default string
|
|
9751
|
+
* description of an object. Called by the built-in method
|
|
9752
|
+
* `Object.prototype.toString`.
|
|
9753
|
+
*/
|
|
9754
|
+
[Symbol.toStringTag] = "LRUCache";
|
|
9755
|
+
/**
|
|
9756
|
+
* Find a value for which the supplied fn method returns a truthy value,
|
|
9757
|
+
* similar to `Array.find()`. fn is called as `fn(value, key, cache)`.
|
|
9758
|
+
*/
|
|
9759
|
+
find(fn, getOptions = {}) {
|
|
9760
|
+
for (const i of this.#indexes()) {
|
|
9761
|
+
const v = this.#valList[i];
|
|
9762
|
+
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
9763
|
+
if (value === void 0) continue;
|
|
9764
|
+
if (fn(value, this.#keyList[i], this)) return this.get(this.#keyList[i], getOptions);
|
|
9765
|
+
}
|
|
9766
|
+
}
|
|
9767
|
+
/**
|
|
9768
|
+
* Call the supplied function on each item in the cache, in order from most
|
|
9769
|
+
* recently used to least recently used.
|
|
9770
|
+
*
|
|
9771
|
+
* `fn` is called as `fn(value, key, cache)`.
|
|
9772
|
+
*
|
|
9773
|
+
* If `thisp` is provided, function will be called in the `this`-context of
|
|
9774
|
+
* the provided object, or the cache if no `thisp` object is provided.
|
|
9775
|
+
*
|
|
9776
|
+
* Does not update age or recenty of use, or iterate over stale values.
|
|
9777
|
+
*/
|
|
9778
|
+
forEach(fn, thisp = this) {
|
|
9779
|
+
for (const i of this.#indexes()) {
|
|
9780
|
+
const v = this.#valList[i];
|
|
9781
|
+
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
9782
|
+
if (value === void 0) continue;
|
|
9783
|
+
fn.call(thisp, value, this.#keyList[i], this);
|
|
9784
|
+
}
|
|
9785
|
+
}
|
|
9786
|
+
/**
|
|
9787
|
+
* The same as {@link LRUCache.forEach} but items are iterated over in
|
|
9788
|
+
* reverse order. (ie, less recently used items are iterated over first.)
|
|
9789
|
+
*/
|
|
9790
|
+
rforEach(fn, thisp = this) {
|
|
9791
|
+
for (const i of this.#rindexes()) {
|
|
9792
|
+
const v = this.#valList[i];
|
|
9793
|
+
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
9794
|
+
if (value === void 0) continue;
|
|
9795
|
+
fn.call(thisp, value, this.#keyList[i], this);
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9798
|
+
/**
|
|
9799
|
+
* Delete any stale entries. Returns true if anything was removed,
|
|
9800
|
+
* false otherwise.
|
|
9801
|
+
*/
|
|
9802
|
+
purgeStale() {
|
|
9803
|
+
let deleted = false;
|
|
9804
|
+
for (const i of this.#rindexes({ allowStale: true })) if (this.#isStale(i)) {
|
|
9805
|
+
this.#delete(this.#keyList[i], "expire");
|
|
9806
|
+
deleted = true;
|
|
9807
|
+
}
|
|
9808
|
+
return deleted;
|
|
9809
|
+
}
|
|
9810
|
+
/**
|
|
9811
|
+
* Get the extended info about a given entry, to get its value, size, and
|
|
9812
|
+
* TTL info simultaneously. Returns `undefined` if the key is not present.
|
|
9813
|
+
*
|
|
9814
|
+
* Unlike {@link LRUCache#dump}, which is designed to be portable and survive
|
|
9815
|
+
* serialization, the `start` value is always the current timestamp, and the
|
|
9816
|
+
* `ttl` is a calculated remaining time to live (negative if expired).
|
|
9817
|
+
*
|
|
9818
|
+
* Always returns stale values, if their info is found in the cache, so be
|
|
9819
|
+
* sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})
|
|
9820
|
+
* if relevant.
|
|
9821
|
+
*/
|
|
9822
|
+
info(key) {
|
|
9823
|
+
const i = this.#keyMap.get(key);
|
|
9824
|
+
if (i === void 0) return void 0;
|
|
9825
|
+
const v = this.#valList[i];
|
|
9826
|
+
/* c8 ignore start - this isn't tested for the info function,
|
|
9827
|
+
* but it's the same logic as found in other places. */
|
|
9828
|
+
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
9829
|
+
if (value === void 0) return void 0;
|
|
9830
|
+
/* c8 ignore end */
|
|
9831
|
+
const entry = { value };
|
|
9832
|
+
if (this.#ttls && this.#starts) {
|
|
9833
|
+
const ttl = this.#ttls[i];
|
|
9834
|
+
const start = this.#starts[i];
|
|
9835
|
+
if (ttl && start) {
|
|
9836
|
+
entry.ttl = ttl - (this.#perf.now() - start);
|
|
9837
|
+
entry.start = Date.now();
|
|
9838
|
+
}
|
|
9839
|
+
}
|
|
9840
|
+
if (this.#sizes) entry.size = this.#sizes[i];
|
|
9841
|
+
return entry;
|
|
9842
|
+
}
|
|
9843
|
+
/**
|
|
9844
|
+
* Return an array of [key, {@link LRUCache.Entry}] tuples which can be
|
|
9845
|
+
* passed to {@link LRUCache#load}.
|
|
9846
|
+
*
|
|
9847
|
+
* The `start` fields are calculated relative to a portable `Date.now()`
|
|
9848
|
+
* timestamp, even if `performance.now()` is available.
|
|
9849
|
+
*
|
|
9850
|
+
* Stale entries are always included in the `dump`, even if
|
|
9851
|
+
* {@link LRUCache.OptionsBase.allowStale} is false.
|
|
9852
|
+
*
|
|
9853
|
+
* Note: this returns an actual array, not a generator, so it can be more
|
|
9854
|
+
* easily passed around.
|
|
9855
|
+
*/
|
|
9856
|
+
dump() {
|
|
9857
|
+
const arr = [];
|
|
9858
|
+
for (const i of this.#indexes({ allowStale: true })) {
|
|
9859
|
+
const key = this.#keyList[i];
|
|
9860
|
+
const v = this.#valList[i];
|
|
9861
|
+
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
9862
|
+
if (value === void 0 || key === void 0) continue;
|
|
9863
|
+
const entry = { value };
|
|
9864
|
+
if (this.#ttls && this.#starts) {
|
|
9865
|
+
entry.ttl = this.#ttls[i];
|
|
9866
|
+
const age = this.#perf.now() - this.#starts[i];
|
|
9867
|
+
entry.start = Math.floor(Date.now() - age);
|
|
9868
|
+
}
|
|
9869
|
+
if (this.#sizes) entry.size = this.#sizes[i];
|
|
9870
|
+
arr.unshift([key, entry]);
|
|
9871
|
+
}
|
|
9872
|
+
return arr;
|
|
9873
|
+
}
|
|
9874
|
+
/**
|
|
9875
|
+
* Reset the cache and load in the items in entries in the order listed.
|
|
9876
|
+
*
|
|
9877
|
+
* The shape of the resulting cache may be different if the same options are
|
|
9878
|
+
* not used in both caches.
|
|
9879
|
+
*
|
|
9880
|
+
* The `start` fields are assumed to be calculated relative to a portable
|
|
9881
|
+
* `Date.now()` timestamp, even if `performance.now()` is available.
|
|
9882
|
+
*/
|
|
9883
|
+
load(arr) {
|
|
9884
|
+
this.clear();
|
|
9885
|
+
for (const [key, entry] of arr) {
|
|
9886
|
+
if (entry.start) {
|
|
9887
|
+
const age = Date.now() - entry.start;
|
|
9888
|
+
entry.start = this.#perf.now() - age;
|
|
9889
|
+
}
|
|
9890
|
+
this.set(key, entry.value, entry);
|
|
9891
|
+
}
|
|
9892
|
+
}
|
|
9893
|
+
/**
|
|
9894
|
+
* Add a value to the cache.
|
|
9895
|
+
*
|
|
9896
|
+
* Note: if `undefined` is specified as a value, this is an alias for
|
|
9897
|
+
* {@link LRUCache#delete}
|
|
9898
|
+
*
|
|
9899
|
+
* Fields on the {@link LRUCache.SetOptions} options param will override
|
|
9900
|
+
* their corresponding values in the constructor options for the scope
|
|
9901
|
+
* of this single `set()` operation.
|
|
9902
|
+
*
|
|
9903
|
+
* If `start` is provided, then that will set the effective start
|
|
9904
|
+
* time for the TTL calculation. Note that this must be a previous
|
|
9905
|
+
* value of `performance.now()` if supported, or a previous value of
|
|
9906
|
+
* `Date.now()` if not.
|
|
9907
|
+
*
|
|
9908
|
+
* Options object may also include `size`, which will prevent
|
|
9909
|
+
* calling the `sizeCalculation` function and just use the specified
|
|
9910
|
+
* number if it is a positive integer, and `noDisposeOnSet` which
|
|
9911
|
+
* will prevent calling a `dispose` function in the case of
|
|
9912
|
+
* overwrites.
|
|
9913
|
+
*
|
|
9914
|
+
* If the `size` (or return value of `sizeCalculation`) for a given
|
|
9915
|
+
* entry is greater than `maxEntrySize`, then the item will not be
|
|
9916
|
+
* added to the cache.
|
|
9917
|
+
*
|
|
9918
|
+
* Will update the recency of the entry.
|
|
9919
|
+
*
|
|
9920
|
+
* If the value is `undefined`, then this is an alias for
|
|
9921
|
+
* `cache.delete(key)`. `undefined` is never stored in the cache.
|
|
9922
|
+
*/
|
|
9923
|
+
set(k, v, setOptions = {}) {
|
|
9924
|
+
if (v === void 0) {
|
|
9925
|
+
this.delete(k);
|
|
9926
|
+
return this;
|
|
9927
|
+
}
|
|
9928
|
+
const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status } = setOptions;
|
|
9929
|
+
let { noUpdateTTL = this.noUpdateTTL } = setOptions;
|
|
9930
|
+
const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation);
|
|
9931
|
+
if (this.maxEntrySize && size > this.maxEntrySize) {
|
|
9932
|
+
if (status) {
|
|
9933
|
+
status.set = "miss";
|
|
9934
|
+
status.maxEntrySizeExceeded = true;
|
|
9935
|
+
}
|
|
9936
|
+
this.#delete(k, "set");
|
|
9937
|
+
return this;
|
|
9938
|
+
}
|
|
9939
|
+
let index = this.#size === 0 ? void 0 : this.#keyMap.get(k);
|
|
9940
|
+
if (index === void 0) {
|
|
9941
|
+
index = this.#size === 0 ? this.#tail : this.#free.length !== 0 ? this.#free.pop() : this.#size === this.#max ? this.#evict(false) : this.#size;
|
|
9942
|
+
this.#keyList[index] = k;
|
|
9943
|
+
this.#valList[index] = v;
|
|
9944
|
+
this.#keyMap.set(k, index);
|
|
9945
|
+
this.#next[this.#tail] = index;
|
|
9946
|
+
this.#prev[index] = this.#tail;
|
|
9947
|
+
this.#tail = index;
|
|
9948
|
+
this.#size++;
|
|
9949
|
+
this.#addItemSize(index, size, status);
|
|
9950
|
+
if (status) status.set = "add";
|
|
9951
|
+
noUpdateTTL = false;
|
|
9952
|
+
if (this.#hasOnInsert) this.#onInsert?.(v, k, "add");
|
|
9953
|
+
} else {
|
|
9954
|
+
this.#moveToTail(index);
|
|
9955
|
+
const oldVal = this.#valList[index];
|
|
9956
|
+
if (v !== oldVal) {
|
|
9957
|
+
if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {
|
|
9958
|
+
oldVal.__abortController.abort(/* @__PURE__ */ new Error("replaced"));
|
|
9959
|
+
const { __staleWhileFetching: s } = oldVal;
|
|
9960
|
+
if (s !== void 0 && !noDisposeOnSet) {
|
|
9961
|
+
if (this.#hasDispose) this.#dispose?.(s, k, "set");
|
|
9962
|
+
if (this.#hasDisposeAfter) this.#disposed?.push([
|
|
9963
|
+
s,
|
|
9964
|
+
k,
|
|
9965
|
+
"set"
|
|
9966
|
+
]);
|
|
9967
|
+
}
|
|
9968
|
+
} else if (!noDisposeOnSet) {
|
|
9969
|
+
if (this.#hasDispose) this.#dispose?.(oldVal, k, "set");
|
|
9970
|
+
if (this.#hasDisposeAfter) this.#disposed?.push([
|
|
9971
|
+
oldVal,
|
|
9972
|
+
k,
|
|
9973
|
+
"set"
|
|
9974
|
+
]);
|
|
9975
|
+
}
|
|
9976
|
+
this.#removeItemSize(index);
|
|
9977
|
+
this.#addItemSize(index, size, status);
|
|
9978
|
+
this.#valList[index] = v;
|
|
9979
|
+
if (status) {
|
|
9980
|
+
status.set = "replace";
|
|
9981
|
+
const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? oldVal.__staleWhileFetching : oldVal;
|
|
9982
|
+
if (oldValue !== void 0) status.oldValue = oldValue;
|
|
9983
|
+
}
|
|
9984
|
+
} else if (status) status.set = "update";
|
|
9985
|
+
if (this.#hasOnInsert) this.onInsert?.(v, k, v === oldVal ? "update" : "replace");
|
|
9986
|
+
}
|
|
9987
|
+
if (ttl !== 0 && !this.#ttls) this.#initializeTTLTracking();
|
|
9988
|
+
if (this.#ttls) {
|
|
9989
|
+
if (!noUpdateTTL) this.#setItemTTL(index, ttl, start);
|
|
9990
|
+
if (status) this.#statusTTL(status, index);
|
|
9991
|
+
}
|
|
9992
|
+
if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {
|
|
9993
|
+
const dt = this.#disposed;
|
|
9994
|
+
let task;
|
|
9995
|
+
while (task = dt?.shift()) this.#disposeAfter?.(...task);
|
|
9996
|
+
}
|
|
9997
|
+
return this;
|
|
9998
|
+
}
|
|
9999
|
+
/**
|
|
10000
|
+
* Evict the least recently used item, returning its value or
|
|
10001
|
+
* `undefined` if cache is empty.
|
|
10002
|
+
*/
|
|
10003
|
+
pop() {
|
|
10004
|
+
try {
|
|
10005
|
+
while (this.#size) {
|
|
10006
|
+
const val = this.#valList[this.#head];
|
|
10007
|
+
this.#evict(true);
|
|
10008
|
+
if (this.#isBackgroundFetch(val)) {
|
|
10009
|
+
if (val.__staleWhileFetching) return val.__staleWhileFetching;
|
|
10010
|
+
} else if (val !== void 0) return val;
|
|
10011
|
+
}
|
|
10012
|
+
} finally {
|
|
10013
|
+
if (this.#hasDisposeAfter && this.#disposed) {
|
|
10014
|
+
const dt = this.#disposed;
|
|
10015
|
+
let task;
|
|
10016
|
+
while (task = dt?.shift()) this.#disposeAfter?.(...task);
|
|
10017
|
+
}
|
|
10018
|
+
}
|
|
10019
|
+
}
|
|
10020
|
+
#evict(free) {
|
|
10021
|
+
const head = this.#head;
|
|
10022
|
+
const k = this.#keyList[head];
|
|
10023
|
+
const v = this.#valList[head];
|
|
10024
|
+
if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("evicted"));
|
|
10025
|
+
else if (this.#hasDispose || this.#hasDisposeAfter) {
|
|
10026
|
+
if (this.#hasDispose) this.#dispose?.(v, k, "evict");
|
|
10027
|
+
if (this.#hasDisposeAfter) this.#disposed?.push([
|
|
10028
|
+
v,
|
|
10029
|
+
k,
|
|
10030
|
+
"evict"
|
|
10031
|
+
]);
|
|
10032
|
+
}
|
|
10033
|
+
this.#removeItemSize(head);
|
|
10034
|
+
if (this.#autopurgeTimers?.[head]) {
|
|
10035
|
+
clearTimeout(this.#autopurgeTimers[head]);
|
|
10036
|
+
this.#autopurgeTimers[head] = void 0;
|
|
10037
|
+
}
|
|
10038
|
+
if (free) {
|
|
10039
|
+
this.#keyList[head] = void 0;
|
|
10040
|
+
this.#valList[head] = void 0;
|
|
10041
|
+
this.#free.push(head);
|
|
10042
|
+
}
|
|
10043
|
+
if (this.#size === 1) {
|
|
10044
|
+
this.#head = this.#tail = 0;
|
|
10045
|
+
this.#free.length = 0;
|
|
10046
|
+
} else this.#head = this.#next[head];
|
|
10047
|
+
this.#keyMap.delete(k);
|
|
10048
|
+
this.#size--;
|
|
10049
|
+
return head;
|
|
10050
|
+
}
|
|
10051
|
+
/**
|
|
10052
|
+
* Check if a key is in the cache, without updating the recency of use.
|
|
10053
|
+
* Will return false if the item is stale, even though it is technically
|
|
10054
|
+
* in the cache.
|
|
10055
|
+
*
|
|
10056
|
+
* Check if a key is in the cache, without updating the recency of
|
|
10057
|
+
* use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set
|
|
10058
|
+
* to `true` in either the options or the constructor.
|
|
10059
|
+
*
|
|
10060
|
+
* Will return `false` if the item is stale, even though it is technically in
|
|
10061
|
+
* the cache. The difference can be determined (if it matters) by using a
|
|
10062
|
+
* `status` argument, and inspecting the `has` field.
|
|
10063
|
+
*
|
|
10064
|
+
* Will not update item age unless
|
|
10065
|
+
* {@link LRUCache.OptionsBase.updateAgeOnHas} is set.
|
|
10066
|
+
*/
|
|
10067
|
+
has(k, hasOptions = {}) {
|
|
10068
|
+
const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions;
|
|
10069
|
+
const index = this.#keyMap.get(k);
|
|
10070
|
+
if (index !== void 0) {
|
|
10071
|
+
const v = this.#valList[index];
|
|
10072
|
+
if (this.#isBackgroundFetch(v) && v.__staleWhileFetching === void 0) return false;
|
|
10073
|
+
if (!this.#isStale(index)) {
|
|
10074
|
+
if (updateAgeOnHas) this.#updateItemAge(index);
|
|
10075
|
+
if (status) {
|
|
10076
|
+
status.has = "hit";
|
|
10077
|
+
this.#statusTTL(status, index);
|
|
10078
|
+
}
|
|
10079
|
+
return true;
|
|
10080
|
+
} else if (status) {
|
|
10081
|
+
status.has = "stale";
|
|
10082
|
+
this.#statusTTL(status, index);
|
|
10083
|
+
}
|
|
10084
|
+
} else if (status) status.has = "miss";
|
|
10085
|
+
return false;
|
|
10086
|
+
}
|
|
10087
|
+
/**
|
|
10088
|
+
* Like {@link LRUCache#get} but doesn't update recency or delete stale
|
|
10089
|
+
* items.
|
|
10090
|
+
*
|
|
10091
|
+
* Returns `undefined` if the item is stale, unless
|
|
10092
|
+
* {@link LRUCache.OptionsBase.allowStale} is set.
|
|
10093
|
+
*/
|
|
10094
|
+
peek(k, peekOptions = {}) {
|
|
10095
|
+
const { allowStale = this.allowStale } = peekOptions;
|
|
10096
|
+
const index = this.#keyMap.get(k);
|
|
10097
|
+
if (index === void 0 || !allowStale && this.#isStale(index)) return;
|
|
10098
|
+
const v = this.#valList[index];
|
|
10099
|
+
return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
10100
|
+
}
|
|
10101
|
+
#backgroundFetch(k, index, options, context) {
|
|
10102
|
+
const v = index === void 0 ? void 0 : this.#valList[index];
|
|
10103
|
+
if (this.#isBackgroundFetch(v)) return v;
|
|
10104
|
+
const ac = new AC();
|
|
10105
|
+
const { signal } = options;
|
|
10106
|
+
signal?.addEventListener("abort", () => ac.abort(signal.reason), { signal: ac.signal });
|
|
10107
|
+
const fetchOpts = {
|
|
10108
|
+
signal: ac.signal,
|
|
10109
|
+
options,
|
|
10110
|
+
context
|
|
10111
|
+
};
|
|
10112
|
+
const cb = (v, updateCache = false) => {
|
|
10113
|
+
const { aborted } = ac.signal;
|
|
10114
|
+
const ignoreAbort = options.ignoreFetchAbort && v !== void 0;
|
|
10115
|
+
if (options.status) if (aborted && !updateCache) {
|
|
10116
|
+
options.status.fetchAborted = true;
|
|
10117
|
+
options.status.fetchError = ac.signal.reason;
|
|
10118
|
+
if (ignoreAbort) options.status.fetchAbortIgnored = true;
|
|
10119
|
+
} else options.status.fetchResolved = true;
|
|
10120
|
+
if (aborted && !ignoreAbort && !updateCache) return fetchFail(ac.signal.reason);
|
|
10121
|
+
const bf = p;
|
|
10122
|
+
const vl = this.#valList[index];
|
|
10123
|
+
if (vl === p || ignoreAbort && updateCache && vl === void 0) if (v === void 0) if (bf.__staleWhileFetching !== void 0) this.#valList[index] = bf.__staleWhileFetching;
|
|
10124
|
+
else this.#delete(k, "fetch");
|
|
10125
|
+
else {
|
|
10126
|
+
if (options.status) options.status.fetchUpdated = true;
|
|
10127
|
+
this.set(k, v, fetchOpts.options);
|
|
10128
|
+
}
|
|
10129
|
+
return v;
|
|
10130
|
+
};
|
|
10131
|
+
const eb = (er) => {
|
|
10132
|
+
if (options.status) {
|
|
10133
|
+
options.status.fetchRejected = true;
|
|
10134
|
+
options.status.fetchError = er;
|
|
10135
|
+
}
|
|
10136
|
+
return fetchFail(er);
|
|
10137
|
+
};
|
|
10138
|
+
const fetchFail = (er) => {
|
|
10139
|
+
const { aborted } = ac.signal;
|
|
10140
|
+
const allowStaleAborted = aborted && options.allowStaleOnFetchAbort;
|
|
10141
|
+
const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection;
|
|
10142
|
+
const noDelete = allowStale || options.noDeleteOnFetchRejection;
|
|
10143
|
+
const bf = p;
|
|
10144
|
+
if (this.#valList[index] === p) {
|
|
10145
|
+
if (!noDelete || bf.__staleWhileFetching === void 0) this.#delete(k, "fetch");
|
|
10146
|
+
else if (!allowStaleAborted) this.#valList[index] = bf.__staleWhileFetching;
|
|
10147
|
+
}
|
|
10148
|
+
if (allowStale) {
|
|
10149
|
+
if (options.status && bf.__staleWhileFetching !== void 0) options.status.returnedStale = true;
|
|
10150
|
+
return bf.__staleWhileFetching;
|
|
10151
|
+
} else if (bf.__returned === bf) throw er;
|
|
10152
|
+
};
|
|
10153
|
+
const pcall = (res, rej) => {
|
|
10154
|
+
const fmp = this.#fetchMethod?.(k, v, fetchOpts);
|
|
10155
|
+
if (fmp && fmp instanceof Promise) fmp.then((v) => res(v === void 0 ? void 0 : v), rej);
|
|
10156
|
+
ac.signal.addEventListener("abort", () => {
|
|
10157
|
+
if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) {
|
|
10158
|
+
res(void 0);
|
|
10159
|
+
if (options.allowStaleOnFetchAbort) res = (v) => cb(v, true);
|
|
10160
|
+
}
|
|
10161
|
+
});
|
|
10162
|
+
};
|
|
10163
|
+
if (options.status) options.status.fetchDispatched = true;
|
|
10164
|
+
const p = new Promise(pcall).then(cb, eb);
|
|
10165
|
+
const bf = Object.assign(p, {
|
|
10166
|
+
__abortController: ac,
|
|
10167
|
+
__staleWhileFetching: v,
|
|
10168
|
+
__returned: void 0
|
|
10169
|
+
});
|
|
10170
|
+
if (index === void 0) {
|
|
10171
|
+
this.set(k, bf, {
|
|
10172
|
+
...fetchOpts.options,
|
|
10173
|
+
status: void 0
|
|
10174
|
+
});
|
|
10175
|
+
index = this.#keyMap.get(k);
|
|
10176
|
+
} else this.#valList[index] = bf;
|
|
10177
|
+
return bf;
|
|
10178
|
+
}
|
|
10179
|
+
#isBackgroundFetch(p) {
|
|
10180
|
+
if (!this.#hasFetchMethod) return false;
|
|
10181
|
+
const b = p;
|
|
10182
|
+
return !!b && b instanceof Promise && b.hasOwnProperty("__staleWhileFetching") && b.__abortController instanceof AC;
|
|
10183
|
+
}
|
|
10184
|
+
async fetch(k, fetchOptions = {}) {
|
|
10185
|
+
const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL, noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal } = fetchOptions;
|
|
10186
|
+
if (!this.#hasFetchMethod) {
|
|
10187
|
+
if (status) status.fetch = "get";
|
|
10188
|
+
return this.get(k, {
|
|
10189
|
+
allowStale,
|
|
10190
|
+
updateAgeOnGet,
|
|
10191
|
+
noDeleteOnStaleGet,
|
|
10192
|
+
status
|
|
10193
|
+
});
|
|
10194
|
+
}
|
|
10195
|
+
const options = {
|
|
10196
|
+
allowStale,
|
|
10197
|
+
updateAgeOnGet,
|
|
10198
|
+
noDeleteOnStaleGet,
|
|
10199
|
+
ttl,
|
|
10200
|
+
noDisposeOnSet,
|
|
10201
|
+
size,
|
|
10202
|
+
sizeCalculation,
|
|
10203
|
+
noUpdateTTL,
|
|
10204
|
+
noDeleteOnFetchRejection,
|
|
10205
|
+
allowStaleOnFetchRejection,
|
|
10206
|
+
allowStaleOnFetchAbort,
|
|
10207
|
+
ignoreFetchAbort,
|
|
10208
|
+
status,
|
|
10209
|
+
signal
|
|
10210
|
+
};
|
|
10211
|
+
let index = this.#keyMap.get(k);
|
|
10212
|
+
if (index === void 0) {
|
|
10213
|
+
if (status) status.fetch = "miss";
|
|
10214
|
+
const p = this.#backgroundFetch(k, index, options, context);
|
|
10215
|
+
return p.__returned = p;
|
|
10216
|
+
} else {
|
|
10217
|
+
const v = this.#valList[index];
|
|
10218
|
+
if (this.#isBackgroundFetch(v)) {
|
|
10219
|
+
const stale = allowStale && v.__staleWhileFetching !== void 0;
|
|
10220
|
+
if (status) {
|
|
10221
|
+
status.fetch = "inflight";
|
|
10222
|
+
if (stale) status.returnedStale = true;
|
|
10223
|
+
}
|
|
10224
|
+
return stale ? v.__staleWhileFetching : v.__returned = v;
|
|
10225
|
+
}
|
|
10226
|
+
const isStale = this.#isStale(index);
|
|
10227
|
+
if (!forceRefresh && !isStale) {
|
|
10228
|
+
if (status) status.fetch = "hit";
|
|
10229
|
+
this.#moveToTail(index);
|
|
10230
|
+
if (updateAgeOnGet) this.#updateItemAge(index);
|
|
10231
|
+
if (status) this.#statusTTL(status, index);
|
|
10232
|
+
return v;
|
|
10233
|
+
}
|
|
10234
|
+
const p = this.#backgroundFetch(k, index, options, context);
|
|
10235
|
+
const staleVal = p.__staleWhileFetching !== void 0 && allowStale;
|
|
10236
|
+
if (status) {
|
|
10237
|
+
status.fetch = isStale ? "stale" : "refresh";
|
|
10238
|
+
if (staleVal && isStale) status.returnedStale = true;
|
|
10239
|
+
}
|
|
10240
|
+
return staleVal ? p.__staleWhileFetching : p.__returned = p;
|
|
10241
|
+
}
|
|
10242
|
+
}
|
|
10243
|
+
async forceFetch(k, fetchOptions = {}) {
|
|
10244
|
+
const v = await this.fetch(k, fetchOptions);
|
|
10245
|
+
if (v === void 0) throw new Error("fetch() returned undefined");
|
|
10246
|
+
return v;
|
|
10247
|
+
}
|
|
10248
|
+
memo(k, memoOptions = {}) {
|
|
10249
|
+
const memoMethod = this.#memoMethod;
|
|
10250
|
+
if (!memoMethod) throw new Error("no memoMethod provided to constructor");
|
|
10251
|
+
const { context, forceRefresh, ...options } = memoOptions;
|
|
10252
|
+
const v = this.get(k, options);
|
|
10253
|
+
if (!forceRefresh && v !== void 0) return v;
|
|
10254
|
+
const vv = memoMethod(k, v, {
|
|
10255
|
+
options,
|
|
10256
|
+
context
|
|
10257
|
+
});
|
|
10258
|
+
this.set(k, vv, options);
|
|
10259
|
+
return vv;
|
|
10260
|
+
}
|
|
10261
|
+
/**
|
|
10262
|
+
* Return a value from the cache. Will update the recency of the cache
|
|
10263
|
+
* entry found.
|
|
10264
|
+
*
|
|
10265
|
+
* If the key is not found, get() will return `undefined`.
|
|
10266
|
+
*/
|
|
10267
|
+
get(k, getOptions = {}) {
|
|
10268
|
+
const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status } = getOptions;
|
|
10269
|
+
const index = this.#keyMap.get(k);
|
|
10270
|
+
if (index !== void 0) {
|
|
10271
|
+
const value = this.#valList[index];
|
|
10272
|
+
const fetching = this.#isBackgroundFetch(value);
|
|
10273
|
+
if (status) this.#statusTTL(status, index);
|
|
10274
|
+
if (this.#isStale(index)) {
|
|
10275
|
+
if (status) status.get = "stale";
|
|
10276
|
+
if (!fetching) {
|
|
10277
|
+
if (!noDeleteOnStaleGet) this.#delete(k, "expire");
|
|
10278
|
+
if (status && allowStale) status.returnedStale = true;
|
|
10279
|
+
return allowStale ? value : void 0;
|
|
10280
|
+
} else {
|
|
10281
|
+
if (status && allowStale && value.__staleWhileFetching !== void 0) status.returnedStale = true;
|
|
10282
|
+
return allowStale ? value.__staleWhileFetching : void 0;
|
|
10283
|
+
}
|
|
10284
|
+
} else {
|
|
10285
|
+
if (status) status.get = "hit";
|
|
10286
|
+
if (fetching) return value.__staleWhileFetching;
|
|
10287
|
+
this.#moveToTail(index);
|
|
10288
|
+
if (updateAgeOnGet) this.#updateItemAge(index);
|
|
10289
|
+
return value;
|
|
10290
|
+
}
|
|
10291
|
+
} else if (status) status.get = "miss";
|
|
10292
|
+
}
|
|
10293
|
+
#connect(p, n) {
|
|
10294
|
+
this.#prev[n] = p;
|
|
10295
|
+
this.#next[p] = n;
|
|
10296
|
+
}
|
|
10297
|
+
#moveToTail(index) {
|
|
10298
|
+
if (index !== this.#tail) {
|
|
10299
|
+
if (index === this.#head) this.#head = this.#next[index];
|
|
10300
|
+
else this.#connect(this.#prev[index], this.#next[index]);
|
|
10301
|
+
this.#connect(this.#tail, index);
|
|
10302
|
+
this.#tail = index;
|
|
10303
|
+
}
|
|
10304
|
+
}
|
|
10305
|
+
/**
|
|
10306
|
+
* Deletes a key out of the cache.
|
|
10307
|
+
*
|
|
10308
|
+
* Returns true if the key was deleted, false otherwise.
|
|
10309
|
+
*/
|
|
10310
|
+
delete(k) {
|
|
10311
|
+
return this.#delete(k, "delete");
|
|
10312
|
+
}
|
|
10313
|
+
#delete(k, reason) {
|
|
10314
|
+
let deleted = false;
|
|
10315
|
+
if (this.#size !== 0) {
|
|
10316
|
+
const index = this.#keyMap.get(k);
|
|
10317
|
+
if (index !== void 0) {
|
|
10318
|
+
if (this.#autopurgeTimers?.[index]) {
|
|
10319
|
+
clearTimeout(this.#autopurgeTimers?.[index]);
|
|
10320
|
+
this.#autopurgeTimers[index] = void 0;
|
|
10321
|
+
}
|
|
10322
|
+
deleted = true;
|
|
10323
|
+
if (this.#size === 1) this.#clear(reason);
|
|
10324
|
+
else {
|
|
10325
|
+
this.#removeItemSize(index);
|
|
10326
|
+
const v = this.#valList[index];
|
|
10327
|
+
if (this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
|
|
10328
|
+
else if (this.#hasDispose || this.#hasDisposeAfter) {
|
|
10329
|
+
if (this.#hasDispose) this.#dispose?.(v, k, reason);
|
|
10330
|
+
if (this.#hasDisposeAfter) this.#disposed?.push([
|
|
10331
|
+
v,
|
|
10332
|
+
k,
|
|
10333
|
+
reason
|
|
10334
|
+
]);
|
|
10335
|
+
}
|
|
10336
|
+
this.#keyMap.delete(k);
|
|
10337
|
+
this.#keyList[index] = void 0;
|
|
10338
|
+
this.#valList[index] = void 0;
|
|
10339
|
+
if (index === this.#tail) this.#tail = this.#prev[index];
|
|
10340
|
+
else if (index === this.#head) this.#head = this.#next[index];
|
|
10341
|
+
else {
|
|
10342
|
+
const pi = this.#prev[index];
|
|
10343
|
+
this.#next[pi] = this.#next[index];
|
|
10344
|
+
const ni = this.#next[index];
|
|
10345
|
+
this.#prev[ni] = this.#prev[index];
|
|
10346
|
+
}
|
|
10347
|
+
this.#size--;
|
|
10348
|
+
this.#free.push(index);
|
|
10349
|
+
}
|
|
10350
|
+
}
|
|
10351
|
+
}
|
|
10352
|
+
if (this.#hasDisposeAfter && this.#disposed?.length) {
|
|
10353
|
+
const dt = this.#disposed;
|
|
10354
|
+
let task;
|
|
10355
|
+
while (task = dt?.shift()) this.#disposeAfter?.(...task);
|
|
10356
|
+
}
|
|
10357
|
+
return deleted;
|
|
10358
|
+
}
|
|
10359
|
+
/**
|
|
10360
|
+
* Clear the cache entirely, throwing away all values.
|
|
10361
|
+
*/
|
|
10362
|
+
clear() {
|
|
10363
|
+
return this.#clear("delete");
|
|
10364
|
+
}
|
|
10365
|
+
#clear(reason) {
|
|
10366
|
+
for (const index of this.#rindexes({ allowStale: true })) {
|
|
10367
|
+
const v = this.#valList[index];
|
|
10368
|
+
if (this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
|
|
10369
|
+
else {
|
|
10370
|
+
const k = this.#keyList[index];
|
|
10371
|
+
if (this.#hasDispose) this.#dispose?.(v, k, reason);
|
|
10372
|
+
if (this.#hasDisposeAfter) this.#disposed?.push([
|
|
10373
|
+
v,
|
|
10374
|
+
k,
|
|
10375
|
+
reason
|
|
10376
|
+
]);
|
|
10377
|
+
}
|
|
10378
|
+
}
|
|
10379
|
+
this.#keyMap.clear();
|
|
10380
|
+
this.#valList.fill(void 0);
|
|
10381
|
+
this.#keyList.fill(void 0);
|
|
10382
|
+
if (this.#ttls && this.#starts) {
|
|
10383
|
+
this.#ttls.fill(0);
|
|
10384
|
+
this.#starts.fill(0);
|
|
10385
|
+
for (const t of this.#autopurgeTimers ?? []) if (t !== void 0) clearTimeout(t);
|
|
10386
|
+
this.#autopurgeTimers?.fill(void 0);
|
|
10387
|
+
}
|
|
10388
|
+
if (this.#sizes) this.#sizes.fill(0);
|
|
10389
|
+
this.#head = 0;
|
|
10390
|
+
this.#tail = 0;
|
|
10391
|
+
this.#free.length = 0;
|
|
10392
|
+
this.#calculatedSize = 0;
|
|
10393
|
+
this.#size = 0;
|
|
10394
|
+
if (this.#hasDisposeAfter && this.#disposed) {
|
|
10395
|
+
const dt = this.#disposed;
|
|
10396
|
+
let task;
|
|
10397
|
+
while (task = dt?.shift()) this.#disposeAfter?.(...task);
|
|
10398
|
+
}
|
|
10399
|
+
}
|
|
10400
|
+
};
|
|
10401
|
+
//#endregion
|
|
10402
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
|
|
10403
|
+
/**
|
|
10404
|
+
* Unified memoised factory dispatching to the right provider flavour by the
|
|
10405
|
+
* source shape:
|
|
10406
|
+
* - `TreeNodeAccessor` → {@link AccessorColumnsProvider}
|
|
10407
|
+
* (indexed by `root.handle`, walks the accessor tree once per root).
|
|
10408
|
+
* - `UpstreamBlockCtx<AccessorHandle>[]` (or omitted — pulled from the
|
|
10409
|
+
* ambient ctx) → {@link ResultPoolColumnsProvider}
|
|
10410
|
+
* (indexed by a content-hash of the block list).
|
|
10411
|
+
*
|
|
10412
|
+
* Both branches return cached instances within their LRU window, so repeated
|
|
10413
|
+
* calls with the same source skip re-walking / re-hashing.
|
|
10414
|
+
*/
|
|
10415
|
+
function ColumnsProvider(source) {
|
|
10416
|
+
if (isNil(source) || Array.isArray(source)) return ResultPoolColumnsProvider(source);
|
|
10417
|
+
else if (source instanceof TreeNodeAccessor) return AccessorColumnsProvider(source);
|
|
10418
|
+
else throw new Error("Unknown columns provider source");
|
|
10419
|
+
}
|
|
10420
|
+
/**
|
|
10421
|
+
* Memoised constructor — same `root.handle` returns the same
|
|
10422
|
+
* {@link AccessorColumnsProviderImpl}, so `indexAccessorRoot` runs once per
|
|
10423
|
+
* accessor root (within the LRU window).
|
|
10424
|
+
*/
|
|
10425
|
+
const _accessorProviderCache = new LRUCache({ max: 64 });
|
|
10426
|
+
function AccessorColumnsProvider(root) {
|
|
10427
|
+
let provider = _accessorProviderCache.get(root.handle);
|
|
10428
|
+
if (provider === void 0) {
|
|
10429
|
+
provider = new AccessorColumnsProviderImpl(root);
|
|
10430
|
+
_accessorProviderCache.set(root.handle, provider);
|
|
10431
|
+
}
|
|
10432
|
+
return provider;
|
|
10433
|
+
}
|
|
10434
|
+
/**
|
|
10435
|
+
* Memoised constructor — same `rawPool` content returns the same
|
|
10436
|
+
* {@link ResultPoolColumnsProviderImpl}, so `indexPoolBlock` runs once per
|
|
10437
|
+
* pool snapshot (within the LRU window).
|
|
10438
|
+
*/
|
|
10439
|
+
const _resultPoolProviderCache = new LRUCache({ max: 4 });
|
|
10440
|
+
function ResultPoolColumnsProvider(rawPool = getCfgRenderCtx().getUpstreamBlockCtx()) {
|
|
10441
|
+
const key = hashRawPool(rawPool);
|
|
10442
|
+
let provider = _resultPoolProviderCache.get(key);
|
|
10443
|
+
if (provider === void 0) {
|
|
10444
|
+
provider = new ResultPoolColumnsProviderImpl(rawPool);
|
|
10445
|
+
_resultPoolProviderCache.set(key, provider);
|
|
10446
|
+
}
|
|
10447
|
+
return provider;
|
|
10448
|
+
}
|
|
10449
|
+
/**
|
|
10450
|
+
* Sandbox-specific provider over a {@link TreeNodeAccessor} root. Uses the
|
|
10451
|
+
* accessor's own `resolvePath` as the canonical root path for id construction,
|
|
10452
|
+
* and adds `getColumns()` returning {@link ColumnLazy}s on top of the generic
|
|
10453
|
+
* entries index.
|
|
10454
|
+
*/
|
|
10455
|
+
var AccessorColumnsProviderImpl = class extends AccessorEntriesProvider {
|
|
10456
|
+
cachedColumns;
|
|
10457
|
+
constructor(root) {
|
|
10458
|
+
super(root, root.resolvePath);
|
|
10459
|
+
}
|
|
10460
|
+
getColumns() {
|
|
10461
|
+
if (this.cachedColumns !== void 0) return this.cachedColumns;
|
|
10462
|
+
return this.cachedColumns = Array.from(this.entries.values()).map((e) => ColumnLazyImpl.fromAccessor(e)).filter((v) => !isNil(v));
|
|
10463
|
+
}
|
|
10464
|
+
};
|
|
10465
|
+
/**
|
|
10466
|
+
* Sandbox-specific result-pool provider. Accepts the raw handle-shaped blocks
|
|
10467
|
+
* returned by {@link GlobalCfgRenderCtxMethods.getUpstreamBlockCtx} and
|
|
10468
|
+
* wraps them into {@link TreeNodeAccessor}s, then adds `getColumns()`.
|
|
10469
|
+
*/
|
|
10470
|
+
var ResultPoolColumnsProviderImpl = class extends ResultPoolEntriesProvider {
|
|
10471
|
+
cachedColumns;
|
|
10472
|
+
constructor(rawPool = getCfgRenderCtx().getUpstreamBlockCtx()) {
|
|
10473
|
+
const blocks = rawPool.map((b) => ({
|
|
10474
|
+
blockId: b.blockId,
|
|
10475
|
+
prodCtx: b.prodCtx !== void 0 ? new TreeNodeAccessor(b.prodCtx, [b.blockId, "prodCtx"]) : void 0,
|
|
10476
|
+
stagingCtx: b.stagingCtx !== void 0 ? new TreeNodeAccessor(b.stagingCtx, [b.blockId, "stagingCtx"]) : void 0,
|
|
10477
|
+
prodIncomplete: b.prodIncomplete,
|
|
10478
|
+
stagingIncomplete: b.stagingIncomplete
|
|
10479
|
+
}));
|
|
10480
|
+
super(blocks);
|
|
10481
|
+
}
|
|
10482
|
+
getColumns() {
|
|
10483
|
+
if (this.cachedColumns !== void 0) return this.cachedColumns;
|
|
10484
|
+
return this.cachedColumns = Array.from(this.getPObjectEntries().values()).map((e) => ColumnLazyImpl.fromAccessor(e)).filter((v) => !isNil(v));
|
|
10485
|
+
}
|
|
10486
|
+
};
|
|
10487
|
+
function hashRawPool(rawPool) {
|
|
10488
|
+
return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
|
|
10489
|
+
}
|
|
10490
|
+
//#endregion
|
|
10491
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
|
|
10492
|
+
/**
|
|
10493
|
+
* Build the default set of ColumnsProviders for the ambient render ctx:
|
|
10494
|
+
* - `AccessorColumnsProvider` over `outputs` (if present)
|
|
10495
|
+
* - `AccessorColumnsProvider` over `prerun` (if present)
|
|
10496
|
+
* - `ResultPoolColumnsProvider` over `rawResultPool`
|
|
10497
|
+
*
|
|
10498
|
+
* Pulls handles directly from the ambient `cfgRenderCtx`. Returns `[]` when
|
|
10499
|
+
* called outside a render context.
|
|
10500
|
+
*
|
|
10501
|
+
* Result is memoised per-ctx (WeakMap → array). Repeated calls within the
|
|
10502
|
+
* same render cycle return the same provider triplet — inner providers are
|
|
10503
|
+
* also LRU-memoised by their content keys, so even a cache miss here doesn't
|
|
10504
|
+
* re-walk the trees.
|
|
10505
|
+
*/
|
|
10506
|
+
const _ctxProvidersCache = /* @__PURE__ */ new WeakMap();
|
|
10507
|
+
function getCtxProviders(deps) {
|
|
10508
|
+
const ctx = deps?.ctx ?? getCfgRenderCtx();
|
|
10509
|
+
const cached = _ctxProvidersCache.get(ctx);
|
|
10510
|
+
if (cached !== void 0) return cached;
|
|
10511
|
+
const providers = [];
|
|
10512
|
+
const outputs = ctx.getAccessorHandleByName(MainAccessorName);
|
|
10513
|
+
if (outputs !== void 0) providers.push(ColumnsProvider(new TreeNodeAccessor(outputs, [MainAccessorName])));
|
|
10514
|
+
const prerun = ctx.getAccessorHandleByName(StagingAccessorName);
|
|
10515
|
+
if (prerun !== void 0) providers.push(ColumnsProvider(new TreeNodeAccessor(prerun, [StagingAccessorName])));
|
|
10516
|
+
providers.push(ColumnsProvider(ctx.getUpstreamBlockCtx()));
|
|
10517
|
+
_ctxProvidersCache.set(ctx, providers);
|
|
10518
|
+
return providers;
|
|
10519
|
+
}
|
|
10520
|
+
function isColumnProvider(source) {
|
|
10521
|
+
if (typeof source !== "object" || source === null) return false;
|
|
10522
|
+
const p = source;
|
|
10523
|
+
return typeof p.getColumns === "function" && typeof p.isFinal === "function";
|
|
10524
|
+
}
|
|
10525
|
+
//#endregion
|
|
10526
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_lazy.js
|
|
10527
|
+
/**
|
|
10528
|
+
* Thrown by leaf-recipe factories when the requested column is provably
|
|
10529
|
+
* absent in the active render ctx — i.e. every relevant accessor reports
|
|
10530
|
+
* `inputsLocked` and the column did not appear. Distinct from the
|
|
10531
|
+
* `undefined` return that the factories still use for the "resolving" case
|
|
10532
|
+
* (the column may still appear later).
|
|
10533
|
+
*
|
|
10534
|
+
* Catch at the boundary (resolver / filter+sort wiring / data-table assembly)
|
|
10535
|
+
* when partial absence should be surfaced to the user rather than silently
|
|
10536
|
+
* producing an empty result.
|
|
10537
|
+
*/
|
|
10538
|
+
var ColumnAbsentError = class extends Error {
|
|
10539
|
+
id;
|
|
10540
|
+
constructor(id) {
|
|
10541
|
+
super(`Column is absent in the active render ctx and will not appear: ${id}`);
|
|
10542
|
+
this.id = id;
|
|
10543
|
+
this.name = "ColumnAbsentError";
|
|
10544
|
+
}
|
|
10545
|
+
};
|
|
10546
|
+
/**
|
|
10547
|
+
* ColumnLazy is the leaf-recipe building block: a {@link ColumnRecipe} whose
|
|
10548
|
+
* `id` is a bare {@link PObjectId} and whose readers are bound to a single
|
|
10549
|
+
* tree-accessor leaf. Layered encodings (Overridden / Discovered / Filtered)
|
|
10550
|
+
* are reified through their dedicated recipe classes and reference leaf
|
|
10551
|
+
* columns by id.
|
|
10552
|
+
*/
|
|
10553
|
+
var ColumnLazyImpl = class ColumnLazyImpl {
|
|
10554
|
+
id;
|
|
10555
|
+
options;
|
|
10556
|
+
specCache;
|
|
10557
|
+
dataCache;
|
|
10558
|
+
dataStatusCache;
|
|
10559
|
+
constructor(id, options) {
|
|
10560
|
+
this.id = id;
|
|
10561
|
+
this.options = options;
|
|
10562
|
+
}
|
|
10563
|
+
/** A leaf-recipe references exactly one column — its own id. */
|
|
10564
|
+
getReferencedIds() {
|
|
10565
|
+
return [this.id];
|
|
10566
|
+
}
|
|
10567
|
+
getSpec() {
|
|
10568
|
+
if (this.specCache === void 0) this.specCache = { value: this.options.getSpec() };
|
|
10569
|
+
return this.specCache.value;
|
|
10570
|
+
}
|
|
10571
|
+
/** Leaf-shaped — points straight at `this.id`. */
|
|
10572
|
+
getQuery() {
|
|
10573
|
+
return {
|
|
10574
|
+
type: "column",
|
|
10575
|
+
column: this.id
|
|
10576
|
+
};
|
|
10577
|
+
}
|
|
10578
|
+
/** Leaf-only: not on the recipe interface — only the leaf can read data directly. */
|
|
10579
|
+
getData() {
|
|
10580
|
+
if (this.dataCache === void 0) this.dataCache = { value: this.options.getData() };
|
|
10581
|
+
return this.dataCache.value;
|
|
10582
|
+
}
|
|
10583
|
+
getDataStatus() {
|
|
10584
|
+
if (this.dataStatusCache === void 0) this.dataStatusCache = { value: this.options.getDataStatus() };
|
|
10585
|
+
return this.dataStatusCache.value;
|
|
10586
|
+
}
|
|
10587
|
+
/**
|
|
10588
|
+
* Overlay overrides → produces a {@link ColumnOverriddenRecipe} wrapping
|
|
10589
|
+
* this leaf. ColumnLazy itself stays bare (id remains a plain PObjectId);
|
|
10590
|
+
* layering lives entirely in the recipe wrappers.
|
|
10591
|
+
*/
|
|
10592
|
+
withSpecs(overrides) {
|
|
10593
|
+
return ColumnOverriddenRecipe.wrap(this, overrides);
|
|
10594
|
+
}
|
|
10595
|
+
/**
|
|
10596
|
+
* Resolve via the ambient {@link ColumnRegistry}. Spec is resolved eagerly:
|
|
10597
|
+
* returns `undefined` if the leaf isn't reachable yet (resolving). Throws
|
|
10598
|
+
* {@link ColumnAbsentError} when every relevant accessor is `inputsLocked`
|
|
10599
|
+
* and the column did not appear — the column will not exist in this ctx.
|
|
10600
|
+
* Data and dataStatus stay lazy.
|
|
10601
|
+
*/
|
|
10602
|
+
static fromId(id, { ctx } = {}) {
|
|
10603
|
+
const registry = new ColumnRegistry(getCtxProviders({ ctx }));
|
|
10604
|
+
const leaf = registry.resolve(id);
|
|
10605
|
+
if (isNil(leaf)) {
|
|
10606
|
+
if (registry.isFinal()) throw new ColumnAbsentError(id);
|
|
10607
|
+
return;
|
|
10608
|
+
}
|
|
10609
|
+
const spec = readSpecAccessor(leaf);
|
|
10610
|
+
if (isNil(spec)) {
|
|
10611
|
+
if (leaf.accessor.getInputsLocked()) throw new ColumnAbsentError(id);
|
|
10612
|
+
return;
|
|
10613
|
+
}
|
|
10614
|
+
if (!spec.hasData()) return void 0;
|
|
10615
|
+
return new ColumnLazyImpl(id, {
|
|
10616
|
+
getSpec: () => spec.getDataAsJson(),
|
|
10617
|
+
getData: () => readDataAccessor(leaf),
|
|
10618
|
+
getDataStatus: () => readDataStatus(leaf)
|
|
10619
|
+
});
|
|
10620
|
+
}
|
|
10621
|
+
/** {@link PlRef} wrapper over {@link fromId}. */
|
|
10622
|
+
static fromPlRef(ref) {
|
|
10623
|
+
return ColumnLazyImpl.fromId(createGlobalPObjectId(ref.blockId, ref.name));
|
|
10624
|
+
}
|
|
10625
|
+
/**
|
|
10626
|
+
* Bind directly to an accessor-backed {@link LeafEntry} — no registry.
|
|
10627
|
+
* Throws {@link ColumnAbsentError} if the leaf has no spec field and its
|
|
10628
|
+
* accessor is `inputsLocked`. Returns `undefined` while still resolving.
|
|
10629
|
+
*/
|
|
10630
|
+
static fromAccessor(entry) {
|
|
10631
|
+
const spec = readSpecAccessor(entry);
|
|
10632
|
+
if (isNil(spec)) {
|
|
10633
|
+
if (entry.accessor.getInputsLocked()) throw new ColumnAbsentError(entry.id);
|
|
10634
|
+
return;
|
|
10635
|
+
}
|
|
10636
|
+
if (!spec.hasData()) return void 0;
|
|
10637
|
+
return new ColumnLazyImpl(entry.id, {
|
|
10638
|
+
getSpec: () => spec.getDataAsJson(),
|
|
10639
|
+
getData: () => readDataAccessor(entry),
|
|
10640
|
+
getDataStatus: () => readDataStatus(entry)
|
|
10641
|
+
});
|
|
10642
|
+
}
|
|
10643
|
+
/**
|
|
10644
|
+
* Wrap a materialised {@link PColumn}. If the input is already a
|
|
10645
|
+
* {@link ColumnLazy} it is returned as-is.
|
|
10646
|
+
*/
|
|
10647
|
+
static fromColumn(column) {
|
|
10648
|
+
if (column instanceof ColumnLazyImpl) return column;
|
|
10649
|
+
return new ColumnLazyImpl(column.id, {
|
|
10650
|
+
getSpec: () => column.spec,
|
|
10651
|
+
getData: () => column.data,
|
|
10652
|
+
getDataStatus: () => "present"
|
|
10653
|
+
});
|
|
10654
|
+
}
|
|
10655
|
+
/**
|
|
10656
|
+
* Distinguishes `present` / `resolving` / `absent` for a {@link PObjectId}
|
|
10657
|
+
* in the active render ctx. Falls back to the registry's `isFinal()`
|
|
10658
|
+
* when the id has no entry — only then we can say `absent` instead of
|
|
10659
|
+
* `resolving`.
|
|
10660
|
+
*/
|
|
10661
|
+
static getStatusById(id, { ctx } = {}) {
|
|
10662
|
+
const registry = new ColumnRegistry(getCtxProviders({ ctx }));
|
|
10663
|
+
const leaf = registry.resolve(id);
|
|
10664
|
+
if (isNil(leaf)) return registry.isFinal() ? "absent" : "resolving";
|
|
10665
|
+
return getLeafEntryStatus(leaf);
|
|
10666
|
+
}
|
|
10667
|
+
/** {@link PlRef} wrapper over {@link getStatusById}. */
|
|
10668
|
+
static getStatusByPlRef(ref, opts = {}) {
|
|
10669
|
+
return ColumnLazyImpl.getStatusById(createGlobalPObjectId(ref.blockId, ref.name), opts);
|
|
10670
|
+
}
|
|
10671
|
+
/** No registry — reads straight off the entry's accessor. */
|
|
10672
|
+
static getStatusByAccessor(entry) {
|
|
10673
|
+
return getLeafEntryStatus(entry);
|
|
10674
|
+
}
|
|
10675
|
+
};
|
|
10676
|
+
/**
|
|
10677
|
+
* Unified dispatcher — picks the right `ColumnLazyImpl.fromX` by source
|
|
10678
|
+
* shape. For ambiguous inputs callers can still use the explicit factories
|
|
10679
|
+
* (also attached as properties: `ColumnLazy.fromId`, `.fromPlRef`,
|
|
10680
|
+
* `.fromAccessor`, `.fromColumn`).
|
|
10681
|
+
*/
|
|
10682
|
+
function ColumnLazyDispatch(source, opts = {}) {
|
|
10683
|
+
if (typeof source === "string") return ColumnLazyImpl.fromId(source, opts);
|
|
10684
|
+
if (source instanceof ColumnLazyImpl) return source;
|
|
10685
|
+
if ("accessor" in source) return ColumnLazyImpl.fromAccessor(source);
|
|
10686
|
+
if (isPlRef(source)) return ColumnLazyImpl.fromPlRef(source);
|
|
10687
|
+
if (isPColumn(source)) return ColumnLazyImpl.fromColumn(source);
|
|
10688
|
+
throw new Error("ColumnLazy: unknown source shape");
|
|
10689
|
+
}
|
|
10690
|
+
/**
|
|
10691
|
+
* Polymorphic counterpart to {@link ColumnLazyDispatch}: returns the
|
|
10692
|
+
* {@link ColumnResolutionStatus} for any factory input without constructing
|
|
10693
|
+
* the recipe. For already-materialised sources ({@link PColumn} value,
|
|
10694
|
+
* existing {@link ColumnLazy}) status is `present` by construction.
|
|
10695
|
+
*/
|
|
10696
|
+
function ColumnLazyGetStatus(source, opts = {}) {
|
|
10697
|
+
if (typeof source === "string") return ColumnLazyImpl.getStatusById(source, opts);
|
|
10698
|
+
if (source instanceof ColumnLazyImpl) return "present";
|
|
10699
|
+
if ("accessor" in source) return ColumnLazyImpl.getStatusByAccessor(source);
|
|
10700
|
+
if (isPlRef(source)) return ColumnLazyImpl.getStatusByPlRef(source, opts);
|
|
10701
|
+
if (isPColumn(source)) return "present";
|
|
10702
|
+
throw new Error("ColumnLazy.getStatus: unknown source shape");
|
|
10703
|
+
}
|
|
10704
|
+
const ColumnLazy = Object.assign(ColumnLazyDispatch, {
|
|
10705
|
+
fromId: ColumnLazyImpl.fromId,
|
|
10706
|
+
fromPlRef: ColumnLazyImpl.fromPlRef,
|
|
10707
|
+
fromAccessor: ColumnLazyImpl.fromAccessor,
|
|
10708
|
+
fromColumn: ColumnLazyImpl.fromColumn,
|
|
10709
|
+
getStatus: ColumnLazyGetStatus,
|
|
10710
|
+
getStatusById: ColumnLazyImpl.getStatusById,
|
|
10711
|
+
getStatusByPlRef: ColumnLazyImpl.getStatusByPlRef,
|
|
10712
|
+
getStatusByAccessor: ColumnLazyImpl.getStatusByAccessor
|
|
10713
|
+
});
|
|
10714
|
+
const readSpecAccessor = memoizeByEntry(({ accessor, name }) => accessor.traverse({
|
|
10715
|
+
field: `${name}.spec`,
|
|
10716
|
+
assertFieldType: "Input",
|
|
10717
|
+
ignoreError: true
|
|
10718
|
+
}));
|
|
10719
|
+
/**
|
|
10720
|
+
* Per-entry counterpart to {@link readDataStatus}: tells whether the leaf's
|
|
10721
|
+
* **spec** can be read in this ctx, and — for the negative cases —
|
|
10722
|
+
* distinguishes `resolving` from `absent` via `getInputsLocked()`.
|
|
10723
|
+
*
|
|
10724
|
+
* - spec field not yet on the entry's accessor + inputs locked → `absent`
|
|
10725
|
+
* - spec field not yet on the entry's accessor + still resolving → `resolving`
|
|
10726
|
+
* - spec resource present but bytes not yet written → `resolving`
|
|
10727
|
+
* (transient — the spec resource is connected, just unfilled)
|
|
10728
|
+
* - spec resource present and `hasData()` → `present`
|
|
10729
|
+
*/
|
|
10730
|
+
function getLeafEntryStatus(entry) {
|
|
10731
|
+
const spec = readSpecAccessor(entry);
|
|
10732
|
+
if (isNil(spec)) return entry.accessor.getInputsLocked() ? "absent" : "resolving";
|
|
10733
|
+
if (!spec.hasData()) return "resolving";
|
|
10734
|
+
return "present";
|
|
10735
|
+
}
|
|
10736
|
+
const readDataAccessor = memoizeByEntry(({ accessor, name }) => accessor.traverse({
|
|
10737
|
+
field: `${name}.data`,
|
|
10738
|
+
assertFieldType: "Input",
|
|
10739
|
+
ignoreError: true
|
|
10740
|
+
}));
|
|
10741
|
+
const readDataStatus = memoizeByEntry(({ accessor, name }) => {
|
|
10742
|
+
if (accessor.listInputFields().includes(`${name}.data`)) return "present";
|
|
10743
|
+
return accessor.getInputsLocked() ? "absent" : "resolving";
|
|
10744
|
+
});
|
|
10745
|
+
function memoizeByEntry(fn) {
|
|
10746
|
+
const cache = new LRUCache({ max: 1e3 });
|
|
10747
|
+
return (entry) => {
|
|
10748
|
+
const key = `${entry.accessor.handle}:${entry.name}`;
|
|
10749
|
+
let hit = cache.get(key);
|
|
10750
|
+
if (!hit) cache.set(key, hit = { value: fn(entry) });
|
|
10751
|
+
return hit.value;
|
|
10752
|
+
};
|
|
10753
|
+
}
|
|
10754
|
+
//#endregion
|
|
10755
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
|
|
10756
|
+
/**
|
|
10757
|
+
* Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
|
|
10758
|
+
* concrete recipe variant based on the id's encoding and recurses on
|
|
10759
|
+
* wrappers' inner `source`:
|
|
10760
|
+
*
|
|
10761
|
+
* - bare {@link PObjectId} (non-JSON) → `ColumnLazy.fromId`
|
|
10762
|
+
* - `ColumnDiscoveredKey` → {@link ColumnDiscoveredRecipe}
|
|
10763
|
+
* - `ColumnOverriddenKey { source, specOverrides }` → recurse on `source`,
|
|
10764
|
+
* then {@link ColumnOverriddenRecipe.wrap}
|
|
10765
|
+
* - `ColumnFilteredKey { source, axisFilters }` → recurse on `source`,
|
|
10766
|
+
* then {@link ColumnFilteredRecipe.wrap}
|
|
10767
|
+
*
|
|
10768
|
+
* Returns `undefined` for unsupported variants (e.g. AnchoredPColumnId,
|
|
10769
|
+
* which needs an anchor map to resolve) or when a nested source itself
|
|
10770
|
+
* cannot be built.
|
|
10771
|
+
*/
|
|
10772
|
+
function ColumnRecipeBuild(id, opts = {}) {
|
|
10773
|
+
const parsed = parseColumnIdSafely(id);
|
|
10774
|
+
if (isPObjectKey(parsed)) return ColumnLazyImpl.fromId(id, opts);
|
|
10775
|
+
if (isColumnDiscoveredKey(parsed)) return ColumnDiscoveredRecipe.fromKey(parsed, opts);
|
|
10776
|
+
if (isColumnOverriddenKey(parsed)) {
|
|
10777
|
+
const inner = ColumnRecipe(parsed.source, opts);
|
|
10778
|
+
if (inner === void 0) return void 0;
|
|
10779
|
+
return ColumnOverriddenRecipe.wrap(inner, parsed.specOverrides);
|
|
10780
|
+
}
|
|
10781
|
+
if (isColumnFilteredKey(parsed)) {
|
|
10782
|
+
if (typeof parsed.source !== "string") throw new Error(`Unsupported ColumnRecipe id variant: filtered column with non-string source (${JSON.stringify(parsed.source)})`);
|
|
10783
|
+
const inner = ColumnRecipe(parsed.source, opts);
|
|
10784
|
+
if (inner === void 0) return void 0;
|
|
10785
|
+
return ColumnFilteredRecipe.wrap(inner, parsed.axisFilters);
|
|
10786
|
+
}
|
|
10787
|
+
throw new Error(`Unsupported ColumnRecipe id variant: ${id}`);
|
|
10788
|
+
}
|
|
10789
|
+
/**
|
|
10790
|
+
* Resolution status counterpart to {@link ColumnRecipeBuild}. Dispatches on
|
|
10791
|
+
* the parsed id shape to the matching `getStatusBy*` static — never
|
|
10792
|
+
* constructs the recipe. Use this at boundaries (resolver, filter/sort
|
|
10793
|
+
* targets) to throw early on `absent` instead of silently producing an empty
|
|
10794
|
+
* recipe via {@link ColumnRecipeBuild}.
|
|
10795
|
+
*/
|
|
10796
|
+
function ColumnRecipeGetStatus(id, opts = {}) {
|
|
10797
|
+
const parsed = parseColumnIdSafely(id);
|
|
10798
|
+
if (isPObjectKey(parsed)) return ColumnLazyImpl.getStatusById(id, opts);
|
|
10799
|
+
if (isColumnDiscoveredKey(parsed)) return ColumnDiscoveredRecipe.getStatusByKey(parsed, opts);
|
|
10800
|
+
if (isColumnOverriddenKey(parsed)) return ColumnOverriddenRecipe.getStatusByKey(parsed, opts);
|
|
10801
|
+
if (isColumnFilteredKey(parsed)) return ColumnFilteredRecipe.getStatusByKey(parsed, opts);
|
|
10802
|
+
throw new Error(`Unsupported ColumnRecipe id variant: ${id}`);
|
|
10803
|
+
}
|
|
10804
|
+
const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
|
|
10805
|
+
//#endregion
|
|
10806
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/column.js
|
|
10807
|
+
/**
|
|
10808
|
+
* Unified entry point — routes between the two top-level dispatchers:
|
|
10809
|
+
* - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
|
|
10810
|
+
* - object source (`PlRef` / `LeafEntry` / `PColumn` / `ColumnLazy`) → {@link ColumnLazy}
|
|
10811
|
+
*
|
|
10812
|
+
* `ColumnLazy` is itself a `ColumnRecipe<PObjectId>`, so the return type is
|
|
10813
|
+
* the common `ColumnRecipe`.
|
|
10814
|
+
*/
|
|
10815
|
+
function Column(source, opts) {
|
|
10816
|
+
if (typeof source === "string") return ColumnRecipe(source, opts);
|
|
10817
|
+
return ColumnLazy(source, opts);
|
|
10818
|
+
}
|
|
10819
|
+
//#endregion
|
|
10820
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
|
|
10821
|
+
/**
|
|
10822
|
+
* Build a {@link ColumnsCollection} from sandbox-side source descriptors.
|
|
10823
|
+
* Resolves the `columnsCollection` driver (either from `deps.driver` or via
|
|
10824
|
+
* `getService("columnsCollection")`) and asks the host to mint a fresh
|
|
10825
|
+
* handle covering the supplied sources. Pass `sources === undefined` to
|
|
10826
|
+
* fall back to the active render ctx (main outputs + prerun + result pool).
|
|
10827
|
+
*
|
|
10828
|
+
* `sources` accepts {@link ColumnsSourceShorthand} string literals
|
|
10829
|
+
* (`"result_pool"`, `"current_block"`) for the common ctx-derived sources.
|
|
10830
|
+
*/
|
|
10831
|
+
function ColumnsCollection(sources, deps) {
|
|
10832
|
+
const driver = deps?.driver ?? getService("columnsCollection", { ctx: deps?.ctx });
|
|
10833
|
+
const serialized = sources ? sources.flatMap((s) => toSerializedSources(s, deps?.ctx)) : defaultCtxSources(deps?.ctx);
|
|
10834
|
+
return new ColumnsCollectionImpl(driver.create(serialized), driver);
|
|
10835
|
+
}
|
|
10836
|
+
/**
|
|
10837
|
+
* Sandbox proxy over the host-side `ColumnsCollection` driver. The driver
|
|
10838
|
+
* owns all column-set state; this object only carries an opaque
|
|
10839
|
+
* {@link CollectionHandle} plus a reference to the driver service.
|
|
10840
|
+
*
|
|
10841
|
+
* Construct via {@link ColumnsCollection} — the bare constructor is a
|
|
10842
|
+
* trivial `(handle, driver)` pair so that `addSource` / `discover` / `filter`
|
|
10843
|
+
* can rebind a freshly-minted handle without going through source
|
|
10844
|
+
* serialisation again.
|
|
10845
|
+
*
|
|
10846
|
+
* Every method returning a `ColumnsCollection` mints a fresh handle on the
|
|
10847
|
+
* host — the host VM bridge pins it to the active render ctx, so the sandbox
|
|
10848
|
+
* never has to manage refcounts.
|
|
10849
|
+
*/
|
|
10850
|
+
var ColumnsCollectionImpl = class ColumnsCollectionImpl {
|
|
10851
|
+
handle;
|
|
10852
|
+
driver;
|
|
10853
|
+
constructor(handle, driver) {
|
|
10854
|
+
this.handle = handle;
|
|
10855
|
+
this.driver = driver;
|
|
10856
|
+
}
|
|
10857
|
+
isEmpty() {
|
|
10858
|
+
return this.driver.isEmpty(this.handle);
|
|
10859
|
+
}
|
|
10860
|
+
isFinal() {
|
|
10861
|
+
return this.driver.isFinal(this.handle);
|
|
10862
|
+
}
|
|
10863
|
+
getColumnIds() {
|
|
10864
|
+
return this.driver.getColumns(this.handle);
|
|
10865
|
+
}
|
|
10866
|
+
getColumns() {
|
|
10867
|
+
return this.getColumnIds().map((id) => ColumnRecipe(id)).filter((c) => !isNil(c));
|
|
10868
|
+
}
|
|
10869
|
+
addSource(source) {
|
|
10870
|
+
return new ColumnsCollectionImpl(this.driver.addSource(this.handle, toSerializedSources(source)), this.driver);
|
|
10871
|
+
}
|
|
10872
|
+
discover(options) {
|
|
10873
|
+
return new ColumnsCollectionImpl(this.driver.discover(this.handle, options), this.driver);
|
|
10874
|
+
}
|
|
10875
|
+
filter(options) {
|
|
10876
|
+
return new ColumnsCollectionImpl(this.driver.filter(this.handle, options), this.driver);
|
|
10877
|
+
}
|
|
10878
|
+
};
|
|
10879
|
+
function toSerializedSources(source, ctx) {
|
|
10880
|
+
if (source === "result_pool") return [{ kind: "result_pool" }];
|
|
10881
|
+
if (source === "current_block") return currentBlockSources(ctx);
|
|
10882
|
+
if (source instanceof ColumnsCollectionImpl) return [{
|
|
10883
|
+
kind: "collection",
|
|
10884
|
+
handle: source.handle
|
|
10885
|
+
}];
|
|
10886
|
+
if (source instanceof TreeNodeAccessor) return [{
|
|
10887
|
+
kind: "accessor",
|
|
10888
|
+
accessor: source.handle,
|
|
10889
|
+
path: source.resolvePath
|
|
10890
|
+
}];
|
|
10891
|
+
if (isColumnArray(source)) return [{
|
|
10892
|
+
kind: "ids",
|
|
10893
|
+
ids: source.columns.map((c) => c.id),
|
|
10894
|
+
isFinal: source.isFinal
|
|
10895
|
+
}];
|
|
10896
|
+
if (isColumnProvider(source)) return [{
|
|
10897
|
+
kind: "ids",
|
|
10898
|
+
ids: source.getColumns().map((c) => c.id),
|
|
10899
|
+
isFinal: source.isFinal()
|
|
10900
|
+
}];
|
|
10901
|
+
throw new Error("ColumnsCollection: unrecognised ColumnsSource shape");
|
|
10902
|
+
}
|
|
10903
|
+
function isColumnArray(source) {
|
|
10904
|
+
if (typeof source !== "object" || source === null) return false;
|
|
10905
|
+
const s = source;
|
|
10906
|
+
return Array.isArray(s.columns) && typeof s.isFinal === "boolean";
|
|
10907
|
+
}
|
|
10908
|
+
function currentBlockSources(ctx) {
|
|
10909
|
+
const renderCtx = ctx ?? getCfgRenderCtx();
|
|
10910
|
+
const sources = [];
|
|
10911
|
+
const outputs = renderCtx.getAccessorHandleByName(MainAccessorName);
|
|
10912
|
+
if (outputs !== void 0) sources.push({
|
|
10913
|
+
kind: "accessor",
|
|
10914
|
+
accessor: outputs,
|
|
10915
|
+
path: [MainAccessorName]
|
|
10916
|
+
});
|
|
10917
|
+
const prerun = renderCtx.getAccessorHandleByName(StagingAccessorName);
|
|
10918
|
+
if (prerun !== void 0) sources.push({
|
|
10919
|
+
kind: "accessor",
|
|
10920
|
+
accessor: prerun,
|
|
10921
|
+
path: [StagingAccessorName]
|
|
10922
|
+
});
|
|
10923
|
+
return sources;
|
|
10924
|
+
}
|
|
10925
|
+
function defaultCtxSources(ctx) {
|
|
10926
|
+
return [...currentBlockSources(ctx), { kind: "result_pool" }];
|
|
10927
|
+
}
|
|
10928
|
+
//#endregion
|
|
10929
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/columns/utils.js
|
|
10930
|
+
/**
|
|
10931
|
+
* PObjectIds of every non-hit column referenced by `recipe.getQuery()`,
|
|
10932
|
+
* deduped in traversal order. The hit column is
|
|
10933
|
+
* `extractPObjectId(recipe.id)`; anything else in the query is a linker or
|
|
10934
|
+
* other engine-consumed column.
|
|
10935
|
+
*
|
|
10936
|
+
* Pure query walk — no registry access. Use {@link collectLinkerColumns} for
|
|
10937
|
+
* the resolved {@link ColumnLazy} variant.
|
|
10938
|
+
*/
|
|
10939
|
+
function collectLinkerIds(recipe) {
|
|
10940
|
+
const hit = extractPObjectId(recipe.id);
|
|
10941
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10942
|
+
const out = [];
|
|
10943
|
+
for (const id of collectSpecQueryColumns(recipe.getQuery())) {
|
|
10944
|
+
const bare = extractPObjectId(id);
|
|
10945
|
+
if (bare === hit) continue;
|
|
10946
|
+
if (seen.has(bare)) continue;
|
|
10947
|
+
seen.add(bare);
|
|
10948
|
+
out.push(bare);
|
|
10949
|
+
}
|
|
10950
|
+
return out;
|
|
10951
|
+
}
|
|
10952
|
+
/**
|
|
10953
|
+
* {@link collectLinkerIds} resolved against the ambient context as
|
|
10954
|
+
* {@link ColumnLazy} instances. Throws if any id fails to resolve —
|
|
10955
|
+
* matches the contract of the legacy `resolveLinkers` it replaces.
|
|
10956
|
+
*/
|
|
10957
|
+
function collectLinkerColumns(recipe, opts = {}) {
|
|
10958
|
+
return collectLinkerIds(recipe).map((id) => ColumnLazyImpl.fromId(id, opts) ?? throwError(`materializeLinkers: linker ${id} not resolvable`));
|
|
10959
|
+
}
|
|
10960
|
+
/**
|
|
10961
|
+
* Hit-side axis qualifications for the recipe — the ones that should land on
|
|
10962
|
+
* the outer-join entry wrapping this column at the consumer boundary.
|
|
10963
|
+
*
|
|
10964
|
+
* Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via
|
|
10965
|
+
* `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise
|
|
10966
|
+
* returns `[]`. Pure recipe walk — no query-tree introspection.
|
|
10967
|
+
*/
|
|
10968
|
+
function hitQualifications(recipe) {
|
|
10969
|
+
return findDiscovered(recipe)?.getColumnQualifications() ?? [];
|
|
10970
|
+
}
|
|
10971
|
+
/**
|
|
10972
|
+
* Per-primary-column axis qualifications for the recipe — applied to the
|
|
10973
|
+
* outer primary anchors on this recipe's group side. Keyed by the external
|
|
10974
|
+
* primary column id (NOT by columns inside this recipe's own query).
|
|
10975
|
+
*
|
|
10976
|
+
* Same walk strategy as {@link hitQualifications}.
|
|
10977
|
+
*/
|
|
10978
|
+
function queriesQualifications(recipe) {
|
|
10979
|
+
return findDiscovered(recipe)?.getQueriesQualifications() ?? {};
|
|
10980
|
+
}
|
|
10981
|
+
/**
|
|
10982
|
+
* Whether the recipe's underlying data resources actually carry bytes —
|
|
10983
|
+
* strictly stronger than `getDataStatus() === "present"`, which only tells
|
|
10984
|
+
* that the `.data` field is wired onto the accessor.
|
|
10985
|
+
*
|
|
10986
|
+
* Walks every physical leaf the recipe depends on via
|
|
10987
|
+
* {@link ColumnRecipe.getReferencedIds} (resolves each id back to a
|
|
10988
|
+
* {@link ColumnLazy} through the ambient ctx) and ANDs `hasData()` across
|
|
10989
|
+
* all of them. Inline {@link PColumnValues} payloads count as present.
|
|
10990
|
+
*
|
|
10991
|
+
* Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as
|
|
10992
|
+
* "not yet ready") rather than throwing — this is a UI-facing predicate, not
|
|
10993
|
+
* a contract assertion.
|
|
10994
|
+
*/
|
|
10995
|
+
function hasColumnData(recipe, opts = {}) {
|
|
10996
|
+
for (const id of recipe.getReferencedIds()) {
|
|
10997
|
+
const lazy = ColumnLazyImpl.fromId(id, opts);
|
|
10998
|
+
if (lazy === void 0) return false;
|
|
10999
|
+
if (lazy.getDataStatus() !== "present") return false;
|
|
11000
|
+
if (!isLazyDataPresent(lazy.getData())) return false;
|
|
11001
|
+
}
|
|
11002
|
+
return true;
|
|
11003
|
+
}
|
|
11004
|
+
function isLazyDataPresent(data) {
|
|
11005
|
+
if (data === void 0) return false;
|
|
11006
|
+
if (Array.isArray(data)) return true;
|
|
11007
|
+
if (data instanceof TreeNodeAccessor) return data.hasData();
|
|
11008
|
+
if (isDataInfo(data)) {
|
|
11009
|
+
let ok = true;
|
|
11010
|
+
visitDataInfo(data, (blob) => {
|
|
11011
|
+
ok &&= blob.hasData();
|
|
11012
|
+
});
|
|
11013
|
+
return ok;
|
|
11014
|
+
}
|
|
11015
|
+
return false;
|
|
11016
|
+
}
|
|
11017
|
+
/**
|
|
11018
|
+
* Walk wrapper layers (Overridden, Filtered) until a {@link
|
|
11019
|
+
* ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain
|
|
11020
|
+
* has no Discovered layer (bare leaves and Overridden-over-leaf cases).
|
|
11021
|
+
*
|
|
11022
|
+
* Invariant from the wrapper classes themselves: there is at most one
|
|
11023
|
+
* Discovered layer in any recipe chain — Discovered is constructed only via
|
|
11024
|
+
* its own factory and is never re-wrapped by Discovered.
|
|
11025
|
+
*/
|
|
11026
|
+
function findDiscovered(recipe) {
|
|
11027
|
+
let current = recipe;
|
|
11028
|
+
while (true) {
|
|
11029
|
+
if (current instanceof ColumnDiscoveredRecipe) return current;
|
|
11030
|
+
if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {
|
|
11031
|
+
current = current.getInner();
|
|
11032
|
+
continue;
|
|
8160
11033
|
}
|
|
8161
|
-
|
|
8162
|
-
...this.config.outputs,
|
|
8163
|
-
...pluginOutputs
|
|
8164
|
-
};
|
|
8165
|
-
globalThis.platformaApiVersion = apiVersion;
|
|
8166
|
-
if (!isInUI()) return { config: {
|
|
8167
|
-
v4: {
|
|
8168
|
-
configVersion: 4,
|
|
8169
|
-
modelAPIVersion: 2,
|
|
8170
|
-
sdkVersion: PlatformaSDKVersion,
|
|
8171
|
-
renderingMode: this.config.renderingMode,
|
|
8172
|
-
sections: this.config.sections,
|
|
8173
|
-
title: this.config.title,
|
|
8174
|
-
subtitle: this.config.subtitle,
|
|
8175
|
-
tags: this.config.tags,
|
|
8176
|
-
outputs: allOutputs,
|
|
8177
|
-
enrichmentTargets: this.config.enrichmentTargets,
|
|
8178
|
-
featureFlags: this.config.featureFlags,
|
|
8179
|
-
blockLifecycleCallbacks: { ...BlockStorageFacadeHandles }
|
|
8180
|
-
},
|
|
8181
|
-
sdkVersion: PlatformaSDKVersion,
|
|
8182
|
-
renderingMode: this.config.renderingMode,
|
|
8183
|
-
sections: this.config.sections,
|
|
8184
|
-
outputs: Object.fromEntries(Object.entries(this.config.outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)]))
|
|
8185
|
-
} };
|
|
8186
|
-
else return {
|
|
8187
|
-
...getPlatformaInstance({
|
|
8188
|
-
sdkVersion: PlatformaSDKVersion,
|
|
8189
|
-
apiVersion
|
|
8190
|
-
}),
|
|
8191
|
-
blockModelInfo: {
|
|
8192
|
-
outputs: Object.fromEntries(Object.entries(allOutputs).map(([key, value]) => [key, { withStatus: Boolean(isConfigLambda(value) && value.withStatus) }])),
|
|
8193
|
-
pluginIds: pluginHandles,
|
|
8194
|
-
featureFlags: this.config.featureFlags,
|
|
8195
|
-
pluginPublicOutputs: Object.fromEntries(pluginHandles.map((handle) => [handle, plugins[handle].model.publicOutputDef]))
|
|
8196
|
-
}
|
|
8197
|
-
};
|
|
11034
|
+
return;
|
|
8198
11035
|
}
|
|
8199
|
-
}
|
|
11036
|
+
}
|
|
11037
|
+
/**
|
|
11038
|
+
* A recipe is a "leaf" (directly co-indexed on the anchor, reached without a
|
|
11039
|
+
* linker chain) iff its wrapper chain contains no {@link ColumnDiscoveredRecipe}.
|
|
11040
|
+
*
|
|
11041
|
+
* `Filtered` / `Overridden` over a bare leaf stay leaves; anything wrapping a
|
|
11042
|
+
* `Discovered` (e.g. `Overridden(Discovered(...))`) is linked. Use this — not an
|
|
11043
|
+
* `instanceof ColumnLazyImpl` check — to split direct vs. linker-joined columns,
|
|
11044
|
+
* since projections over a plain leaf are still direct.
|
|
11045
|
+
*/
|
|
11046
|
+
function isLeafColumn(recipe) {
|
|
11047
|
+
return findDiscovered(recipe) === void 0;
|
|
11048
|
+
}
|
|
8200
11049
|
//#endregion
|
|
8201
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
11050
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/filters/traverse.js
|
|
8202
11051
|
/**
|
|
8203
11052
|
* Recursively traverses a FilterSpec tree bottom-up, applying visitor callbacks.
|
|
8204
11053
|
*
|
|
@@ -8237,16 +11086,15 @@ function collectFilterSpecColumns(filter) {
|
|
|
8237
11086
|
});
|
|
8238
11087
|
}
|
|
8239
11088
|
//#endregion
|
|
8240
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
8241
|
-
/**
|
|
8242
|
-
function resolveColumnRef(
|
|
8243
|
-
|
|
8244
|
-
return parsed.type === "axis" ? {
|
|
11089
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
|
|
11090
|
+
/** Converts a QueryColumnId object into a SpecQueryExpression reference. */
|
|
11091
|
+
function resolveColumnRef(col) {
|
|
11092
|
+
return col.type === "axis" ? {
|
|
8245
11093
|
type: "axisRef",
|
|
8246
|
-
value:
|
|
11094
|
+
value: col.id
|
|
8247
11095
|
} : {
|
|
8248
11096
|
type: "columnRef",
|
|
8249
|
-
value:
|
|
11097
|
+
value: col.id
|
|
8250
11098
|
};
|
|
8251
11099
|
}
|
|
8252
11100
|
/** Converts a FilterSpec tree into a SpecQueryExpression. */
|
|
@@ -8566,7 +11414,7 @@ function isEmpty(value) {
|
|
|
8566
11414
|
return true;
|
|
8567
11415
|
}
|
|
8568
11416
|
//#endregion
|
|
8569
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
11417
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/filters/distill.js
|
|
8570
11418
|
/**
|
|
8571
11419
|
* Strips non-FilterSpec metadata (whitelist approach) and removes
|
|
8572
11420
|
* unfilled leaves (type is undefined or any required field is undefined).
|
|
@@ -8671,7 +11519,7 @@ const REQUIRED_KEYS_BY_TYPE = {
|
|
|
8671
11519
|
greaterThanColumnOrEqual: ["column", "rhs"]
|
|
8672
11520
|
};
|
|
8673
11521
|
//#endregion
|
|
8674
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
11522
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
|
|
8675
11523
|
/** Upgrade PlDataTableStateV2 to the latest version */
|
|
8676
11524
|
function upgradePlDataTableStateV2(state) {
|
|
8677
11525
|
if (!state) return createPlDataTableStateV2();
|
|
@@ -8682,12 +11530,13 @@ function upgradePlDataTableStateV2(state) {
|
|
|
8682
11530
|
...entry,
|
|
8683
11531
|
filtersState: []
|
|
8684
11532
|
})),
|
|
8685
|
-
pTableParams:
|
|
11533
|
+
pTableParams: createDefaultPTableParamsV7()
|
|
8686
11534
|
};
|
|
8687
11535
|
if (state.version === 3) state = createPlDataTableStateV2();
|
|
8688
11536
|
if (state.version === 4) state = migrateV4toV6(state);
|
|
8689
11537
|
if (state.version === 5) state = migrateV5toV6(state);
|
|
8690
11538
|
if (state.version === 6) state = migrateV6toV7(state);
|
|
11539
|
+
if (state.version === 7) state = migrateV7toV8(state);
|
|
8691
11540
|
return state;
|
|
8692
11541
|
}
|
|
8693
11542
|
/** Migrate v5 to v6: unwrap `{source, labeled}` colIds in gridState. */
|
|
@@ -8698,7 +11547,7 @@ function migrateV5toV6(state) {
|
|
|
8698
11547
|
...entry,
|
|
8699
11548
|
gridState: unwrapV5GridState(entry.gridState)
|
|
8700
11549
|
})),
|
|
8701
|
-
pTableParams:
|
|
11550
|
+
pTableParams: createDefaultPTableParamsV7()
|
|
8702
11551
|
};
|
|
8703
11552
|
}
|
|
8704
11553
|
/** Convert v5 wrapped colId JSON to bare PTableColumnSpec JSON, taking `.source`.
|
|
@@ -8755,10 +11604,7 @@ function migrateV4toV6(state) {
|
|
|
8755
11604
|
const nextId = () => ++idCounter;
|
|
8756
11605
|
const migratedCache = state.stateCache.map((entry) => {
|
|
8757
11606
|
const leaves = [];
|
|
8758
|
-
for (const f of entry.filtersState) if (f.filter !== null && !f.filter.disabled)
|
|
8759
|
-
const column = canonicalizeJson(f.id);
|
|
8760
|
-
leaves.push(migrateTableFilter(column, f.filter.value, nextId));
|
|
8761
|
-
}
|
|
11607
|
+
for (const f of entry.filtersState) if (f.filter !== null && !f.filter.disabled) leaves.push(migrateTableFilter(canonicalizeJson(f.id), f.filter.value, nextId));
|
|
8762
11608
|
const filtersState = leaves.length > 0 ? {
|
|
8763
11609
|
id: nextId(),
|
|
8764
11610
|
type: "and",
|
|
@@ -8786,10 +11632,11 @@ function migrateV4toV6(state) {
|
|
|
8786
11632
|
filters: distillFilterSpec(currentCache.filtersState),
|
|
8787
11633
|
defaultFilters: null,
|
|
8788
11634
|
sorting: state.pTableParams.sorting
|
|
8789
|
-
} :
|
|
11635
|
+
} : createDefaultPTableParamsV7()
|
|
8790
11636
|
};
|
|
8791
11637
|
}
|
|
8792
|
-
/** Migrate a single per-column PlTableFilter to a
|
|
11638
|
+
/** Migrate a single per-column PlTableFilter to a v7-form tree node (legacy
|
|
11639
|
+
* string column ids). v7 → v8 later converts these to object form. */
|
|
8793
11640
|
function migrateTableFilter(column, filter, nextId) {
|
|
8794
11641
|
const id = nextId();
|
|
8795
11642
|
switch (filter.type) {
|
|
@@ -8915,7 +11762,9 @@ function migrateTableFilter(column, filter, nextId) {
|
|
|
8915
11762
|
};
|
|
8916
11763
|
}
|
|
8917
11764
|
}
|
|
8918
|
-
|
|
11765
|
+
/** Default pTableParams in the v7 shape (sorting: []). Used by intermediate
|
|
11766
|
+
* migration steps that produce v6/v7 state before the v7 → v8 conversion. */
|
|
11767
|
+
function createDefaultPTableParamsV7() {
|
|
8919
11768
|
return {
|
|
8920
11769
|
sourceId: null,
|
|
8921
11770
|
hiddenColIds: null,
|
|
@@ -8924,87 +11773,232 @@ function createDefaultPTableParams() {
|
|
|
8924
11773
|
sorting: []
|
|
8925
11774
|
};
|
|
8926
11775
|
}
|
|
11776
|
+
function createDefaultPTableParams() {
|
|
11777
|
+
return {
|
|
11778
|
+
sourceId: null,
|
|
11779
|
+
hiddenColIds: null,
|
|
11780
|
+
filters: null,
|
|
11781
|
+
defaultFilters: null,
|
|
11782
|
+
sorting: null
|
|
11783
|
+
};
|
|
11784
|
+
}
|
|
8927
11785
|
function createPlDataTableStateV2() {
|
|
8928
11786
|
return {
|
|
8929
|
-
version:
|
|
11787
|
+
version: 8,
|
|
8930
11788
|
stateCache: [],
|
|
8931
11789
|
pTableParams: createDefaultPTableParams()
|
|
8932
11790
|
};
|
|
8933
11791
|
}
|
|
11792
|
+
function migrateV7toV8(state) {
|
|
11793
|
+
const newCache = state.stateCache.map((entry) => ({
|
|
11794
|
+
sourceId: entry.sourceId,
|
|
11795
|
+
gridState: entry.gridState,
|
|
11796
|
+
sheetsState: entry.sheetsState,
|
|
11797
|
+
filtersState: convertFiltersWithMeta(entry.filtersState),
|
|
11798
|
+
defaultFiltersState: convertFiltersWithMeta(entry.defaultFiltersState),
|
|
11799
|
+
searchString: entry.searchString
|
|
11800
|
+
}));
|
|
11801
|
+
const params = state.pTableParams;
|
|
11802
|
+
let pTableParams;
|
|
11803
|
+
if (params.sourceId === null) pTableParams = createDefaultPTableParams();
|
|
11804
|
+
else pTableParams = {
|
|
11805
|
+
sourceId: params.sourceId,
|
|
11806
|
+
hiddenColIds: params.hiddenColIds,
|
|
11807
|
+
sorting: params.sorting.length === 0 ? null : params.sorting,
|
|
11808
|
+
filters: convertFiltersPlain(params.filters),
|
|
11809
|
+
defaultFilters: convertFiltersPlain(params.defaultFilters)
|
|
11810
|
+
};
|
|
11811
|
+
return {
|
|
11812
|
+
version: 8,
|
|
11813
|
+
stateCache: newCache,
|
|
11814
|
+
pTableParams
|
|
11815
|
+
};
|
|
11816
|
+
}
|
|
11817
|
+
function convertFiltersWithMeta(node) {
|
|
11818
|
+
if (node === null) return null;
|
|
11819
|
+
const result = pruneFilterNode(node);
|
|
11820
|
+
if (result === void 0) return null;
|
|
11821
|
+
return result;
|
|
11822
|
+
}
|
|
11823
|
+
function convertFiltersPlain(node) {
|
|
11824
|
+
if (node === null) return null;
|
|
11825
|
+
const result = pruneFilterNode(node);
|
|
11826
|
+
if (result === void 0) return null;
|
|
11827
|
+
return result;
|
|
11828
|
+
}
|
|
11829
|
+
/** Recursively converts and prunes a legacy v7 filter tree. Preserves meta
|
|
11830
|
+
* fields (id/isExpanded/source/isSuppressed) on non-leaf nodes. Returns
|
|
11831
|
+
* `undefined` when the subtree is empty after pruning. */
|
|
11832
|
+
function pruneFilterNode(node) {
|
|
11833
|
+
if (!node || typeof node !== "object") return void 0;
|
|
11834
|
+
const n = node;
|
|
11835
|
+
if (n.type === "and" || n.type === "or") {
|
|
11836
|
+
const kept = (n.filters ?? []).map((f) => pruneFilterNode(f)).filter((f) => f !== void 0);
|
|
11837
|
+
if (kept.length === 0) return void 0;
|
|
11838
|
+
return {
|
|
11839
|
+
...n,
|
|
11840
|
+
type: n.type,
|
|
11841
|
+
filters: kept
|
|
11842
|
+
};
|
|
11843
|
+
}
|
|
11844
|
+
if (n.type === "not") {
|
|
11845
|
+
const inner = pruneFilterNode(n.filter);
|
|
11846
|
+
if (inner === void 0) return void 0;
|
|
11847
|
+
return {
|
|
11848
|
+
...n,
|
|
11849
|
+
type: "not",
|
|
11850
|
+
filter: inner
|
|
11851
|
+
};
|
|
11852
|
+
}
|
|
11853
|
+
return convertLegacyLeaf(n);
|
|
11854
|
+
}
|
|
11855
|
+
function convertLegacyLeaf(leaf) {
|
|
11856
|
+
if (leaf.type === void 0) return leaf;
|
|
11857
|
+
const result = { ...leaf };
|
|
11858
|
+
if ("column" in result) {
|
|
11859
|
+
const c = parseLegacyLeafColumn(result.column);
|
|
11860
|
+
if (c === void 0) return void 0;
|
|
11861
|
+
result.column = c;
|
|
11862
|
+
}
|
|
11863
|
+
if ("rhs" in result) {
|
|
11864
|
+
const c = parseLegacyLeafColumn(result.rhs);
|
|
11865
|
+
if (c === void 0) return void 0;
|
|
11866
|
+
result.rhs = c;
|
|
11867
|
+
}
|
|
11868
|
+
return result;
|
|
11869
|
+
}
|
|
11870
|
+
function parseLegacyLeafColumn(s) {
|
|
11871
|
+
if (typeof s !== "string") return void 0;
|
|
11872
|
+
const parsed = parseJsonSafely(s);
|
|
11873
|
+
if (!parsed || typeof parsed !== "object") return void 0;
|
|
11874
|
+
if (!("type" in parsed) || !("id" in parsed)) return void 0;
|
|
11875
|
+
const t = parsed.type;
|
|
11876
|
+
if (t !== "axis" && t !== "column") return void 0;
|
|
11877
|
+
return parsed;
|
|
11878
|
+
}
|
|
8934
11879
|
//#endregion
|
|
8935
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
11880
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
|
|
11881
|
+
/** Adapt a {@link ColumnRecipe} to the plain {@link RuleColumn} shape. */
|
|
11882
|
+
function toRuleColumn(col) {
|
|
11883
|
+
return {
|
|
11884
|
+
id: extractPObjectId(col.id),
|
|
11885
|
+
spec: col.getSpec()
|
|
11886
|
+
};
|
|
11887
|
+
}
|
|
11888
|
+
/** Check if column should be omitted from the table */
|
|
11889
|
+
function isColumnHidden(spec) {
|
|
11890
|
+
return readAnnotation(spec, Annotation.Table.Visibility) === "hidden";
|
|
11891
|
+
}
|
|
8936
11892
|
/** Check if column is hidden by default */
|
|
8937
11893
|
function isColumnOptional(spec) {
|
|
8938
11894
|
return readAnnotation(spec, Annotation.Table.Visibility) === "optional";
|
|
8939
11895
|
}
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
const
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
}]
|
|
8985
|
-
},
|
|
8986
|
-
data: labelColumn.data
|
|
8987
|
-
});
|
|
8988
|
-
else labelColumns.push(labelColumn);
|
|
8989
|
-
unlabeledAxes.splice(labelMatch, 1);
|
|
11896
|
+
/** Get effective visibility for a column. Rule map lookup first, then annotation fallback. */
|
|
11897
|
+
function getEffectiveVisibility(col, visibilityByColId) {
|
|
11898
|
+
const rule = visibilityByColId?.get(col.id);
|
|
11899
|
+
if (rule !== void 0) return rule.visibility;
|
|
11900
|
+
if (isColumnHidden(col.spec)) return "hidden";
|
|
11901
|
+
if (isColumnOptional(col.spec)) return "optional";
|
|
11902
|
+
}
|
|
11903
|
+
/** Get ordering priority for a column. Rule map lookup first, then annotation fallback. */
|
|
11904
|
+
function getOrderPriority(col, orderByColId) {
|
|
11905
|
+
const rule = orderByColId?.get(col.id);
|
|
11906
|
+
if (rule !== void 0) return rule.priority;
|
|
11907
|
+
const annotation = Number(readAnnotation(col.spec, Annotation.Table.OrderPriority));
|
|
11908
|
+
return isNaN(annotation) ? void 0 : annotation;
|
|
11909
|
+
}
|
|
11910
|
+
/**
|
|
11911
|
+
* Evaluate display rules against a set of columns and return a map of `colId → winning rule`
|
|
11912
|
+
* (first-match-wins, preserving original rule order).
|
|
11913
|
+
*
|
|
11914
|
+
* Predicate-based rules (`ColumnMatcher`) are evaluated directly on the spec.
|
|
11915
|
+
* Selector-based rules (`ColumnSelector`) are matched via the
|
|
11916
|
+
* `columnsCollection` service — the inline column ids must be resolvable in
|
|
11917
|
+
* the active render ctx for the host to read their specs.
|
|
11918
|
+
*/
|
|
11919
|
+
function evaluateRules(rules, columns) {
|
|
11920
|
+
const result = /* @__PURE__ */ new Map();
|
|
11921
|
+
if (rules.length === 0 || columns.length === 0) return result;
|
|
11922
|
+
const selectorRules = rules.filter((rule) => typeof rule.match !== "function");
|
|
11923
|
+
const selectorHitsByRule = /* @__PURE__ */ new Map();
|
|
11924
|
+
if (selectorRules.length > 0) {
|
|
11925
|
+
const baseCollection = ColumnsCollection([{
|
|
11926
|
+
columns: uniqBy(columns, (col) => col.id),
|
|
11927
|
+
isFinal: true
|
|
11928
|
+
}]);
|
|
11929
|
+
for (const rule of selectorRules) {
|
|
11930
|
+
const hitIds = baseCollection.filter({ include: rule.match }).getColumnIds();
|
|
11931
|
+
if (hitIds.length === 0) return result;
|
|
11932
|
+
selectorHitsByRule.set(rule, new Set(hitIds.map((id) => extractPObjectId(id))));
|
|
11933
|
+
}
|
|
11934
|
+
}
|
|
11935
|
+
for (const col of columns) {
|
|
11936
|
+
const colKey = extractPObjectId(col.id);
|
|
11937
|
+
for (const rule of rules) if (selectorHitsByRule.get(rule)?.has(colKey) ?? false) {
|
|
11938
|
+
result.set(colKey, rule);
|
|
11939
|
+
break;
|
|
8990
11940
|
}
|
|
8991
11941
|
}
|
|
8992
|
-
return
|
|
11942
|
+
return result;
|
|
11943
|
+
}
|
|
11944
|
+
/**
|
|
11945
|
+
* Build a sidecar map `columnId → AnnotationDataStatus` derived from each
|
|
11946
|
+
* recipe's own status. This is *rendering* metadata — kept out of the spec
|
|
11947
|
+
* so it cannot perturb column identity (id-bearing spec overrides would
|
|
11948
|
+
* diverge the visible PTable's column ids from the full table / pframe).
|
|
11949
|
+
*
|
|
11950
|
+
* Mapping `ColumnFieldStatus` × actual byte-presence → `AnnotationDataStatus`:
|
|
11951
|
+
* - `absent` → `"absent"`
|
|
11952
|
+
* - `resolving` → `"computing"`
|
|
11953
|
+
* - `present` + `hasColumnData()` → `"ready"`
|
|
11954
|
+
* - `present` + no bytes yet → `"computing"`
|
|
11955
|
+
*
|
|
11956
|
+
* Intentionally scoped to visible columns — the probe is meaningful only for
|
|
11957
|
+
* what the user will actually see.
|
|
11958
|
+
*/
|
|
11959
|
+
function buildDataStatusMap(columns, opts = {}) {
|
|
11960
|
+
return columns.reduce((acc, c) => (acc[c.id] = deriveDataStatus(c, opts), acc), {});
|
|
11961
|
+
}
|
|
11962
|
+
function deriveDataStatus(column, opts) {
|
|
11963
|
+
const field = column.getDataStatus();
|
|
11964
|
+
if (field === "absent") return "absent";
|
|
11965
|
+
if (field === "resolving") return "computing";
|
|
11966
|
+
return hasColumnData(column, opts) ? "ready" : "computing";
|
|
11967
|
+
}
|
|
11968
|
+
/** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */
|
|
11969
|
+
function deriveAllLabels(options) {
|
|
11970
|
+
const { columns, deriveLabelsOptions } = options;
|
|
11971
|
+
return deriveDistinctLabels(columns.map((c) => ({
|
|
11972
|
+
spec: c.spec,
|
|
11973
|
+
linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
|
|
11974
|
+
qualifications: c.qualifications
|
|
11975
|
+
})), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
|
|
8993
11976
|
}
|
|
8994
11977
|
//#endregion
|
|
8995
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
11978
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
|
|
11979
|
+
/**
|
|
11980
|
+
* Assemble a ptable def directly from recipes. Each secondary recipe is its own
|
|
11981
|
+
* outer-joined subtree: `getQuery()` encodes its linker chain, and its
|
|
11982
|
+
* hit-/queries-qualifications are derived on the spot via {@link hitQualifications}
|
|
11983
|
+
* / {@link queriesQualifications} — no pre-extracted DTO. Bare leaves yield empty
|
|
11984
|
+
* qualifications, so plain {@link ColumnRecipe} arrays (e.g. label columns) work
|
|
11985
|
+
* unchanged.
|
|
11986
|
+
*/
|
|
8996
11987
|
function createPTableDefV3(params) {
|
|
8997
11988
|
let query = {
|
|
8998
11989
|
type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
|
|
8999
|
-
entries: params.primary.map((
|
|
11990
|
+
entries: params.primary.map((c) => columnToJoinEntry(c, []))
|
|
9000
11991
|
};
|
|
9001
11992
|
if (params.secondary.length > 0) query = {
|
|
9002
11993
|
type: "outerJoin",
|
|
9003
11994
|
primary: {
|
|
9004
11995
|
entry: query,
|
|
9005
|
-
qualifications: params.secondary.flatMap((
|
|
11996
|
+
qualifications: params.secondary.flatMap((s) => {
|
|
11997
|
+
const quals = queriesQualifications(s);
|
|
11998
|
+
return params.primary.flatMap((p) => quals[p.id] ?? []);
|
|
11999
|
+
})
|
|
9006
12000
|
},
|
|
9007
|
-
secondary: params.secondary.
|
|
12001
|
+
secondary: params.secondary.map((c) => columnToJoinEntry(c, hitQualifications(c)))
|
|
9008
12002
|
};
|
|
9009
12003
|
if (!isNil(params.filters)) {
|
|
9010
12004
|
const nonEmpty = distillFilterSpec(params.filters);
|
|
@@ -9024,7 +12018,7 @@ function createPTableDefV3(params) {
|
|
|
9024
12018
|
sortBy: params.sorting.map((s) => ({
|
|
9025
12019
|
expression: columnIdToExpr(s.column),
|
|
9026
12020
|
ascending: s.ascending,
|
|
9027
|
-
nullsFirst:
|
|
12021
|
+
nullsFirst: s.naAndAbsentAreLeastValues
|
|
9028
12022
|
}))
|
|
9029
12023
|
};
|
|
9030
12024
|
return { query };
|
|
@@ -9038,153 +12032,392 @@ function columnIdToExpr(col) {
|
|
|
9038
12032
|
value: col.id
|
|
9039
12033
|
};
|
|
9040
12034
|
}
|
|
9041
|
-
function
|
|
12035
|
+
function columnToJoinEntry(col, qualifications) {
|
|
9042
12036
|
return {
|
|
9043
|
-
entry:
|
|
9044
|
-
|
|
9045
|
-
column: col
|
|
9046
|
-
},
|
|
9047
|
-
qualifications: qs
|
|
12037
|
+
entry: col.getQuery(),
|
|
12038
|
+
qualifications
|
|
9048
12039
|
};
|
|
9049
12040
|
}
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
12041
|
+
//#endregion
|
|
12042
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
|
|
12043
|
+
function createColumnResolver(columns, deps) {
|
|
12044
|
+
const axisIds = [];
|
|
12045
|
+
for (const c of columns) for (const ax of c.getSpec().axesSpec) axisIds.push(getAxisId(ax));
|
|
12046
|
+
const byFullId = /* @__PURE__ */ new Map();
|
|
12047
|
+
const byPObjectId = /* @__PURE__ */ new Map();
|
|
12048
|
+
for (const c of columns) {
|
|
12049
|
+
byFullId.set(c.id, c);
|
|
12050
|
+
const pid = extractPObjectId(c.id);
|
|
12051
|
+
const existing = byPObjectId.get(pid);
|
|
12052
|
+
if (existing === void 0) byPObjectId.set(pid, c);
|
|
12053
|
+
else if (existing.id !== c.id) deps?.warn?.(`Ambiguous PObjectId ${pid}: recipe ids ${existing.id} and ${c.id} both match — keeping first.`);
|
|
12054
|
+
}
|
|
12055
|
+
return (ref) => {
|
|
12056
|
+
if (ref.type === "axis") return axisIds.some((a) => matchAxisId(ref.id, a)) ? ref : void 0;
|
|
12057
|
+
const hit = byFullId.get(ref.id) ?? byPObjectId.get(extractPObjectId(ref.id));
|
|
12058
|
+
if (hit === void 0) return void 0;
|
|
12059
|
+
return {
|
|
12060
|
+
type: "column",
|
|
12061
|
+
id: hit.id
|
|
12062
|
+
};
|
|
9063
12063
|
};
|
|
9064
12064
|
}
|
|
9065
12065
|
//#endregion
|
|
9066
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
12066
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
|
|
12067
|
+
/**
|
|
12068
|
+
* Discover columns from sources/anchors and split them into primary
|
|
12069
|
+
* (direct anchor hits — zero-hop, query is a bare column) and secondary
|
|
12070
|
+
* (reached via a linker chain, query carries a join).
|
|
12071
|
+
*/
|
|
12072
|
+
function discoverTableColumns(ctx, options) {
|
|
12073
|
+
const discoveredColumns = ColumnsCollection(options.sources, { ctx: ctx.ctx }).discover({
|
|
12074
|
+
...options.selector,
|
|
12075
|
+
anchors: options.anchors
|
|
12076
|
+
}).getColumns();
|
|
12077
|
+
const primary = [];
|
|
12078
|
+
const secondary = [];
|
|
12079
|
+
for (const col of discoveredColumns) if (isLeafColumn(col)) primary.push(col);
|
|
12080
|
+
else secondary.push(col);
|
|
12081
|
+
return {
|
|
12082
|
+
primary,
|
|
12083
|
+
secondary
|
|
12084
|
+
};
|
|
9083
12085
|
}
|
|
9084
|
-
//#endregion
|
|
9085
|
-
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.79.27/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js
|
|
9086
12086
|
/**
|
|
9087
|
-
*
|
|
12087
|
+
* Discover label columns matching the axes of the given value columns from
|
|
12088
|
+
* ctx providers. Returns a list of label {@link ColumnRecipe}s.
|
|
9088
12089
|
*
|
|
9089
|
-
*
|
|
9090
|
-
*
|
|
9091
|
-
* @param columns column list
|
|
9092
|
-
* @param tableState table ui state
|
|
9093
|
-
* @returns PlAgDataTableV2 table source
|
|
12090
|
+
* Primary columns are used as anchors for axis-aware label discovery.
|
|
12091
|
+
* `maxHops` is taken from the longest linker chain present in `columns`.
|
|
9094
12092
|
*/
|
|
9095
|
-
function
|
|
9096
|
-
if (columns.length === 0) return
|
|
9097
|
-
const
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
12093
|
+
function discoverLabelColumns(ctx, primary, columns) {
|
|
12094
|
+
if (columns.length === 0) return [];
|
|
12095
|
+
const axes = columns.flatMap((col) => col.getSpec().axesSpec);
|
|
12096
|
+
return ColumnsCollection(void 0, { ctx: ctx.ctx }).discover({
|
|
12097
|
+
include: axes.map((a) => ({
|
|
12098
|
+
name: {
|
|
12099
|
+
type: "exact",
|
|
12100
|
+
value: PColumnName.Label
|
|
12101
|
+
},
|
|
12102
|
+
axes: [{ name: {
|
|
12103
|
+
type: "exact",
|
|
12104
|
+
value: a.name
|
|
12105
|
+
} }]
|
|
12106
|
+
})),
|
|
12107
|
+
anchors: Object.fromEntries(primary.map((col, i) => [`anchor_${i}`, col.getSpec()])),
|
|
12108
|
+
maxHops: columns.reduce((acc, c) => Math.max(acc, collectLinkerIds(c).length), 0)
|
|
12109
|
+
}).getColumns();
|
|
12110
|
+
}
|
|
12111
|
+
//#endregion
|
|
12112
|
+
//#region ../node_modules/.pnpm/@platforma-sdk+model@1.80.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
|
|
12113
|
+
function createPlDataTableV3(ctx, options) {
|
|
12114
|
+
const state = upgradePlDataTableStateV2(options.tableState);
|
|
12115
|
+
const primaryJoinType = options.primaryJoinType ?? "full";
|
|
12116
|
+
const resolved = resolveInputColumns(ctx, options);
|
|
12117
|
+
if (resolved === void 0) return void 0;
|
|
12118
|
+
const { primary, secondary } = resolved;
|
|
12119
|
+
if (primary.length === 0) return void 0;
|
|
12120
|
+
const { direct, linked } = splitByTopology(secondary);
|
|
12121
|
+
const derivedLabels = deriveAllLabels({
|
|
12122
|
+
columns: [...primary, ...secondary].filter((c) => !isColumnHidden(c.getSpec())).map(toLabelableColumn),
|
|
12123
|
+
deriveLabelsOptions: {
|
|
12124
|
+
includeNativeLabel: true,
|
|
12125
|
+
...options.labelsOptions
|
|
12126
|
+
}
|
|
9111
12127
|
});
|
|
9112
|
-
const
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
const
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
const
|
|
9127
|
-
|
|
9128
|
-
const
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
const coreJoinType = options?.coreJoinType ?? "full";
|
|
9133
|
-
const fullDef = createPTableDefV2({
|
|
9134
|
-
columns,
|
|
9135
|
-
labelColumns: fullLabelColumns,
|
|
9136
|
-
coreJoinType,
|
|
12128
|
+
const allColumnsForRules = [
|
|
12129
|
+
...primary,
|
|
12130
|
+
...direct,
|
|
12131
|
+
...linked,
|
|
12132
|
+
...collectLinkerSnapshots(linked)
|
|
12133
|
+
];
|
|
12134
|
+
const visibilityByColId = evaluateRules(options.displayOptions?.visibility ?? [], allColumnsForRules);
|
|
12135
|
+
const orderByColId = evaluateRules(options.displayOptions?.ordering ?? [], allColumnsForRules);
|
|
12136
|
+
const resolver = createColumnResolver([
|
|
12137
|
+
...primary,
|
|
12138
|
+
...direct,
|
|
12139
|
+
...linked.flatMap((lc) => [...collectLinkerColumns(lc), lc])
|
|
12140
|
+
], { warn: ctx.logWarn.bind(ctx) });
|
|
12141
|
+
const remapedDefaultFilters = remapFilterColumnIds(options.filters, resolver);
|
|
12142
|
+
const filters = filterFilters(concatFilters(state.pTableParams.filters, state.pTableParams.defaultFilters ?? remapedDefaultFilters), resolver);
|
|
12143
|
+
const sorting = filterSorting(resolveSorting(state.pTableParams.sorting, remapSortingColumnIds(options.sorting, resolver)), resolver);
|
|
12144
|
+
const fullDef = createPTableDefV3({
|
|
12145
|
+
primaryJoinType,
|
|
12146
|
+
primary,
|
|
12147
|
+
secondary: [...direct, ...linked],
|
|
9137
12148
|
filters,
|
|
9138
|
-
sorting
|
|
9139
|
-
coreColumnPredicate: options?.coreColumnPredicate
|
|
12149
|
+
sorting
|
|
9140
12150
|
});
|
|
9141
12151
|
const fullHandle = ctx.createPTableV2(fullDef);
|
|
9142
|
-
const pframeHandle = ctx.createPFrame(
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
const obj = parseJson(c);
|
|
9156
|
-
return obj.type === "column" ? [obj.id] : [];
|
|
9157
|
-
}).forEach((c) => hiddenColumns.delete(c));
|
|
9158
|
-
const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));
|
|
9159
|
-
const visibleLabelColumns = getMatchingLabelColumns(visibleColumns.map(getColumnIdAndSpec), allLabelColumns);
|
|
9160
|
-
if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return void 0;
|
|
9161
|
-
const visibleDef = createPTableDefV2({
|
|
9162
|
-
columns: visibleColumns,
|
|
9163
|
-
labelColumns: visibleLabelColumns,
|
|
9164
|
-
coreJoinType,
|
|
9165
|
-
filters,
|
|
12152
|
+
const pframeHandle = ctx.createPFrame(uniq([
|
|
12153
|
+
...primary.map((v) => extractPObjectId(v.id)),
|
|
12154
|
+
...direct.map((v) => extractPObjectId(v.id)),
|
|
12155
|
+
...linked.map((v) => extractPObjectId(v.id))
|
|
12156
|
+
]));
|
|
12157
|
+
const hiddenSpecs = state.pTableParams.hiddenColIds;
|
|
12158
|
+
const hiddenColumnIds = computeHiddenColumns({
|
|
12159
|
+
columns: [
|
|
12160
|
+
...primary,
|
|
12161
|
+
...direct,
|
|
12162
|
+
...linked
|
|
12163
|
+
],
|
|
12164
|
+
visibilityByColId,
|
|
9166
12165
|
sorting,
|
|
9167
|
-
|
|
12166
|
+
filters,
|
|
12167
|
+
hiddenSpecs
|
|
12168
|
+
});
|
|
12169
|
+
const visible = {
|
|
12170
|
+
primary,
|
|
12171
|
+
direct: direct.filter((c) => !hiddenColumnIds.has(c.id)),
|
|
12172
|
+
linked: linked.filter((c) => !hiddenColumnIds.has(c.id))
|
|
12173
|
+
};
|
|
12174
|
+
const visibleDef = createPTableDefV3({
|
|
12175
|
+
primaryJoinType,
|
|
12176
|
+
primary,
|
|
12177
|
+
secondary: [...visible.direct, ...visible.linked],
|
|
12178
|
+
filters,
|
|
12179
|
+
sorting
|
|
9168
12180
|
});
|
|
9169
12181
|
const visibleHandle = ctx.createPTableV2(visibleDef);
|
|
9170
|
-
|
|
12182
|
+
const columnsMeta = buildColumnsMeta({
|
|
12183
|
+
fullColumns: [
|
|
12184
|
+
...primary,
|
|
12185
|
+
...direct,
|
|
12186
|
+
...linked
|
|
12187
|
+
],
|
|
12188
|
+
visibleColumns: [
|
|
12189
|
+
...visible.primary,
|
|
12190
|
+
...visible.direct,
|
|
12191
|
+
...visible.linked
|
|
12192
|
+
],
|
|
12193
|
+
primaryColumns: primary,
|
|
12194
|
+
derivedLabels,
|
|
12195
|
+
visibilityByColId,
|
|
12196
|
+
orderByColId
|
|
12197
|
+
});
|
|
9171
12198
|
return {
|
|
9172
|
-
sourceId:
|
|
12199
|
+
sourceId: state.pTableParams.sourceId,
|
|
9173
12200
|
fullTableHandle: fullHandle,
|
|
9174
12201
|
fullPframeHandle: pframeHandle,
|
|
9175
12202
|
visibleTableHandle: visibleHandle,
|
|
9176
|
-
defaultFilters
|
|
12203
|
+
defaultFilters: remapedDefaultFilters,
|
|
12204
|
+
columnsMeta
|
|
9177
12205
|
};
|
|
9178
12206
|
}
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
12207
|
+
/** Normalize either option branch into a {primary, secondary} pair of recipes. */
|
|
12208
|
+
function resolveInputColumns(ctx, options) {
|
|
12209
|
+
if ("primaryColumns" in options) {
|
|
12210
|
+
const primary = options.primaryColumns;
|
|
12211
|
+
const secondary = options.columns ?? [];
|
|
12212
|
+
const labels = discoverLabelColumns(ctx, primary, [...primary, ...secondary]);
|
|
12213
|
+
const primaryIds = new Set(primary.map((c) => c.id));
|
|
12214
|
+
return {
|
|
12215
|
+
primary,
|
|
12216
|
+
secondary: dedupColumns([...secondary, ...labels].filter((c) => !primaryIds.has(c.id)), (c) => c.id, (c) => c.getSpec())
|
|
12217
|
+
};
|
|
12218
|
+
}
|
|
12219
|
+
if (isPlainObject(options.columns)) return discoverTableColumns(ctx, options.columns);
|
|
12220
|
+
}
|
|
12221
|
+
/** Split secondary recipes by query topology: leaves (no linker chain) vs joined. */
|
|
12222
|
+
function splitByTopology(columns) {
|
|
12223
|
+
const direct = [];
|
|
12224
|
+
const linked = [];
|
|
12225
|
+
for (const c of columns) if (isLeafColumn(c)) direct.push(c);
|
|
12226
|
+
else linked.push(c);
|
|
12227
|
+
return {
|
|
12228
|
+
direct,
|
|
12229
|
+
linked
|
|
12230
|
+
};
|
|
12231
|
+
}
|
|
12232
|
+
/** All linker recipes across the given linked columns, deduped by id. */
|
|
12233
|
+
function collectLinkerSnapshots(linked) {
|
|
12234
|
+
return uniqueBy(linked.flatMap((c) => collectLinkerColumns(c)), (c) => c.id);
|
|
12235
|
+
}
|
|
12236
|
+
function toLabelableColumn(col) {
|
|
12237
|
+
return {
|
|
12238
|
+
id: col.id,
|
|
12239
|
+
spec: col.getSpec(),
|
|
12240
|
+
linkerPath: collectLinkerColumns(col).map((linker) => ({ linker: { spec: linker.getSpec() } })),
|
|
12241
|
+
qualifications: {
|
|
12242
|
+
forHit: [...hitQualifications(col)],
|
|
12243
|
+
forQueries: queriesQualifications(col)
|
|
12244
|
+
}
|
|
12245
|
+
};
|
|
12246
|
+
}
|
|
12247
|
+
/**
|
|
12248
|
+
* Compute display metadata as a sidecar keyed by each emitted column's
|
|
12249
|
+
* `ColumnUniversalId` (and axis `AxisId`), instead of baking it into the specs
|
|
12250
|
+
* via `withSpecs`. Spec overrides change a recipe's id, so the same physical
|
|
12251
|
+
* column reached two ways would diverge into two ids and render twice; keeping
|
|
12252
|
+
* meta out of the spec preserves identity and lets dedup collapse such cases.
|
|
12253
|
+
* The UI overlays this onto the engine-emitted specs at render time.
|
|
12254
|
+
*/
|
|
12255
|
+
function buildColumnsMeta(params) {
|
|
12256
|
+
const { fullColumns, visibleColumns, primaryColumns, derivedLabels } = params;
|
|
12257
|
+
const { visibilityByColId, orderByColId } = params;
|
|
12258
|
+
const visibleStatus = buildDataStatusMap(visibleColumns);
|
|
12259
|
+
const columns = fullColumns.reduce((acc, c) => {
|
|
12260
|
+
const rc = toRuleColumn(c);
|
|
12261
|
+
acc[c.id] = {
|
|
12262
|
+
label: derivedLabels[c.id],
|
|
12263
|
+
visibility: getEffectiveVisibility(rc, visibilityByColId),
|
|
12264
|
+
order: getOrderPriority(rc, orderByColId),
|
|
12265
|
+
status: visibleStatus[c.id]
|
|
12266
|
+
};
|
|
12267
|
+
return acc;
|
|
12268
|
+
}, {});
|
|
12269
|
+
const primaryAxisKeys = new Set(primaryColumns.flatMap((c) => c.getSpec().axesSpec.map((a) => canonicalizeAxisId(a))));
|
|
12270
|
+
return {
|
|
12271
|
+
columns,
|
|
12272
|
+
axes: fullColumns.reduce((acc, c) => c.getSpec().axesSpec.reduce((inner, ax) => {
|
|
12273
|
+
const key = canonicalizeAxisId(ax);
|
|
12274
|
+
if (inner[key] === void 0) inner[key] = { hidden: !primaryAxisKeys.has(key) };
|
|
12275
|
+
return inner;
|
|
12276
|
+
}, acc), {})
|
|
12277
|
+
};
|
|
12278
|
+
}
|
|
12279
|
+
/** Drop filter leaves whose column references cannot be resolved; rewrite the
|
|
12280
|
+
* resolvable ones through the resolver. Prune empty and/or/not groups. */
|
|
12281
|
+
function filterFilters(filters, resolver) {
|
|
12282
|
+
if (isNil$1(filters)) return filters;
|
|
12283
|
+
const rewriteLeaf = (leaf) => {
|
|
12284
|
+
if (leaf.type === void 0) return leaf;
|
|
12285
|
+
const result = { ...leaf };
|
|
12286
|
+
if ("column" in result) {
|
|
12287
|
+
const c = resolver(result.column);
|
|
12288
|
+
if (isNil$1(c)) return void 0;
|
|
12289
|
+
result.column = c;
|
|
12290
|
+
}
|
|
12291
|
+
if ("rhs" in result) {
|
|
12292
|
+
const c = resolver(result.rhs);
|
|
12293
|
+
if (isNil$1(c)) return void 0;
|
|
12294
|
+
result.rhs = c;
|
|
12295
|
+
}
|
|
12296
|
+
return result;
|
|
12297
|
+
};
|
|
12298
|
+
const prune = (node) => {
|
|
12299
|
+
if (node.type === "and" || node.type === "or") {
|
|
12300
|
+
const kept = node.filters.map((f) => prune(f)).filter((f) => !isNil$1(f));
|
|
12301
|
+
if (kept.length === 0) return void 0;
|
|
12302
|
+
return {
|
|
12303
|
+
type: node.type,
|
|
12304
|
+
filters: kept
|
|
12305
|
+
};
|
|
12306
|
+
}
|
|
12307
|
+
if (node.type === "not") {
|
|
12308
|
+
const inner = prune(node.filter);
|
|
12309
|
+
return isNil$1(inner) ? void 0 : {
|
|
12310
|
+
type: "not",
|
|
12311
|
+
filter: inner
|
|
12312
|
+
};
|
|
12313
|
+
}
|
|
12314
|
+
return rewriteLeaf(node);
|
|
12315
|
+
};
|
|
12316
|
+
return prune(filters);
|
|
12317
|
+
}
|
|
12318
|
+
/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */
|
|
12319
|
+
function concatFilters(a, b) {
|
|
12320
|
+
if (isNil$1(a)) return b;
|
|
12321
|
+
if (isNil$1(b)) return a;
|
|
12322
|
+
return {
|
|
12323
|
+
...a,
|
|
12324
|
+
filters: [...a.filters, ...b.filters]
|
|
12325
|
+
};
|
|
12326
|
+
}
|
|
12327
|
+
/** Pick user sorting from state if set, otherwise fall back to options default.
|
|
12328
|
+
* null = user has not touched sorting → use default;
|
|
12329
|
+
* [] = user has explicitly cleared sorting → no sorting (default ignored). */
|
|
12330
|
+
function resolveSorting(userSorting, defaultSorting) {
|
|
12331
|
+
return (isNil$1(userSorting) ? defaultSorting : userSorting) ?? [];
|
|
12332
|
+
}
|
|
12333
|
+
/** Rewrite sorting entries through the resolver; drop those that fail to resolve. */
|
|
12334
|
+
function filterSorting(sorting, resolver) {
|
|
12335
|
+
return sorting.flatMap((s) => {
|
|
12336
|
+
const col = resolver(s.column);
|
|
12337
|
+
return isNil$1(col) ? [] : [{
|
|
12338
|
+
...s,
|
|
12339
|
+
column: col
|
|
12340
|
+
}];
|
|
9186
12341
|
});
|
|
9187
12342
|
}
|
|
12343
|
+
/** Determine which columns should be hidden based on state or optional-column defaults.
|
|
12344
|
+
* Keyed by the recipe's logical {@link ColumnUniversalId} (rich) — variants of
|
|
12345
|
+
* the same physical column are independently visible/hidden. */
|
|
12346
|
+
function computeHiddenColumns(params) {
|
|
12347
|
+
const { columns, visibilityByColId, sorting, filters, hiddenSpecs } = params;
|
|
12348
|
+
const visibilityOf = (c) => getEffectiveVisibility(toRuleColumn(c), visibilityByColId);
|
|
12349
|
+
const alwaysHidden = columns.filter((c) => visibilityOf(c) === "hidden").map((c) => c.id);
|
|
12350
|
+
const optionalHidden = !isNil$1(hiddenSpecs) ? hiddenSpecs.filter((s) => s.type === "column").map((s) => s.id) : columns.filter((c) => visibilityOf(c) === "optional").map((c) => c.id);
|
|
12351
|
+
const initial = [...alwaysHidden, ...optionalHidden];
|
|
12352
|
+
const preserved = collectPreservedColumnIds(sorting, filters);
|
|
12353
|
+
return new Set(initial.filter((id) => !preserved.has(id)));
|
|
12354
|
+
}
|
|
12355
|
+
/** Collect IDs of columns that must remain visible (sorted, filtered). */
|
|
12356
|
+
function collectPreservedColumnIds(sorting, filters) {
|
|
12357
|
+
const sortedIds = (sorting ?? []).map((s) => s.column).filter((c) => c.type === "column").map((c) => c.id);
|
|
12358
|
+
const filterIds = !isNil$1(filters) ? collectFilterSpecColumns(filters).flatMap((c) => c.type === "column" ? [c.id] : []) : [];
|
|
12359
|
+
return /* @__PURE__ */ new Set([...sortedIds, ...filterIds]);
|
|
12360
|
+
}
|
|
12361
|
+
/** Remap column references in sorting entries through the resolver.
|
|
12362
|
+
* Unresolved entries are dropped with a warning (best-effort contract). */
|
|
12363
|
+
function remapSortingColumnIds(sorting, resolver) {
|
|
12364
|
+
return sorting?.flatMap((s) => {
|
|
12365
|
+
const col = resolver(s.column);
|
|
12366
|
+
if (isNil$1(col)) {
|
|
12367
|
+
console.warn(`Sorting column ${JSON.stringify(s.column)} does not match any discovered column — dropped.`);
|
|
12368
|
+
return [];
|
|
12369
|
+
}
|
|
12370
|
+
return [{
|
|
12371
|
+
...s,
|
|
12372
|
+
column: col
|
|
12373
|
+
}];
|
|
12374
|
+
});
|
|
12375
|
+
}
|
|
12376
|
+
/** Remap column references in a filter tree through the resolver.
|
|
12377
|
+
* Unresolved leaves are dropped with a warning; empty groups are pruned. */
|
|
12378
|
+
function remapFilterColumnIds(filters, resolver) {
|
|
12379
|
+
if (isNil$1(filters)) return filters;
|
|
12380
|
+
const mapLeaf = (leaf) => {
|
|
12381
|
+
if (leaf.type === void 0) return leaf;
|
|
12382
|
+
const result = { ...leaf };
|
|
12383
|
+
if ("column" in result) {
|
|
12384
|
+
const c = resolver(result.column);
|
|
12385
|
+
if (isNil$1(c)) {
|
|
12386
|
+
console.warn(`Filter column ${JSON.stringify(result.column)} does not match any discovered column — dropped.`);
|
|
12387
|
+
return;
|
|
12388
|
+
}
|
|
12389
|
+
result.column = c;
|
|
12390
|
+
}
|
|
12391
|
+
if ("rhs" in result) {
|
|
12392
|
+
const c = resolver(result.rhs);
|
|
12393
|
+
if (isNil$1(c)) {
|
|
12394
|
+
console.warn(`Filter rhs ${JSON.stringify(result.rhs)} does not match any discovered column — dropped.`);
|
|
12395
|
+
return;
|
|
12396
|
+
}
|
|
12397
|
+
result.rhs = c;
|
|
12398
|
+
}
|
|
12399
|
+
return result;
|
|
12400
|
+
};
|
|
12401
|
+
const prune = (node) => {
|
|
12402
|
+
if (node.type === "and" || node.type === "or") {
|
|
12403
|
+
const kept = node.filters.map((f) => prune(f)).filter((f) => !isNil$1(f));
|
|
12404
|
+
if (kept.length === 0) return void 0;
|
|
12405
|
+
return {
|
|
12406
|
+
type: node.type,
|
|
12407
|
+
filters: kept
|
|
12408
|
+
};
|
|
12409
|
+
}
|
|
12410
|
+
if (node.type === "not") {
|
|
12411
|
+
const inner = prune(node.filter);
|
|
12412
|
+
return isNil$1(inner) ? void 0 : {
|
|
12413
|
+
type: "not",
|
|
12414
|
+
filter: inner
|
|
12415
|
+
};
|
|
12416
|
+
}
|
|
12417
|
+
return mapLeaf(node);
|
|
12418
|
+
};
|
|
12419
|
+
return prune(filters);
|
|
12420
|
+
}
|
|
9188
12421
|
(/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
9189
12422
|
exports = module.exports = stringify;
|
|
9190
12423
|
exports.getSerialize = serializer;
|
|
@@ -9254,8 +12487,8 @@ const StopCodonReplacements = objectType({
|
|
|
9254
12487
|
opal: stringType().optional()
|
|
9255
12488
|
}).optional();
|
|
9256
12489
|
const BlockArgsValidBase = objectType({
|
|
9257
|
-
defaultBlockLabel: stringType(),
|
|
9258
|
-
customBlockLabel: stringType(),
|
|
12490
|
+
defaultBlockLabel: stringType().optional(),
|
|
12491
|
+
customBlockLabel: stringType().optional(),
|
|
9259
12492
|
input: PlRef,
|
|
9260
12493
|
inputLibrary: PlRef.optional(),
|
|
9261
12494
|
libraryFile: stringType().transform((v) => v).optional(),
|
|
@@ -9544,9 +12777,8 @@ const platforma$1 = BlockModelV3.create(dataModel).prerunArgs((data) => ({
|
|
|
9544
12777
|
}).output("started", (ctx) => ctx.outputs !== void 0).output("done", (ctx) => {
|
|
9545
12778
|
return ctx.outputs !== void 0 ? parseResourceMap(ctx.outputs?.resolve("clns"), (_acc) => true, false).data.map((e) => e.key[0]) : void 0;
|
|
9546
12779
|
}).outputWithStatus("clones", (ctx) => {
|
|
9547
|
-
const
|
|
9548
|
-
if (
|
|
9549
|
-
const pColumns = Object.values(collection).filter(isPColumn);
|
|
12780
|
+
const pColumns = ctx.outputs?.resolve("clonotypes")?.getPColumns();
|
|
12781
|
+
if (pColumns === void 0) return void 0;
|
|
9550
12782
|
return ctx.createPFrame(pColumns);
|
|
9551
12783
|
}).retentiveOutput("inputOptions", (ctx) => {
|
|
9552
12784
|
return ctx.resultPool.getOptions((v) => {
|
|
@@ -9585,8 +12817,12 @@ const platforma$1 = BlockModelV3.create(dataModel).prerunArgs((data) => ({
|
|
|
9585
12817
|
assertFieldType: "Input",
|
|
9586
12818
|
allowPermanentAbsence: true
|
|
9587
12819
|
})?.getPColumns();
|
|
9588
|
-
if (pCols === void 0) return;
|
|
9589
|
-
return
|
|
12820
|
+
if (pCols === void 0 || pCols.length === 0) return;
|
|
12821
|
+
return createPlDataTableV3(ctx, {
|
|
12822
|
+
primaryColumns: [ColumnLazy.fromColumn(pCols[0])],
|
|
12823
|
+
columns: pCols.slice(1).map((c) => ColumnLazy.fromColumn(c)),
|
|
12824
|
+
tableState: ctx.data.tableState
|
|
12825
|
+
});
|
|
9590
12826
|
}).output("rawTsvs", (ctx) => {
|
|
9591
12827
|
if (ctx.outputs === void 0) return void 0;
|
|
9592
12828
|
const pCols = ctx.outputs?.resolve("clonotypeTables")?.getPColumns();
|