@platforma-sdk/model 1.61.0 → 1.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/block_model.cjs +19 -10
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +22 -5
- package/dist/block_model.js +18 -10
- package/dist/block_model.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +26 -14
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +9 -8
- package/dist/columns/column_collection_builder.js +26 -14
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +93 -89
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +93 -89
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +4 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/platforma.d.ts +9 -3
- package/dist/plugin_handle.cjs.map +1 -1
- package/dist/plugin_handle.d.ts +13 -7
- package/dist/plugin_handle.js.map +1 -1
- package/dist/plugin_model.cjs +84 -12
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +121 -41
- package/dist/plugin_model.js +84 -12
- package/dist/plugin_model.js.map +1 -1
- package/dist/render/api.cjs +17 -31
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +12 -18
- package/dist/render/api.js +17 -31
- package/dist/render/api.js.map +1 -1
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +3 -14
- package/dist/render/internal.js.map +1 -1
- package/dist/services/block_services.cjs +18 -0
- package/dist/services/block_services.cjs.map +1 -0
- package/dist/services/block_services.d.ts +18 -0
- package/dist/services/block_services.js +16 -0
- package/dist/services/block_services.js.map +1 -0
- package/dist/services/index.cjs +2 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +2 -0
- package/dist/services/service_bridge.cjs +35 -0
- package/dist/services/service_bridge.cjs.map +1 -0
- package/dist/services/service_bridge.d.ts +18 -0
- package/dist/services/service_bridge.js +33 -0
- package/dist/services/service_bridge.js.map +1 -0
- package/dist/services/service_resolve.d.ts +13 -0
- package/package.json +6 -6
- package/src/block_model.ts +49 -14
- package/src/columns/column_collection_builder.test.ts +23 -2
- package/src/columns/column_collection_builder.ts +38 -30
- package/src/columns/ctx_column_sources.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +159 -153
- package/src/components/PlDataTable/createPlDataTable/index.ts +5 -4
- package/src/index.ts +2 -0
- package/src/platforma.ts +14 -2
- package/src/plugin_handle.ts +24 -6
- package/src/plugin_model.ts +321 -82
- package/src/render/api.ts +55 -57
- package/src/render/internal.ts +3 -38
- package/src/services/block_services.ts +17 -0
- package/src/services/index.ts +3 -0
- package/src/services/service_bridge.ts +71 -0
- package/src/services/service_resolve.ts +71 -0
package/src/block_model.ts
CHANGED
|
@@ -6,9 +6,12 @@ import type {
|
|
|
6
6
|
BlockCodeKnownFeatureFlags,
|
|
7
7
|
BlockConfigContainer,
|
|
8
8
|
} from "@milaboratories/pl-model-common";
|
|
9
|
+
import { resolveRequiredServices } from "@milaboratories/pl-model-common";
|
|
9
10
|
import { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from "./internal";
|
|
10
11
|
import type { DataModel } from "./block_migrations";
|
|
11
12
|
import type { PlatformaV3 } from "./platforma";
|
|
13
|
+
import type { BlockDefaultUiServices } from "./services/service_resolve";
|
|
14
|
+
import { blockServiceNames, BLOCK_SERVICE_FLAGS } from "./services/block_services";
|
|
12
15
|
import type { InferRenderFunctionReturn, RenderFunction } from "./render";
|
|
13
16
|
import { BlockRenderCtx, PluginRenderCtx } from "./render";
|
|
14
17
|
import type { PluginData, PluginModel, PluginOutputs, PluginParams } from "./plugin_model";
|
|
@@ -87,8 +90,10 @@ export type PluginRecord<
|
|
|
87
90
|
Data extends PluginData = PluginData,
|
|
88
91
|
Params extends PluginParams = undefined,
|
|
89
92
|
Outputs extends PluginOutputs = PluginOutputs,
|
|
93
|
+
ModelServices = unknown,
|
|
94
|
+
UiServices = unknown,
|
|
90
95
|
> = {
|
|
91
|
-
readonly model: PluginModel<Data, Params, Outputs>;
|
|
96
|
+
readonly model: PluginModel<Data, Params, Outputs, ModelServices, UiServices>;
|
|
92
97
|
readonly inputs: ParamsInputErased;
|
|
93
98
|
};
|
|
94
99
|
|
|
@@ -128,13 +133,17 @@ export class BlockModelV3<
|
|
|
128
133
|
private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins, Transfers>,
|
|
129
134
|
) {}
|
|
130
135
|
|
|
131
|
-
public static readonly
|
|
136
|
+
public static readonly FEATURE_FLAGS = {
|
|
132
137
|
supportsLazyState: true,
|
|
133
138
|
supportsPframeQueryRanking: true,
|
|
134
139
|
requiresUIAPIVersion: 3,
|
|
135
140
|
requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,
|
|
136
141
|
requiresCreatePTable: 2,
|
|
137
|
-
|
|
142
|
+
...BLOCK_SERVICE_FLAGS,
|
|
143
|
+
} satisfies BlockCodeKnownFeatureFlags;
|
|
144
|
+
|
|
145
|
+
/** @deprecated Use FEATURE_FLAGS */
|
|
146
|
+
public static readonly INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;
|
|
138
147
|
|
|
139
148
|
/**
|
|
140
149
|
* Creates a new BlockModelV3 builder with the specified data model.
|
|
@@ -164,7 +173,7 @@ export class BlockModelV3<
|
|
|
164
173
|
subtitle: undefined,
|
|
165
174
|
tags: undefined,
|
|
166
175
|
enrichmentTargets: undefined,
|
|
167
|
-
featureFlags: { ...BlockModelV3.
|
|
176
|
+
featureFlags: { ...BlockModelV3.FEATURE_FLAGS },
|
|
168
177
|
argsFunction: undefined,
|
|
169
178
|
prerunArgsFunction: undefined,
|
|
170
179
|
plugins: {},
|
|
@@ -228,7 +237,7 @@ export class BlockModelV3<
|
|
|
228
237
|
...this.config.outputs,
|
|
229
238
|
[key]: createAndRegisterRenderLambda({
|
|
230
239
|
handle: `block-output#${key}`,
|
|
231
|
-
lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>()),
|
|
240
|
+
lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>(blockServiceNames)),
|
|
232
241
|
...flags,
|
|
233
242
|
}),
|
|
234
243
|
},
|
|
@@ -324,7 +333,10 @@ export class BlockModelV3<
|
|
|
324
333
|
...this.config,
|
|
325
334
|
// Replace the default sections callback with the user-provided one
|
|
326
335
|
sections: createAndRegisterRenderLambda(
|
|
327
|
-
{
|
|
336
|
+
{
|
|
337
|
+
handle: "sections",
|
|
338
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),
|
|
339
|
+
},
|
|
328
340
|
true,
|
|
329
341
|
),
|
|
330
342
|
},
|
|
@@ -339,7 +351,7 @@ export class BlockModelV3<
|
|
|
339
351
|
...this.config,
|
|
340
352
|
title: createAndRegisterRenderLambda({
|
|
341
353
|
handle: "title",
|
|
342
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
354
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),
|
|
343
355
|
}),
|
|
344
356
|
});
|
|
345
357
|
}
|
|
@@ -351,7 +363,7 @@ export class BlockModelV3<
|
|
|
351
363
|
...this.config,
|
|
352
364
|
subtitle: createAndRegisterRenderLambda({
|
|
353
365
|
handle: "subtitle",
|
|
354
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
366
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),
|
|
355
367
|
}),
|
|
356
368
|
});
|
|
357
369
|
}
|
|
@@ -363,7 +375,7 @@ export class BlockModelV3<
|
|
|
363
375
|
...this.config,
|
|
364
376
|
tags: createAndRegisterRenderLambda({
|
|
365
377
|
handle: "tags",
|
|
366
|
-
lambda: () => rf(new BlockRenderCtx<Args, Data>()),
|
|
378
|
+
lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),
|
|
367
379
|
}),
|
|
368
380
|
});
|
|
369
381
|
}
|
|
@@ -418,6 +430,8 @@ export class BlockModelV3<
|
|
|
418
430
|
PParams extends PluginParams,
|
|
419
431
|
POutputs extends PluginOutputs,
|
|
420
432
|
PTransferData,
|
|
433
|
+
PluginModelServices,
|
|
434
|
+
PluginUiServices,
|
|
421
435
|
>(
|
|
422
436
|
instance: PluginInstanceClass<
|
|
423
437
|
PluginId &
|
|
@@ -432,7 +446,9 @@ export class BlockModelV3<
|
|
|
432
446
|
PData,
|
|
433
447
|
PParams,
|
|
434
448
|
POutputs,
|
|
435
|
-
PTransferData
|
|
449
|
+
PTransferData,
|
|
450
|
+
PluginModelServices,
|
|
451
|
+
PluginUiServices
|
|
436
452
|
>,
|
|
437
453
|
params?: ParamsInput<PParams, Args, Data>,
|
|
438
454
|
): BlockModelV3<
|
|
@@ -440,7 +456,15 @@ export class BlockModelV3<
|
|
|
440
456
|
OutputsCfg,
|
|
441
457
|
Data,
|
|
442
458
|
Href,
|
|
443
|
-
Plugins & {
|
|
459
|
+
Plugins & {
|
|
460
|
+
[K in PluginId]: PluginRecord<
|
|
461
|
+
PData,
|
|
462
|
+
PParams,
|
|
463
|
+
POutputs,
|
|
464
|
+
PluginModelServices,
|
|
465
|
+
PluginUiServices
|
|
466
|
+
>;
|
|
467
|
+
},
|
|
444
468
|
Omit<Transfers, PluginId>
|
|
445
469
|
>;
|
|
446
470
|
public plugin(
|
|
@@ -489,7 +513,14 @@ export class BlockModelV3<
|
|
|
489
513
|
public done(
|
|
490
514
|
..._: keyof Transfers extends never ? [] : [never]
|
|
491
515
|
): PlatformaExtended<
|
|
492
|
-
PlatformaV3<
|
|
516
|
+
PlatformaV3<
|
|
517
|
+
Data,
|
|
518
|
+
Args,
|
|
519
|
+
InferOutputsFromLambdas<OutputsCfg>,
|
|
520
|
+
Href,
|
|
521
|
+
Plugins,
|
|
522
|
+
BlockDefaultUiServices
|
|
523
|
+
>
|
|
493
524
|
> {
|
|
494
525
|
if (this.config.argsFunction === undefined) throw new Error("Args rendering function not set.");
|
|
495
526
|
|
|
@@ -505,6 +536,8 @@ export class BlockModelV3<
|
|
|
505
536
|
|
|
506
537
|
const { dataModel, argsFunction, prerunArgsFunction } = this.config;
|
|
507
538
|
|
|
539
|
+
const mergedServiceNames = resolveRequiredServices(this.config.featureFlags);
|
|
540
|
+
|
|
508
541
|
function getPlugin(handle: PluginHandle): PluginRecord {
|
|
509
542
|
const plugin = plugins[handle];
|
|
510
543
|
if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);
|
|
@@ -544,16 +577,18 @@ export class BlockModelV3<
|
|
|
544
577
|
// Wrap plugin param lambdas: close over BlockRenderCtx creation
|
|
545
578
|
const wrappedInputs: Record<string, () => unknown> = {};
|
|
546
579
|
for (const [paramKey, paramFn] of Object.entries(inputs)) {
|
|
547
|
-
wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());
|
|
580
|
+
wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx(mergedServiceNames));
|
|
548
581
|
}
|
|
549
582
|
|
|
550
583
|
// Register plugin outputs (in config pack, evaluated by middle layer)
|
|
551
584
|
const outputs = model.outputs as Record<string, (ctx: PluginRenderCtx) => unknown>;
|
|
585
|
+
const { outputFlags } = model;
|
|
552
586
|
for (const [outputKey, outputFn] of Object.entries(outputs)) {
|
|
553
587
|
const key = pluginOutputKey(handle, outputKey);
|
|
554
588
|
pluginOutputs[key] = createAndRegisterRenderLambda({
|
|
555
589
|
handle: key,
|
|
556
|
-
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),
|
|
590
|
+
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs, mergedServiceNames)),
|
|
591
|
+
withStatus: outputFlags[outputKey]?.withStatus,
|
|
557
592
|
});
|
|
558
593
|
}
|
|
559
594
|
}
|
|
@@ -20,8 +20,8 @@ function createSpecFrameCtx() {
|
|
|
20
20
|
return driver;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
for (const driver of drivers) driver.dispose();
|
|
23
|
+
afterEach(async () => {
|
|
24
|
+
for (const driver of drivers) await driver.dispose();
|
|
25
25
|
drivers.length = 0;
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -166,6 +166,27 @@ describe("ColumnCollection.findColumns", () => {
|
|
|
166
166
|
expect(results).toHaveLength(1);
|
|
167
167
|
expect(results[0].spec.name).toBe("col2");
|
|
168
168
|
});
|
|
169
|
+
|
|
170
|
+
test("include filters by exact name among disjoint-axis columns", () => {
|
|
171
|
+
const vdjAxis = sampleAxis("pl7.app/vdj/clonotypeKey");
|
|
172
|
+
const itemAxis = sampleAxis("item");
|
|
173
|
+
|
|
174
|
+
const vdjColumns = Array.from({ length: 10 }, (_, i) =>
|
|
175
|
+
createSnapshot(`vdj${i}`, createSpec(`pl7.app/vdj/col${i}`, { axesSpec: [vdjAxis] })),
|
|
176
|
+
);
|
|
177
|
+
const mockScore = createSnapshot("mock", createSpec("mock_score", { axesSpec: [itemAxis] }));
|
|
178
|
+
|
|
179
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
180
|
+
builder.addSource([...vdjColumns, mockScore]);
|
|
181
|
+
|
|
182
|
+
const collection = builder.build()!;
|
|
183
|
+
const results = collection.findColumns({
|
|
184
|
+
include: [{ name: [{ type: "exact", value: "mock_score" }] }],
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(results).toHaveLength(1);
|
|
188
|
+
expect(results[0].spec.name).toBe("mock_score");
|
|
189
|
+
});
|
|
169
190
|
});
|
|
170
191
|
|
|
171
192
|
describe("dedup by native ID", () => {
|
|
@@ -19,13 +19,7 @@ import { createColumnSnapshot } from "./column_snapshot";
|
|
|
19
19
|
import type { ColumnSnapshotProvider, ColumnSource } from "./column_snapshot_provider";
|
|
20
20
|
import { ArrayColumnProvider, toColumnSnapshotProvider } from "./column_snapshot_provider";
|
|
21
21
|
|
|
22
|
-
import type {
|
|
23
|
-
|
|
24
|
-
/** Subset of render context methods needed for spec frame operations. */
|
|
25
|
-
type SpecFrameCtx = Pick<
|
|
26
|
-
GlobalCfgRenderCtxMethods,
|
|
27
|
-
"createSpecFrame" | "specFrameDiscoverColumns" | "disposeSpecFrame"
|
|
28
|
-
>;
|
|
22
|
+
import type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from "@milaboratories/pl-model-common";
|
|
29
23
|
|
|
30
24
|
// --- FindColumnsOptions ---
|
|
31
25
|
|
|
@@ -40,7 +34,9 @@ export interface FindColumnsOptions {
|
|
|
40
34
|
// --- ColumnCollection ---
|
|
41
35
|
|
|
42
36
|
/** Plain collection — no axis context, selector-based filtering only. */
|
|
43
|
-
export interface ColumnCollection {
|
|
37
|
+
export interface ColumnCollection extends Disposable {
|
|
38
|
+
/** Release the underlying spec frame WASM resource. */
|
|
39
|
+
dispose(): void;
|
|
44
40
|
/** Point lookup by provider-native ID. */
|
|
45
41
|
getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;
|
|
46
42
|
|
|
@@ -53,7 +49,9 @@ export interface ColumnCollection {
|
|
|
53
49
|
// --- AnchoredColumnCollection ---
|
|
54
50
|
|
|
55
51
|
/** Axis-aware column collection with anchored identity derivation. */
|
|
56
|
-
export interface AnchoredColumnCollection {
|
|
52
|
+
export interface AnchoredColumnCollection extends Disposable {
|
|
53
|
+
/** Release the underlying spec frame WASM resource. */
|
|
54
|
+
dispose(): void;
|
|
57
55
|
/** Point lookup by anchored ID. */
|
|
58
56
|
getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;
|
|
59
57
|
|
|
@@ -122,7 +120,7 @@ export interface AnchoredBuildOptions extends BuildOptions {
|
|
|
122
120
|
export class ColumnCollectionBuilder {
|
|
123
121
|
private readonly providers: ColumnSnapshotProvider[] = [];
|
|
124
122
|
|
|
125
|
-
constructor(private readonly
|
|
123
|
+
constructor(private readonly specDriver: PFrameSpecDriver) {}
|
|
126
124
|
|
|
127
125
|
/**
|
|
128
126
|
* Register a column source. Sources added first take precedence for dedup.
|
|
@@ -178,14 +176,14 @@ export class ColumnCollectionBuilder {
|
|
|
178
176
|
const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);
|
|
179
177
|
const idDeriver = new AnchoredIdDeriver(anchorSpecs);
|
|
180
178
|
|
|
181
|
-
return new AnchoredColumnCollectionImpl(this.
|
|
179
|
+
return new AnchoredColumnCollectionImpl(this.specDriver, {
|
|
182
180
|
columns: columnMap,
|
|
183
181
|
idDeriver,
|
|
184
182
|
anchorSpecs,
|
|
185
183
|
columnListComplete: allowPartial ? allComplete : false,
|
|
186
184
|
});
|
|
187
185
|
} else {
|
|
188
|
-
return new ColumnCollectionImpl(this.
|
|
186
|
+
return new ColumnCollectionImpl(this.specDriver, {
|
|
189
187
|
columns: columnMap,
|
|
190
188
|
columnListComplete: allowPartial ? allComplete : false,
|
|
191
189
|
});
|
|
@@ -230,25 +228,30 @@ interface ColumnCollectionImplOptions {
|
|
|
230
228
|
readonly columnListComplete?: boolean;
|
|
231
229
|
}
|
|
232
230
|
|
|
233
|
-
class ColumnCollectionImpl implements ColumnCollection {
|
|
231
|
+
class ColumnCollectionImpl implements ColumnCollection, Disposable {
|
|
234
232
|
private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;
|
|
235
|
-
private readonly
|
|
233
|
+
private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;
|
|
236
234
|
public readonly columnListComplete: boolean;
|
|
237
235
|
|
|
238
236
|
constructor(
|
|
239
|
-
private readonly
|
|
237
|
+
private readonly specDriver: PFrameSpecDriver,
|
|
240
238
|
options: ColumnCollectionImplOptions,
|
|
241
239
|
) {
|
|
242
240
|
this.columns = options.columns;
|
|
243
241
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
244
|
-
this.
|
|
245
|
-
Array.from(this.columns.entries()).
|
|
246
|
-
(acc, [id, col]) => ((acc[id] = col.spec), acc),
|
|
247
|
-
{} as Record<string, PColumnSpec>,
|
|
248
|
-
),
|
|
242
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(
|
|
243
|
+
Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),
|
|
249
244
|
);
|
|
250
245
|
}
|
|
251
246
|
|
|
247
|
+
dispose(): void {
|
|
248
|
+
this.specFrameEntry.unref();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
[Symbol.dispose](): void {
|
|
252
|
+
this.dispose();
|
|
253
|
+
}
|
|
254
|
+
|
|
252
255
|
getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {
|
|
253
256
|
const col = this.columns.get(id);
|
|
254
257
|
if (col === undefined) return undefined;
|
|
@@ -259,7 +262,7 @@ class ColumnCollectionImpl implements ColumnCollection {
|
|
|
259
262
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;
|
|
260
263
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;
|
|
261
264
|
|
|
262
|
-
const response = this.
|
|
265
|
+
const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
263
266
|
includeColumns,
|
|
264
267
|
excludeColumns,
|
|
265
268
|
axes: [],
|
|
@@ -288,17 +291,17 @@ interface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOption
|
|
|
288
291
|
readonly anchorSpecs: Record<string, PColumnSpec>;
|
|
289
292
|
}
|
|
290
293
|
|
|
291
|
-
class AnchoredColumnCollectionImpl implements AnchoredColumnCollection {
|
|
294
|
+
class AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {
|
|
292
295
|
private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;
|
|
293
296
|
private readonly idDeriver: AnchoredIdDeriver;
|
|
294
|
-
private readonly
|
|
297
|
+
private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;
|
|
295
298
|
private readonly anchorAxes: ColumnAxesWithQualifications[];
|
|
296
299
|
/** Reverse lookup: SUniversalPColumnId → PObjectId */
|
|
297
300
|
private readonly idToOriginal: Map<SUniversalPColumnId, PObjectId>;
|
|
298
301
|
public readonly columnListComplete: boolean;
|
|
299
302
|
|
|
300
303
|
constructor(
|
|
301
|
-
private readonly
|
|
304
|
+
private readonly specDriver: PFrameSpecDriver,
|
|
302
305
|
options: AnchoredColumnCollectionImplOptions,
|
|
303
306
|
) {
|
|
304
307
|
this.columns = options.columns;
|
|
@@ -306,11 +309,8 @@ class AnchoredColumnCollectionImpl implements AnchoredColumnCollection {
|
|
|
306
309
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
307
310
|
|
|
308
311
|
// Create spec frame from all collected columns
|
|
309
|
-
this.
|
|
310
|
-
Array.from(this.columns.entries()).
|
|
311
|
-
(acc, [id, col]) => ((acc[id] = col.spec), acc),
|
|
312
|
-
{} as Record<string, PColumnSpec>,
|
|
313
|
-
),
|
|
312
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(
|
|
313
|
+
Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),
|
|
314
314
|
);
|
|
315
315
|
|
|
316
316
|
// Build anchor axes for discovery requests
|
|
@@ -327,6 +327,14 @@ class AnchoredColumnCollectionImpl implements AnchoredColumnCollection {
|
|
|
327
327
|
);
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
dispose(): void {
|
|
331
|
+
this.specFrameEntry.unref();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
[Symbol.dispose](): void {
|
|
335
|
+
this.dispose();
|
|
336
|
+
}
|
|
337
|
+
|
|
330
338
|
getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {
|
|
331
339
|
const origId = this.idToOriginal.get(id);
|
|
332
340
|
if (origId === undefined) return undefined;
|
|
@@ -341,7 +349,7 @@ class AnchoredColumnCollectionImpl implements AnchoredColumnCollection {
|
|
|
341
349
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;
|
|
342
350
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;
|
|
343
351
|
|
|
344
|
-
const response = this.
|
|
352
|
+
const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
345
353
|
includeColumns,
|
|
346
354
|
excludeColumns,
|
|
347
355
|
constraints,
|
|
@@ -17,8 +17,8 @@ import type { ValueOf } from "@milaboratories/helpers";
|
|
|
17
17
|
*
|
|
18
18
|
* Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.
|
|
19
19
|
*/
|
|
20
|
-
export function collectCtxColumnSnapshotProviders<A, U>(
|
|
21
|
-
ctx: RenderCtxBase<A, U>,
|
|
20
|
+
export function collectCtxColumnSnapshotProviders<A, U, S>(
|
|
21
|
+
ctx: RenderCtxBase<A, U, S>,
|
|
22
22
|
): ColumnSnapshotProvider[] {
|
|
23
23
|
const providers: ColumnSnapshotProvider[] = [];
|
|
24
24
|
|