@platforma-sdk/model 1.61.1 → 1.63.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 +17 -10
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +22 -5
- package/dist/block_model.js +16 -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/components/PlMultiSequenceAlignment.cjs +1 -1
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.js +2 -2
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts +1 -1
- package/dist/components/PlSelectionModel.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/pframe_utils/index.cjs +2 -5
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.js +2 -5
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts +8 -4
- 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 +37 -11
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +80 -39
- package/dist/plugin_model.js +37 -11
- package/dist/plugin_model.js.map +1 -1
- package/dist/render/api.cjs +13 -24
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +11 -14
- package/dist/render/api.js +13 -24
- 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 +9 -9
- package/src/block_model.ts +47 -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/components/PlMultiSequenceAlignment.ts +1 -2
- package/src/components/PlSelectionModel.ts +1 -1
- package/src/index.ts +1 -0
- package/src/pframe_utils/index.ts +2 -6
- package/src/platforma.ts +14 -2
- package/src/plugin_handle.ts +24 -6
- package/src/plugin_model.ts +252 -84
- package/src/render/api.ts +50 -51
- 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
|
@@ -41,6 +41,7 @@ import type { PlDataTableFilters, PlDataTableModel } from "../typesV5";
|
|
|
41
41
|
import { upgradePlDataTableStateV2 } from "../state-migration";
|
|
42
42
|
import type { PlDataTableStateV2 } from "../state-migration";
|
|
43
43
|
import type { ColumnSource, MatchingMode } from "../../../columns";
|
|
44
|
+
import { Services, type RequireServices } from "@milaboratories/pl-model-common";
|
|
44
45
|
import { ColumnCollectionBuilder } from "../../../columns";
|
|
45
46
|
import { isColumnSnapshotProvider } from "../../../columns/column_snapshot_provider";
|
|
46
47
|
import { collectCtxColumnSnapshotProviders } from "../../../columns/ctx_column_sources";
|
|
@@ -184,8 +185,8 @@ export type createPlDataTableOptionsV3 = {
|
|
|
184
185
|
// | { annotation: Record<string, string> }
|
|
185
186
|
// | { ids: Set<string> };
|
|
186
187
|
|
|
187
|
-
export function createPlDataTableV3<A, U
|
|
188
|
-
ctx: RenderCtxBase<A, U>,
|
|
188
|
+
export function createPlDataTableV3<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(
|
|
189
|
+
ctx: RenderCtxBase<A, U, S>,
|
|
189
190
|
options: createPlDataTableOptionsV3,
|
|
190
191
|
): PlDataTableModel | undefined {
|
|
191
192
|
const providers = options.source
|
|
@@ -195,170 +196,175 @@ export function createPlDataTableV3<A, U>(
|
|
|
195
196
|
if (providers.length === 0) return undefined;
|
|
196
197
|
|
|
197
198
|
// Step 1: Build collection from sources
|
|
198
|
-
const builder = new ColumnCollectionBuilder(ctx).addSources(providers);
|
|
199
|
+
const builder = new ColumnCollectionBuilder(ctx.services.pframeSpec).addSources(providers);
|
|
199
200
|
const anchors = options.columns.anchors;
|
|
200
201
|
const collection = isNil(anchors) ? builder.build() : builder.build({ anchors });
|
|
201
202
|
|
|
202
203
|
if (!collection) return undefined;
|
|
204
|
+
try {
|
|
205
|
+
// Step 2: Get data columns, excluding annotation-hidden ones
|
|
206
|
+
const findOptions = options.columns
|
|
207
|
+
? {
|
|
208
|
+
include: options.columns.include,
|
|
209
|
+
exclude: options.columns.exclude,
|
|
210
|
+
mode: options.columns.mode,
|
|
211
|
+
maxHops: options.columns.maxHops,
|
|
212
|
+
}
|
|
213
|
+
: undefined;
|
|
214
|
+
const findResult = collection.findColumns(findOptions);
|
|
215
|
+
const snapshots = findResult.map((v) => ("column" in v ? v.column : v));
|
|
216
|
+
const dataSnapshots = snapshots.filter((s) => !isColumnHidden(s.spec));
|
|
217
|
+
if (dataSnapshots.length === 0) return undefined;
|
|
218
|
+
|
|
219
|
+
// Convert snapshots to PColumn<PColumnDataUniversal>[]
|
|
220
|
+
const columns: PColumn<PColumnDataUniversal>[] = [];
|
|
221
|
+
for (const snap of dataSnapshots) {
|
|
222
|
+
if (!snap.data) return undefined;
|
|
223
|
+
const data = snap.data.get();
|
|
224
|
+
if (data === undefined) return undefined;
|
|
225
|
+
columns.push({ id: snap.id, spec: snap.spec, data });
|
|
226
|
+
}
|
|
203
227
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
maxHops: options.columns.maxHops,
|
|
211
|
-
}
|
|
212
|
-
: undefined;
|
|
213
|
-
const findResult = collection.findColumns(findOptions);
|
|
214
|
-
const snapshots = findResult.map((v) => ("column" in v ? v.column : v));
|
|
215
|
-
const dataSnapshots = snapshots.filter((s) => !isColumnHidden(s.spec));
|
|
216
|
-
if (dataSnapshots.length === 0) return undefined;
|
|
217
|
-
|
|
218
|
-
// Convert snapshots to PColumn<PColumnDataUniversal>[]
|
|
219
|
-
const columns: PColumn<PColumnDataUniversal>[] = [];
|
|
220
|
-
for (const snap of dataSnapshots) {
|
|
221
|
-
if (!snap.data) return undefined;
|
|
222
|
-
const data = snap.data.get();
|
|
223
|
-
if (data === undefined) return undefined;
|
|
224
|
-
columns.push({ id: snap.id, spec: snap.spec, data });
|
|
225
|
-
}
|
|
228
|
+
// Step 3: Normalize table state
|
|
229
|
+
const tableStateNormalized = upgradePlDataTableStateV2(options.state);
|
|
230
|
+
|
|
231
|
+
// Step 4: Get label columns from result pool and match to data columns
|
|
232
|
+
const allLabelColumns = getAllLabelColumns(ctx.resultPool);
|
|
233
|
+
if (!allLabelColumns) return undefined;
|
|
226
234
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// Step 4: Get label columns from result pool and match to data columns
|
|
231
|
-
const allLabelColumns = getAllLabelColumns(ctx.resultPool);
|
|
232
|
-
if (!allLabelColumns) return undefined;
|
|
233
|
-
|
|
234
|
-
const fullLabelColumns = getMatchingLabelColumns(
|
|
235
|
-
columns.map(getColumnIdAndSpec),
|
|
236
|
-
allLabelColumns,
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
const fullColumns = [...columns, ...fullLabelColumns];
|
|
240
|
-
|
|
241
|
-
// Step 5: Build column ID set for filter/sorting validation
|
|
242
|
-
const fullColumnsAxes = uniqueBy(
|
|
243
|
-
fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),
|
|
244
|
-
(a) => canonicalizeJson<AxisId>(a),
|
|
245
|
-
);
|
|
246
|
-
const fullColumnsIds: PTableColumnId[] = [
|
|
247
|
-
...fullColumnsAxes.map((a) => ({ type: "axis", id: a }) satisfies PTableColumnIdAxis),
|
|
248
|
-
...fullColumns.map((c) => ({ type: "column", id: c.id }) satisfies PTableColumnIdColumn),
|
|
249
|
-
];
|
|
250
|
-
const fullColumnsIdsSet = new Set(fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)));
|
|
251
|
-
const isValidColumnId = (id: string): boolean =>
|
|
252
|
-
fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);
|
|
253
|
-
|
|
254
|
-
// Step 6: Filtering validation
|
|
255
|
-
const stateFilters = tableStateNormalized.pTableParams.filters;
|
|
256
|
-
const opsFilters = options?.filters ?? null;
|
|
257
|
-
const filters: null | PlDataTableFilters =
|
|
258
|
-
stateFilters != null && opsFilters != null
|
|
259
|
-
? { type: "and", filters: [stateFilters, opsFilters] }
|
|
260
|
-
: (stateFilters ?? opsFilters);
|
|
261
|
-
const filterColumns = filters ? collectFilterSpecColumns(filters) : [];
|
|
262
|
-
const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));
|
|
263
|
-
if (firstInvalidFilterColumn)
|
|
264
|
-
throw new Error(
|
|
265
|
-
`Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,
|
|
235
|
+
const fullLabelColumns = getMatchingLabelColumns(
|
|
236
|
+
columns.map(getColumnIdAndSpec),
|
|
237
|
+
allLabelColumns,
|
|
266
238
|
);
|
|
267
239
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
240
|
+
const fullColumns = [...columns, ...fullLabelColumns];
|
|
241
|
+
|
|
242
|
+
// Step 5: Build column ID set for filter/sorting validation
|
|
243
|
+
const fullColumnsAxes = uniqueBy(
|
|
244
|
+
fullColumns.flatMap((c) => c.spec.axesSpec.map((a) => getAxisId(a))),
|
|
245
|
+
(a) => canonicalizeJson<AxisId>(a),
|
|
246
|
+
);
|
|
247
|
+
const fullColumnsIds: PTableColumnId[] = [
|
|
248
|
+
...fullColumnsAxes.map((a) => ({ type: "axis", id: a }) satisfies PTableColumnIdAxis),
|
|
249
|
+
...fullColumns.map((c) => ({ type: "column", id: c.id }) satisfies PTableColumnIdColumn),
|
|
250
|
+
];
|
|
251
|
+
const fullColumnsIdsSet = new Set(
|
|
252
|
+
fullColumnsIds.map((c) => canonicalizeJson<PTableColumnId>(c)),
|
|
253
|
+
);
|
|
254
|
+
const isValidColumnId = (id: string): boolean =>
|
|
255
|
+
fullColumnsIdsSet.has(id as CanonicalizedJson<PTableColumnId>);
|
|
256
|
+
|
|
257
|
+
// Step 6: Filtering validation
|
|
258
|
+
const stateFilters = tableStateNormalized.pTableParams.filters;
|
|
259
|
+
const opsFilters = options?.filters ?? null;
|
|
260
|
+
const filters: null | PlDataTableFilters =
|
|
261
|
+
stateFilters != null && opsFilters != null
|
|
262
|
+
? { type: "and", filters: [stateFilters, opsFilters] }
|
|
263
|
+
: (stateFilters ?? opsFilters);
|
|
264
|
+
const filterColumns = filters ? collectFilterSpecColumns(filters) : [];
|
|
265
|
+
const firstInvalidFilterColumn = filterColumns.find((col) => !isValidColumnId(col));
|
|
266
|
+
if (firstInvalidFilterColumn)
|
|
267
|
+
throw new Error(
|
|
268
|
+
`Invalid filter column ${firstInvalidFilterColumn}: column reference does not match the table columns`,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
// Step 7: Sorting validation
|
|
272
|
+
const userSorting = tableStateNormalized.pTableParams.sorting;
|
|
273
|
+
const sorting = (isEmpty(userSorting) ? options?.sorting : userSorting) ?? [];
|
|
274
|
+
const firstInvalidSortingColumn = sorting.find(
|
|
275
|
+
(s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),
|
|
276
|
+
);
|
|
277
|
+
if (firstInvalidSortingColumn)
|
|
278
|
+
throw new Error(
|
|
279
|
+
`Invalid sorting column ${JSON.stringify(firstInvalidSortingColumn.column)}: column reference does not match the table columns`,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
// Step 8: Build full table definition and handles
|
|
283
|
+
const coreJoinType = options?.coreJoinType ?? "full";
|
|
284
|
+
const fullDef = createPTableDef({
|
|
285
|
+
columns,
|
|
286
|
+
labelColumns: fullLabelColumns,
|
|
287
|
+
coreJoinType,
|
|
288
|
+
filters,
|
|
289
|
+
sorting,
|
|
290
|
+
coreColumnPredicate: options?.coreColumnPredicate,
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const fullHandle = ctx.createPTableV2(fullDef);
|
|
294
|
+
const pframeHandle = ctx.createPFrame(fullColumns);
|
|
295
|
+
if (!fullHandle || !pframeHandle) return undefined;
|
|
296
|
+
|
|
297
|
+
// Step 9: Determine hidden columns
|
|
298
|
+
const hiddenColumns = new Set<PObjectId>(
|
|
299
|
+
((): PObjectId[] => {
|
|
300
|
+
// Inner join works as a filter — all columns must be present
|
|
301
|
+
if (coreJoinType === "inner") return [];
|
|
302
|
+
|
|
303
|
+
const hiddenColIds = tableStateNormalized.pTableParams.hiddenColIds;
|
|
304
|
+
if (hiddenColIds) return hiddenColIds;
|
|
305
|
+
|
|
306
|
+
return columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);
|
|
307
|
+
})(),
|
|
277
308
|
);
|
|
278
309
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
columns
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (coreColumnPredicate) {
|
|
313
|
-
const coreColumns = columns.flatMap((c) =>
|
|
314
|
-
coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],
|
|
310
|
+
// Preserve linker columns
|
|
311
|
+
columns.filter((c) => isLinkerColumn(c.spec)).forEach((c) => hiddenColumns.delete(c.id));
|
|
312
|
+
|
|
313
|
+
// Preserve core columns as they change the shape of join
|
|
314
|
+
const coreColumnPredicate = options?.coreColumnPredicate;
|
|
315
|
+
if (coreColumnPredicate) {
|
|
316
|
+
const coreColumns = columns.flatMap((c) =>
|
|
317
|
+
coreColumnPredicate(getColumnIdAndSpec(c)) ? [c.id] : [],
|
|
318
|
+
);
|
|
319
|
+
coreColumns.forEach((c) => hiddenColumns.delete(c));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Preserve sorted columns from being hidden
|
|
323
|
+
sorting
|
|
324
|
+
.map((s) => s.column)
|
|
325
|
+
.filter((c): c is PTableColumnIdColumn => c.type === "column")
|
|
326
|
+
.forEach((c) => hiddenColumns.delete(c.id));
|
|
327
|
+
|
|
328
|
+
// Preserve filter columns from being hidden
|
|
329
|
+
if (filters) {
|
|
330
|
+
collectFilterSpecColumns(filters)
|
|
331
|
+
.flatMap((c) => {
|
|
332
|
+
const obj = parseJson(c);
|
|
333
|
+
return obj.type === "column" ? [obj.id] : [];
|
|
334
|
+
})
|
|
335
|
+
.forEach((c) => hiddenColumns.delete(c));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Step 10: Build visible table definition
|
|
339
|
+
const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));
|
|
340
|
+
const visibleLabelColumns = getMatchingLabelColumns(
|
|
341
|
+
visibleColumns.map(getColumnIdAndSpec),
|
|
342
|
+
allLabelColumns,
|
|
315
343
|
);
|
|
316
|
-
coreColumns.forEach((c) => hiddenColumns.delete(c));
|
|
317
|
-
}
|
|
318
344
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
345
|
+
if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;
|
|
346
|
+
|
|
347
|
+
const visibleDef = createPTableDef({
|
|
348
|
+
columns: visibleColumns,
|
|
349
|
+
labelColumns: visibleLabelColumns,
|
|
350
|
+
coreJoinType,
|
|
351
|
+
filters,
|
|
352
|
+
sorting,
|
|
353
|
+
coreColumnPredicate,
|
|
354
|
+
});
|
|
355
|
+
const visibleHandle = ctx.createPTableV2(visibleDef);
|
|
356
|
+
|
|
357
|
+
if (!visibleHandle) return undefined;
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
sourceId: tableStateNormalized.pTableParams.sourceId,
|
|
361
|
+
fullTableHandle: fullHandle,
|
|
362
|
+
fullPframeHandle: pframeHandle,
|
|
363
|
+
visibleTableHandle: visibleHandle,
|
|
364
|
+
} satisfies PlDataTableModel;
|
|
365
|
+
} finally {
|
|
366
|
+
collection.dispose();
|
|
333
367
|
}
|
|
334
|
-
|
|
335
|
-
// Step 10: Build visible table definition
|
|
336
|
-
const visibleColumns = columns.filter((c) => !hiddenColumns.has(c.id));
|
|
337
|
-
const visibleLabelColumns = getMatchingLabelColumns(
|
|
338
|
-
visibleColumns.map(getColumnIdAndSpec),
|
|
339
|
-
allLabelColumns,
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
if (!allPColumnsReady([...visibleColumns, ...visibleLabelColumns])) return undefined;
|
|
343
|
-
|
|
344
|
-
const visibleDef = createPTableDef({
|
|
345
|
-
columns: visibleColumns,
|
|
346
|
-
labelColumns: visibleLabelColumns,
|
|
347
|
-
coreJoinType,
|
|
348
|
-
filters,
|
|
349
|
-
sorting,
|
|
350
|
-
coreColumnPredicate,
|
|
351
|
-
});
|
|
352
|
-
const visibleHandle = ctx.createPTableV2(visibleDef);
|
|
353
|
-
|
|
354
|
-
if (!visibleHandle) return undefined;
|
|
355
|
-
|
|
356
|
-
return {
|
|
357
|
-
sourceId: tableStateNormalized.pTableParams.sourceId,
|
|
358
|
-
fullTableHandle: fullHandle,
|
|
359
|
-
fullPframeHandle: pframeHandle,
|
|
360
|
-
visibleTableHandle: visibleHandle,
|
|
361
|
-
} satisfies PlDataTableModel;
|
|
362
368
|
}
|
|
363
369
|
|
|
364
370
|
/** Normalize raw ColumnSource | ColumnSource[] into a flat list of sources. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Services, type RequireServices } from "@milaboratories/pl-model-common";
|
|
1
2
|
import type { RenderCtxBase } from "../../../render";
|
|
2
3
|
import type { PlDataTableModel } from "../typesV5";
|
|
3
4
|
import { createPlDataTableOptionsV2, createPlDataTableV2 } from "./createPlDataTableV2";
|
|
@@ -8,12 +9,12 @@ export function createPlDataTable<A, U>(
|
|
|
8
9
|
ctx: RenderCtxBase<A, U>,
|
|
9
10
|
options: { version: "v2" } & createPlDataTableOptionsV2,
|
|
10
11
|
): ReturnType<typeof createPlDataTableV2>;
|
|
11
|
-
export function createPlDataTable<A, U
|
|
12
|
-
ctx: RenderCtxBase<A, U>,
|
|
12
|
+
export function createPlDataTable<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(
|
|
13
|
+
ctx: RenderCtxBase<A, U, S>,
|
|
13
14
|
options: { version?: "v3" } & createPlDataTableOptionsV3,
|
|
14
15
|
): ReturnType<typeof createPlDataTableV3>;
|
|
15
|
-
export function createPlDataTable<A, U
|
|
16
|
-
ctx: RenderCtxBase<A, U>,
|
|
16
|
+
export function createPlDataTable<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(
|
|
17
|
+
ctx: RenderCtxBase<A, U, S>,
|
|
17
18
|
options:
|
|
18
19
|
| ({ version: "v2" } & createPlDataTableOptionsV2)
|
|
19
20
|
| ({ version?: "v3" } & createPlDataTableOptionsV3),
|
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
} from "@milaboratories/pl-model-common";
|
|
9
9
|
import {
|
|
10
10
|
Annotation,
|
|
11
|
-
isPTableAbsent,
|
|
12
11
|
PColumnName,
|
|
13
12
|
stringifyJson,
|
|
14
13
|
uniquePlId,
|
|
@@ -56,7 +55,7 @@ export function createRowSelectionColumn({
|
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
58
57
|
const data: PColumnValues = selection.selectedKeys
|
|
59
|
-
.filter((r): r is PColumnKey => r.every((v) =>
|
|
58
|
+
.filter((r): r is PColumnKey => r.every((v) => v !== null))
|
|
60
59
|
.map((r) => ({ key: r, val: 1 }));
|
|
61
60
|
if (!data.length) {
|
|
62
61
|
return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AxesSpec, PTableValueAxis } from "@milaboratories/pl-model-common";
|
|
2
2
|
|
|
3
3
|
/** Key is a set of all axes values, which means it is unique across rows */
|
|
4
|
-
export type PTableKey = PTableValueAxis[];
|
|
4
|
+
export type PTableKey = (PTableValueAxis | null)[];
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Information on selected rows.
|
package/src/index.ts
CHANGED
|
@@ -80,17 +80,13 @@ const UNIQUE_VALUES_LIMIT = 1000000;
|
|
|
80
80
|
const sortValuesPredicate = (a: { label: string }, b: { label: string }) =>
|
|
81
81
|
a.label.localeCompare(b.label, "en", { numeric: true });
|
|
82
82
|
|
|
83
|
-
function convertColumnData(
|
|
84
|
-
type: ValueType,
|
|
85
|
-
response: PTableVector,
|
|
86
|
-
absentValue: number | null = null,
|
|
87
|
-
): PValue[] {
|
|
83
|
+
function convertColumnData(type: ValueType, response: PTableVector): PValue[] {
|
|
88
84
|
if (type === "String") {
|
|
89
85
|
return response.data as PValue[];
|
|
90
86
|
}
|
|
91
87
|
const res: PValue[] = new Array(response.data.length);
|
|
92
88
|
for (let i = 0; i < response.data.length; i++) {
|
|
93
|
-
res[i] = pTableValue(response, i
|
|
89
|
+
res[i] = pTableValue(response, i) as PValue;
|
|
94
90
|
}
|
|
95
91
|
return res;
|
|
96
92
|
}
|
package/src/platforma.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
OutputWithStatus,
|
|
10
10
|
} from "@milaboratories/pl-model-common";
|
|
11
11
|
import type { SdkInfo } from "./version";
|
|
12
|
+
import type { ServiceDispatch, UiServices as AllUiServices } from "@milaboratories/pl-model-common";
|
|
12
13
|
import type { BlockStatePatch } from "./block_state_patch";
|
|
13
14
|
import type { PluginRecord } from "./block_model";
|
|
14
15
|
import type { PluginHandle, PluginFactoryLike } from "./plugin_handle";
|
|
@@ -54,13 +55,18 @@ export interface PlatformaV3<
|
|
|
54
55
|
>,
|
|
55
56
|
Href extends `/${string}` = `/${string}`,
|
|
56
57
|
Plugins extends Record<string, unknown> = Record<string, unknown>,
|
|
58
|
+
UiServices extends Partial<AllUiServices> = Partial<AllUiServices>,
|
|
57
59
|
>
|
|
58
60
|
extends BlockApiV3<Data, Args, Outputs, Href>, DriverKit {
|
|
59
61
|
/** Information about SDK version current platforma environment was compiled with. */
|
|
60
62
|
readonly sdkInfo: SdkInfo;
|
|
61
63
|
readonly apiVersion: 3;
|
|
64
|
+
/** Service dispatch — lists available services, their methods, and invokes them. */
|
|
65
|
+
readonly serviceDispatch: ServiceDispatch;
|
|
62
66
|
/** @internal Type brand for plugin type inference. Not used at runtime. */
|
|
63
67
|
readonly __pluginsBrand?: Plugins;
|
|
68
|
+
/** @internal Type brand for UI service type inference. Not used at runtime. */
|
|
69
|
+
readonly __uiServicesBrand?: UiServices;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
export type Platforma<
|
|
@@ -148,7 +154,13 @@ export type InferPluginData<Pl, PluginId extends string> =
|
|
|
148
154
|
* because PluginRecord doesn't carry Config (lost after factory.create()).
|
|
149
155
|
*/
|
|
150
156
|
export type InferPluginHandles<T extends Record<string, unknown>> = {
|
|
151
|
-
readonly [K in keyof T]: T[K] extends PluginRecord<
|
|
152
|
-
|
|
157
|
+
readonly [K in keyof T]: T[K] extends PluginRecord<
|
|
158
|
+
infer Data,
|
|
159
|
+
infer Params,
|
|
160
|
+
infer Outputs,
|
|
161
|
+
infer ModelServices,
|
|
162
|
+
infer UiServices
|
|
163
|
+
>
|
|
164
|
+
? { handle: PluginHandle<PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices>> }
|
|
153
165
|
: never;
|
|
154
166
|
};
|
package/src/plugin_handle.ts
CHANGED
|
@@ -23,37 +23,55 @@ export interface PluginFactoryLike<
|
|
|
23
23
|
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
24
24
|
Params extends undefined | Record<string, unknown> = undefined | Record<string, unknown>,
|
|
25
25
|
Outputs extends Record<string, unknown> = Record<string, unknown>,
|
|
26
|
+
ModelServices = unknown,
|
|
27
|
+
UiServices = unknown,
|
|
26
28
|
> {
|
|
27
29
|
readonly __types?: {
|
|
28
30
|
data: Data;
|
|
29
31
|
params: Params;
|
|
30
32
|
outputs: Outputs;
|
|
33
|
+
modelServices: ModelServices;
|
|
34
|
+
uiServices: UiServices;
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/** Extract the Data type from a PluginFactoryLike phantom. */
|
|
35
39
|
export type InferFactoryData<F extends PluginFactoryLike> = NonNullable<
|
|
36
|
-
F extends PluginFactoryLike<infer D, any, any> ? D : Record<string, unknown>
|
|
40
|
+
F extends PluginFactoryLike<infer D, any, any, any, any> ? D : Record<string, unknown>
|
|
37
41
|
>;
|
|
38
42
|
|
|
39
43
|
/** Extract the Params type from a PluginFactoryLike phantom. */
|
|
40
44
|
export type InferFactoryParams<F extends PluginFactoryLike> = NonNullable<
|
|
41
|
-
F extends PluginFactoryLike<any, infer P, any> ? P : undefined
|
|
45
|
+
F extends PluginFactoryLike<any, infer P, any, any, any> ? P : undefined
|
|
42
46
|
>;
|
|
43
47
|
|
|
44
48
|
/** Extract the Outputs type from a PluginFactoryLike phantom. */
|
|
45
49
|
export type InferFactoryOutputs<F extends PluginFactoryLike> = NonNullable<
|
|
46
|
-
F extends PluginFactoryLike<any, any, infer O> ? O : Record<string, unknown>
|
|
50
|
+
F extends PluginFactoryLike<any, any, infer O, any, any> ? O : Record<string, unknown>
|
|
47
51
|
>;
|
|
48
52
|
|
|
53
|
+
/** Extract the pre-resolved model services type from a PluginFactoryLike phantom. */
|
|
54
|
+
export type InferFactoryModelServices<F extends PluginFactoryLike> =
|
|
55
|
+
F extends PluginFactoryLike<any, any, any, infer ModelServices, any> ? ModelServices : {};
|
|
56
|
+
|
|
57
|
+
/** Extract the pre-resolved UI services type from a PluginFactoryLike phantom. */
|
|
58
|
+
export type InferFactoryUiServices<F extends PluginFactoryLike> =
|
|
59
|
+
F extends PluginFactoryLike<any, any, any, any, infer UiServices> ? UiServices : {};
|
|
60
|
+
|
|
49
61
|
/**
|
|
50
62
|
* Derive a typed PluginHandle from a PluginFactory type.
|
|
51
|
-
* Normalizes the brand to
|
|
63
|
+
* Normalizes the brand to data/params/outputs/services (strips config) so handles
|
|
52
64
|
* from InferPluginHandles match handles from InferPluginHandle.
|
|
53
65
|
*/
|
|
54
66
|
export type InferPluginHandle<F extends PluginFactoryLike> = NonNullable<
|
|
55
|
-
F extends PluginFactoryLike<
|
|
56
|
-
|
|
67
|
+
F extends PluginFactoryLike<
|
|
68
|
+
infer Data,
|
|
69
|
+
infer Params,
|
|
70
|
+
infer Outputs,
|
|
71
|
+
infer ModelServices,
|
|
72
|
+
infer UiServices
|
|
73
|
+
>
|
|
74
|
+
? PluginHandle<PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices>>
|
|
57
75
|
: PluginHandle
|
|
58
76
|
>;
|
|
59
77
|
|