@platforma-sdk/model 1.79.6 → 1.79.15

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.
@@ -2,8 +2,8 @@ require("../_virtual/_rolldown/runtime.cjs");
2
2
  const require_accessor = require("../render/accessor.cjs");
3
3
  const require_get_services = require("../services/get_services.cjs");
4
4
  require("../services/index.cjs");
5
- const require_column_selector = require("./column_selector.cjs");
6
5
  const require_column_snapshot_provider = require("./column_snapshot_provider.cjs");
6
+ const require_column_selector = require("./column_selector.cjs");
7
7
  let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
8
8
  let _milaboratories_helpers = require("@milaboratories/helpers");
9
9
  //#region src/columns/column_collection_builder.ts
@@ -1,8 +1,8 @@
1
1
  import { TreeNodeAccessor } from "../render/accessor.js";
2
2
  import { getService } from "../services/get_services.js";
3
3
  import "../services/index.js";
4
- import { convertColumnSelectorToMultiColumnSelector } from "./column_selector.js";
5
4
  import { ArrayColumnProvider, toColumnSnapshotProvider } from "./column_snapshot_provider.js";
5
+ import { convertColumnSelectorToMultiColumnSelector } from "./column_selector.js";
6
6
  import { deriveNativeId, isPColumnSpec } from "@milaboratories/pl-model-common";
7
7
  import { throwError } from "@milaboratories/helpers";
8
8
  //#region src/columns/column_collection_builder.ts
@@ -1,6 +1,6 @@
1
- require("./column_selector.cjs");
1
+ require("./column_snapshot.cjs");
2
2
  require("./column_snapshot_provider.cjs");
3
+ require("./column_selector.cjs");
3
4
  require("./column_collection_builder.cjs");
4
5
  require("./ctx_column_sources.cjs");
5
- require("./column_snapshot.cjs");
6
6
  require("./expand_by_partition.cjs");
@@ -1,6 +1,6 @@
1
- import "./column_selector.js";
1
+ import "./column_snapshot.js";
2
2
  import "./column_snapshot_provider.js";
3
+ import "./column_selector.js";
3
4
  import "./column_collection_builder.js";
4
5
  import "./ctx_column_sources.js";
5
- import "./column_snapshot.js";
6
6
  import "./expand_by_partition.js";
@@ -1,7 +1,7 @@
1
1
  require("../../_virtual/_rolldown/runtime.cjs");
2
- const require_filter_discovery = require("./filter_discovery.cjs");
3
2
  const require_column_collection_builder = require("../../columns/column_collection_builder.cjs");
4
3
  const require_ctx_column_sources = require("../../columns/ctx_column_sources.cjs");
4
+ const require_filter_discovery = require("./filter_discovery.cjs");
5
5
  const require_enrichment_discovery = require("./enrichment_discovery.cjs");
6
6
  let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
7
7
  //#region src/components/PlDatasetSelector/build_dataset_options.ts
@@ -1,6 +1,6 @@
1
- import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
2
1
  import { ColumnCollectionBuilder } from "../../columns/column_collection_builder.js";
3
2
  import { ResultPoolColumnSnapshotProvider, collectCtxColumnSnapshotProviders } from "../../columns/ctx_column_sources.js";
3
+ import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
4
4
  import { enrichmentVariantsToRefs, findEnrichmentColumns } from "./enrichment_discovery.js";
5
5
  import { multiColumnSelectorsToPredicate } from "@milaboratories/pl-model-common";
6
6
  //#region src/components/PlDatasetSelector/build_dataset_options.ts
package/dist/index.cjs CHANGED
@@ -28,15 +28,18 @@ const require_block_model_legacy = require("./block_model_legacy.cjs");
28
28
  const require_plugin_model = require("./plugin_model.cjs");
29
29
  const require_block_model = require("./block_model.cjs");
30
30
  const require_axes = require("./pframe_utils/axes.cjs");
31
+ const require_column_snapshot = require("./columns/column_snapshot.cjs");
32
+ const require_column_snapshot_provider = require("./columns/column_snapshot_provider.cjs");
33
+ const require_column_selector = require("./columns/column_selector.cjs");
34
+ const require_column_collection_builder = require("./columns/column_collection_builder.cjs");
35
+ const require_ctx_column_sources = require("./columns/ctx_column_sources.cjs");
36
+ const require_expand_by_partition = require("./columns/expand_by_partition.cjs");
37
+ require("./columns/index.cjs");
31
38
  const require_columns = require("./pframe_utils/columns.cjs");
32
39
  const require_PFrameForGraphs = require("./components/PFrameForGraphs.cjs");
33
40
  const require_filters_ui = require("./components/PlAnnotations/filters_ui.cjs");
34
41
  const require_dataset_selection = require("./components/PlDatasetSelector/dataset_selection.cjs");
35
42
  const require_filter_discovery = require("./components/PlDatasetSelector/filter_discovery.cjs");
36
- const require_column_selector = require("./columns/column_selector.cjs");
37
- const require_column_snapshot_provider = require("./columns/column_snapshot_provider.cjs");
38
- const require_column_collection_builder = require("./columns/column_collection_builder.cjs");
39
- const require_ctx_column_sources = require("./columns/ctx_column_sources.cjs");
40
43
  const require_build_dataset_options = require("./components/PlDatasetSelector/build_dataset_options.cjs");
41
44
  const require_filterToQuery = require("./filters/converters/filterToQuery.cjs");
42
45
  const require_filterUiToExpressionImpl = require("./filters/converters/filterUiToExpressionImpl.cjs");
@@ -44,9 +47,6 @@ const require_distill = require("./filters/distill.cjs");
44
47
  require("./filters/index.cjs");
45
48
  const require_state_migration = require("./components/PlDataTable/state-migration.cjs");
46
49
  const require_createPlDataTableSheet = require("./components/PlDataTable/createPlDataTableSheet.cjs");
47
- const require_column_snapshot = require("./columns/column_snapshot.cjs");
48
- const require_expand_by_partition = require("./columns/expand_by_partition.cjs");
49
- require("./columns/index.cjs");
50
50
  const require_derive_distinct_tooltips = require("./labels/derive_distinct_tooltips.cjs");
51
51
  const require_utils = require("./components/PlDataTable/createPlDataTable/utils.cjs");
52
52
  const require_createPlDataTableV2 = require("./components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs");
package/dist/index.js CHANGED
@@ -27,15 +27,18 @@ import { BlockModel } from "./block_model_legacy.js";
27
27
  import { PluginDataModel, PluginDataModelBuilder, PluginInstance, PluginModel } from "./plugin_model.js";
28
28
  import { BlockModelV3 } from "./block_model.js";
29
29
  import { enrichCompatible, getAvailableWithLinkersAxes } from "./pframe_utils/axes.js";
30
+ import { createColumnSnapshot, createReadyColumnData } from "./columns/column_snapshot.js";
31
+ import { ArrayColumnProvider, OutputColumnProvider, SnapshotColumnProvider, isColumnSnapshotProvider, toColumnSnapshotProvider } from "./columns/column_snapshot_provider.js";
32
+ import { convertColumnSelectorToMultiColumnSelector, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector } from "./columns/column_selector.js";
33
+ import { ColumnCollectionBuilder } from "./columns/column_collection_builder.js";
34
+ import { ResultPoolColumnSnapshotProvider, collectCtxColumnSnapshotProviders } from "./columns/ctx_column_sources.js";
35
+ import { expandByPartition } from "./columns/expand_by_partition.js";
36
+ import "./columns/index.js";
30
37
  import { getAllRelatedColumns, getRelatedColumns } from "./pframe_utils/columns.js";
31
38
  import { createPFrameForGraphs, isHiddenFromGraphColumn, isHiddenFromUIColumn } from "./components/PFrameForGraphs.js";
32
39
  import { compileAnnotationScript, compileFilter, compileFilters, unreachable } from "./components/PlAnnotations/filters_ui.js";
33
40
  import { createDatasetSelection, isDatasetSelection } from "./components/PlDatasetSelector/dataset_selection.js";
34
41
  import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./components/PlDatasetSelector/filter_discovery.js";
35
- import { convertColumnSelectorToMultiColumnSelector, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector } from "./columns/column_selector.js";
36
- import { ArrayColumnProvider, OutputColumnProvider, SnapshotColumnProvider, isColumnSnapshotProvider, toColumnSnapshotProvider } from "./columns/column_snapshot_provider.js";
37
- import { ColumnCollectionBuilder } from "./columns/column_collection_builder.js";
38
- import { ResultPoolColumnSnapshotProvider, collectCtxColumnSnapshotProviders } from "./columns/ctx_column_sources.js";
39
42
  import { buildDatasetOptions } from "./components/PlDatasetSelector/build_dataset_options.js";
40
43
  import { filterSpecToSpecQueryExpr } from "./filters/converters/filterToQuery.js";
41
44
  import { convertFilterUiToExpressionImpl, convertFilterUiToExpressions } from "./filters/converters/filterUiToExpressionImpl.js";
@@ -43,9 +46,6 @@ import { distillFilterSpec } from "./filters/distill.js";
43
46
  import "./filters/index.js";
44
47
  import { createDefaultPTableParams, createPlDataTableStateV2, upgradePlDataTableStateV2 } from "./components/PlDataTable/state-migration.js";
45
48
  import { createPlDataTableSheet } from "./components/PlDataTable/createPlDataTableSheet.js";
46
- import { createColumnSnapshot, createReadyColumnData } from "./columns/column_snapshot.js";
47
- import { expandByPartition } from "./columns/expand_by_partition.js";
48
- import "./columns/index.js";
49
49
  import { deriveDistinctTooltips } from "./labels/derive_distinct_tooltips.js";
50
50
  import { getEffectiveVisibility, getOrderPriority, isColumnHidden, isColumnOptional } from "./components/PlDataTable/createPlDataTable/utils.js";
51
51
  import { createPlDataTableV2 } from "./components/PlDataTable/createPlDataTable/createPlDataTableV2.js";
package/dist/package.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "1.79.6";
2
+ var version = "1.79.15";
3
3
  //#endregion
4
4
  Object.defineProperty(exports, "version", {
5
5
  enumerable: true,
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "1.79.6";
2
+ var version = "1.79.15";
3
3
  //#endregion
4
4
  export { version };
5
5
 
@@ -2,6 +2,9 @@ require("../_virtual/_rolldown/runtime.cjs");
2
2
  const require_column_collection = require("../render/util/column_collection.cjs");
3
3
  require("../render/index.cjs");
4
4
  const require_axes = require("./axes.cjs");
5
+ const require_column_collection_builder = require("../columns/column_collection_builder.cjs");
6
+ const require_ctx_column_sources = require("../columns/ctx_column_sources.cjs");
7
+ require("../columns/index.cjs");
5
8
  let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
6
9
  //#region src/pframe_utils/columns.ts
7
10
  function getAllRelatedColumns(ctx, predicate) {
@@ -58,7 +61,28 @@ function getRelatedColumns(ctx, { columns: rootColumns, predicate }) {
58
61
  dontWaitAllData: true,
59
62
  overrideLabelAnnotation: false
60
63
  }) ?? []).filter((column) => (0, _milaboratories_pl_model_common.isLabelColumn)(column.spec));
61
- return require_axes.enrichCompatible(blockAxes, [...compatibleWithoutLabels, ...compatibleLabels]);
64
+ const compatible = [...compatibleWithoutLabels, ...compatibleLabels];
65
+ const integrableIds = discoverIntegrableColumnIds(ctx, rootColumns);
66
+ const rootIds = new Set(rootColumns.map((c) => c.id));
67
+ return require_axes.enrichCompatible(blockAxes, compatible.filter((c) => rootIds.has(c.id) || (0, _milaboratories_pl_model_common.isLinkerColumn)(c.spec) || (integrableIds?.has(c.id) ?? true)));
68
+ }
69
+ /** Column ids that discovery confirms integrate with the block, or `undefined` when it can't decide. */
70
+ function discoverIntegrableColumnIds(ctx, rootColumns) {
71
+ const anchorSpecs = Array.from(new Map(rootColumns.map((c) => [(0, _milaboratories_pl_model_common.canonicalizeJson)(c.spec), c.spec])).values());
72
+ if (anchorSpecs.length === 0) return void 0;
73
+ try {
74
+ const collection = new require_column_collection_builder.ColumnCollectionBuilder().addSources(require_ctx_column_sources.collectCtxColumnSnapshotProviders(ctx)).build({
75
+ allowPartialColumnList: true,
76
+ anchors: Object.fromEntries(anchorSpecs.map((spec, i) => [`anchor_${i}`, spec]))
77
+ });
78
+ try {
79
+ return new Set(collection.findColumns({ mode: "enrichment" }).map((m) => m.column.id));
80
+ } finally {
81
+ collection.dispose();
82
+ }
83
+ } catch {
84
+ return;
85
+ }
62
86
  }
63
87
  //#endregion
64
88
  exports.getAllRelatedColumns = getAllRelatedColumns;
@@ -1 +1 @@
1
- {"version":3,"file":"columns.cjs","names":["PColumnCollection","enrichCompatible","getAvailableWithLinkersAxes"],"sources":["../../src/pframe_utils/columns.ts"],"sourcesContent":["import type { PColumn, PColumnSpec, PColumnLazy, PFrameDef } from \"@milaboratories/pl-model-common\";\nimport {\n getNormalizedAxesList,\n getAxisId,\n canonicalizeJson,\n isLinkerColumn,\n matchAxisId,\n isLabelColumn,\n} from \"@milaboratories/pl-model-common\";\nimport type { AxesVault } from \"./axes\";\nimport { enrichCompatible, getAvailableWithLinkersAxes } from \"./axes\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../render\";\nimport { PColumnCollection } from \"../render\";\n\nexport function getAllRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n predicate: (spec: PColumnSpec) => boolean,\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block doesn't produce own columns then use all columns from result pool\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n const allColumns =\n columns.getColumns(predicate, {\n dontWaitAllData: true,\n overrideLabelAnnotation: false,\n }) ?? [];\n\n const allAxes: AxesVault = new Map(\n allColumns\n .flatMap((column) => getNormalizedAxesList(column.spec.axesSpec))\n .map((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return [canonicalizeJson(axisId), axisSpec];\n }),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(allAxes, allColumns);\n\n return extendedColumns;\n}\n\nexport function getRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n {\n columns: rootColumns,\n predicate,\n }: {\n columns: PColumn<PColumnDataUniversal>[];\n predicate: (spec: PColumnSpec) => boolean;\n },\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block has its own columns then take from result pool only compatible with them\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n columns.addColumns(rootColumns);\n\n // all possible axes from block columns\n const blockAxes: AxesVault = new Map();\n // axes from block columns and compatible result pool columns\n const allAxes: AxesVault = new Map();\n for (const c of rootColumns) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n blockAxes.set(canonicalizeJson(aid), spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n // all linker columns always go to pFrame - even it's impossible to use some of them they all are hidden\n const linkerColumns =\n columns.getColumns((spec) => predicate(spec) && isLinkerColumn(spec), {\n dontWaitAllData: true,\n }) ?? [];\n const availableWithLinkersAxes = getAvailableWithLinkersAxes(linkerColumns, blockAxes);\n\n // all possible axes from connected linkers\n for (const item of availableWithLinkersAxes) {\n blockAxes.set(...item);\n allAxes.set(...item);\n }\n\n const blockAxesArr = Array.from(blockAxes.values());\n // all compatible with block columns but without label columns\n let compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return blockAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // extend axes set for label columns request\n for (const c of compatibleWithoutLabels) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n const allAxesArr = Array.from(allAxes.values());\n // extend allowed columns - add columns thad doesn't have axes from block, but have all axes in 'allAxes' list (that means all axes from linkers or from 'hanging' of other selected columns)\n compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.every((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // label columns must be compatible with full set of axes - block axes and axes from compatible columns from result pool\n const compatibleLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => isLabelColumn(column.spec));\n\n const compatible = [...compatibleWithoutLabels, ...compatibleLabels];\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(blockAxes, compatible);\n\n return extendedColumns;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"columns.cjs","names":["PColumnCollection","enrichCompatible","getAvailableWithLinkersAxes","ColumnCollectionBuilder","collectCtxColumnSnapshotProviders"],"sources":["../../src/pframe_utils/columns.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnSpec,\n PColumnLazy,\n PFrameDef,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport {\n getNormalizedAxesList,\n getAxisId,\n canonicalizeJson,\n isLinkerColumn,\n matchAxisId,\n isLabelColumn,\n} from \"@milaboratories/pl-model-common\";\nimport type { AxesVault } from \"./axes\";\nimport { enrichCompatible, getAvailableWithLinkersAxes } from \"./axes\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../render\";\nimport { PColumnCollection } from \"../render\";\nimport { ColumnCollectionBuilder } from \"../columns\";\nimport { collectCtxColumnSnapshotProviders } from \"../columns/ctx_column_sources\";\n\nexport function getAllRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n predicate: (spec: PColumnSpec) => boolean,\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block doesn't produce own columns then use all columns from result pool\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n const allColumns =\n columns.getColumns(predicate, {\n dontWaitAllData: true,\n overrideLabelAnnotation: false,\n }) ?? [];\n\n const allAxes: AxesVault = new Map(\n allColumns\n .flatMap((column) => getNormalizedAxesList(column.spec.axesSpec))\n .map((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return [canonicalizeJson(axisId), axisSpec];\n }),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(allAxes, allColumns);\n\n return extendedColumns;\n}\n\nexport function getRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n {\n columns: rootColumns,\n predicate,\n }: {\n columns: PColumn<PColumnDataUniversal>[];\n predicate: (spec: PColumnSpec) => boolean;\n },\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block has its own columns then take from result pool only compatible with them\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n columns.addColumns(rootColumns);\n\n // all possible axes from block columns\n const blockAxes: AxesVault = new Map();\n // axes from block columns and compatible result pool columns\n const allAxes: AxesVault = new Map();\n for (const c of rootColumns) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n blockAxes.set(canonicalizeJson(aid), spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n // all linker columns always go to pFrame - even it's impossible to use some of them they all are hidden\n const linkerColumns =\n columns.getColumns((spec) => predicate(spec) && isLinkerColumn(spec), {\n dontWaitAllData: true,\n }) ?? [];\n const availableWithLinkersAxes = getAvailableWithLinkersAxes(linkerColumns, blockAxes);\n\n // all possible axes from connected linkers\n for (const item of availableWithLinkersAxes) {\n blockAxes.set(...item);\n allAxes.set(...item);\n }\n\n const blockAxesArr = Array.from(blockAxes.values());\n // all compatible with block columns but without label columns\n let compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return blockAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // extend axes set for label columns request\n for (const c of compatibleWithoutLabels) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n const allAxesArr = Array.from(allAxes.values());\n // extend allowed columns - add columns thad doesn't have axes from block, but have all axes in 'allAxes' list (that means all axes from linkers or from 'hanging' of other selected columns)\n compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.every((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // label columns must be compatible with full set of axes - block axes and axes from compatible columns from result pool\n const compatibleLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => isLabelColumn(column.spec));\n\n const compatible = [...compatibleWithoutLabels, ...compatibleLabels];\n\n // Drop result-pool columns that share an axis with the block but cannot join it.\n const integrableIds = discoverIntegrableColumnIds(ctx, rootColumns);\n const rootIds = new Set(rootColumns.map((c) => c.id));\n const connected = compatible.filter(\n (c) => rootIds.has(c.id) || isLinkerColumn(c.spec) || (integrableIds?.has(c.id) ?? true),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(blockAxes, connected);\n\n return extendedColumns;\n}\n\n/** Column ids that discovery confirms integrate with the block, or `undefined` when it can't decide. */\nfunction discoverIntegrableColumnIds<A, U>(\n ctx: RenderCtxBase<A, U>,\n rootColumns: PColumn<PColumnDataUniversal>[],\n): Set<PObjectId> | undefined {\n const anchorSpecs = Array.from(\n new Map(rootColumns.map((c) => [canonicalizeJson(c.spec), c.spec])).values(),\n );\n if (anchorSpecs.length === 0) return undefined;\n\n try {\n const collection = new ColumnCollectionBuilder()\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({\n allowPartialColumnList: true,\n anchors: Object.fromEntries(anchorSpecs.map((spec, i) => [`anchor_${i}`, spec])),\n });\n try {\n return new Set(collection.findColumns({ mode: \"enrichment\" }).map((m) => m.column.id));\n } finally {\n collection.dispose();\n }\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"columns.d.ts","names":[],"sources":["../../src/pframe_utils/columns.ts"],"mappings":";;;;;iBAcgB,oBAAA,MAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA,GACtB,SAAA,GAAY,IAAA,EAAM,WAAA,eACjB,SAAA,CAAU,OAAA,CAAQ,oBAAA,IAAwB,WAAA,aAAwB,oBAAA;AAAA,iBAyBrD,iBAAA,MAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA;EAEpB,OAAA,EAAS,WAAA;EACT;AAAA;EAEA,OAAA,EAAS,OAAA,CAAQ,oBAAA;EACjB,SAAA,GAAY,IAAA,EAAM,WAAA;AAAA,IAEnB,SAAA,CAAU,OAAA,CAAQ,oBAAA,IAAwB,WAAA,aAAwB,oBAAA"}
1
+ {"version":3,"file":"columns.d.ts","names":[],"sources":["../../src/pframe_utils/columns.ts"],"mappings":";;;;;iBAsBgB,oBAAA,MAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA,GACtB,SAAA,GAAY,IAAA,EAAM,WAAA,eACjB,SAAA,CAAU,OAAA,CAAQ,oBAAA,IAAwB,WAAA,aAAwB,oBAAA;AAAA,iBAyBrD,iBAAA,MAAA,CACd,GAAA,EAAK,aAAA,CAAc,CAAA,EAAG,CAAA;EAEpB,OAAA,EAAS,WAAA;EACT;AAAA;EAEA,OAAA,EAAS,OAAA,CAAQ,oBAAA;EACjB,SAAA,GAAY,IAAA,EAAM,WAAA;AAAA,IAEnB,SAAA,CAAU,OAAA,CAAQ,oBAAA,IAAwB,WAAA,aAAwB,oBAAA"}
@@ -1,6 +1,9 @@
1
1
  import { PColumnCollection } from "../render/util/column_collection.js";
2
2
  import "../render/index.js";
3
3
  import { enrichCompatible, getAvailableWithLinkersAxes } from "./axes.js";
4
+ import { ColumnCollectionBuilder } from "../columns/column_collection_builder.js";
5
+ import { collectCtxColumnSnapshotProviders } from "../columns/ctx_column_sources.js";
6
+ import "../columns/index.js";
4
7
  import { canonicalizeJson, getAxisId, getNormalizedAxesList, isLabelColumn, isLinkerColumn, matchAxisId } from "@milaboratories/pl-model-common";
5
8
  //#region src/pframe_utils/columns.ts
6
9
  function getAllRelatedColumns(ctx, predicate) {
@@ -57,7 +60,28 @@ function getRelatedColumns(ctx, { columns: rootColumns, predicate }) {
57
60
  dontWaitAllData: true,
58
61
  overrideLabelAnnotation: false
59
62
  }) ?? []).filter((column) => isLabelColumn(column.spec));
60
- return enrichCompatible(blockAxes, [...compatibleWithoutLabels, ...compatibleLabels]);
63
+ const compatible = [...compatibleWithoutLabels, ...compatibleLabels];
64
+ const integrableIds = discoverIntegrableColumnIds(ctx, rootColumns);
65
+ const rootIds = new Set(rootColumns.map((c) => c.id));
66
+ return enrichCompatible(blockAxes, compatible.filter((c) => rootIds.has(c.id) || isLinkerColumn(c.spec) || (integrableIds?.has(c.id) ?? true)));
67
+ }
68
+ /** Column ids that discovery confirms integrate with the block, or `undefined` when it can't decide. */
69
+ function discoverIntegrableColumnIds(ctx, rootColumns) {
70
+ const anchorSpecs = Array.from(new Map(rootColumns.map((c) => [canonicalizeJson(c.spec), c.spec])).values());
71
+ if (anchorSpecs.length === 0) return void 0;
72
+ try {
73
+ const collection = new ColumnCollectionBuilder().addSources(collectCtxColumnSnapshotProviders(ctx)).build({
74
+ allowPartialColumnList: true,
75
+ anchors: Object.fromEntries(anchorSpecs.map((spec, i) => [`anchor_${i}`, spec]))
76
+ });
77
+ try {
78
+ return new Set(collection.findColumns({ mode: "enrichment" }).map((m) => m.column.id));
79
+ } finally {
80
+ collection.dispose();
81
+ }
82
+ } catch {
83
+ return;
84
+ }
61
85
  }
62
86
  //#endregion
63
87
  export { getAllRelatedColumns, getRelatedColumns };
@@ -1 +1 @@
1
- {"version":3,"file":"columns.js","names":[],"sources":["../../src/pframe_utils/columns.ts"],"sourcesContent":["import type { PColumn, PColumnSpec, PColumnLazy, PFrameDef } from \"@milaboratories/pl-model-common\";\nimport {\n getNormalizedAxesList,\n getAxisId,\n canonicalizeJson,\n isLinkerColumn,\n matchAxisId,\n isLabelColumn,\n} from \"@milaboratories/pl-model-common\";\nimport type { AxesVault } from \"./axes\";\nimport { enrichCompatible, getAvailableWithLinkersAxes } from \"./axes\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../render\";\nimport { PColumnCollection } from \"../render\";\n\nexport function getAllRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n predicate: (spec: PColumnSpec) => boolean,\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block doesn't produce own columns then use all columns from result pool\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n const allColumns =\n columns.getColumns(predicate, {\n dontWaitAllData: true,\n overrideLabelAnnotation: false,\n }) ?? [];\n\n const allAxes: AxesVault = new Map(\n allColumns\n .flatMap((column) => getNormalizedAxesList(column.spec.axesSpec))\n .map((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return [canonicalizeJson(axisId), axisSpec];\n }),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(allAxes, allColumns);\n\n return extendedColumns;\n}\n\nexport function getRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n {\n columns: rootColumns,\n predicate,\n }: {\n columns: PColumn<PColumnDataUniversal>[];\n predicate: (spec: PColumnSpec) => boolean;\n },\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block has its own columns then take from result pool only compatible with them\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n columns.addColumns(rootColumns);\n\n // all possible axes from block columns\n const blockAxes: AxesVault = new Map();\n // axes from block columns and compatible result pool columns\n const allAxes: AxesVault = new Map();\n for (const c of rootColumns) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n blockAxes.set(canonicalizeJson(aid), spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n // all linker columns always go to pFrame - even it's impossible to use some of them they all are hidden\n const linkerColumns =\n columns.getColumns((spec) => predicate(spec) && isLinkerColumn(spec), {\n dontWaitAllData: true,\n }) ?? [];\n const availableWithLinkersAxes = getAvailableWithLinkersAxes(linkerColumns, blockAxes);\n\n // all possible axes from connected linkers\n for (const item of availableWithLinkersAxes) {\n blockAxes.set(...item);\n allAxes.set(...item);\n }\n\n const blockAxesArr = Array.from(blockAxes.values());\n // all compatible with block columns but without label columns\n let compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return blockAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // extend axes set for label columns request\n for (const c of compatibleWithoutLabels) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n const allAxesArr = Array.from(allAxes.values());\n // extend allowed columns - add columns thad doesn't have axes from block, but have all axes in 'allAxes' list (that means all axes from linkers or from 'hanging' of other selected columns)\n compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.every((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // label columns must be compatible with full set of axes - block axes and axes from compatible columns from result pool\n const compatibleLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => isLabelColumn(column.spec));\n\n const compatible = [...compatibleWithoutLabels, ...compatibleLabels];\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(blockAxes, compatible);\n\n return extendedColumns;\n}\n"],"mappings":";;;;;AAcA,SAAgB,qBACd,KACA,WAC0F;CAE1F,MAAM,UAAU,IAAI,mBAAmB;AACvC,SAAQ,kBAAkB,IAAI,WAAW;CACzC,MAAM,aACJ,QAAQ,WAAW,WAAW;EAC5B,iBAAiB;EACjB,yBAAyB;EAC1B,CAAC,IAAI,EAAE;AAcV,QAFwB,iBAVG,IAAI,IAC7B,WACG,SAAS,WAAW,sBAAsB,OAAO,KAAK,SAAS,CAAC,CAChE,KAAK,aAAa;AAEjB,SAAO,CAAC,iBADO,UAAU,SAAS,CACF,EAAE,SAAS;GAC3C,CACL,EAGiD,WAAW;;AAK/D,SAAgB,kBACd,KACA,EACE,SAAS,aACT,aAKwF;CAE1F,MAAM,UAAU,IAAI,mBAAmB;AACvC,SAAQ,kBAAkB,IAAI,WAAW;AACzC,SAAQ,WAAW,YAAY;CAG/B,MAAM,4BAAuB,IAAI,KAAK;CAEtC,MAAM,0BAAqB,IAAI,KAAK;AACpC,MAAK,MAAM,KAAK,YACd,MAAK,MAAM,QAAQ,sBAAsB,EAAE,KAAK,SAAS,EAAE;EACzD,MAAM,MAAM,UAAU,KAAK;AAC3B,YAAU,IAAI,iBAAiB,IAAI,EAAE,KAAK;AAC1C,UAAQ,IAAI,iBAAiB,IAAI,EAAE,KAAK;;CAS5C,MAAM,2BAA2B,4BAH/B,QAAQ,YAAY,SAAS,UAAU,KAAK,IAAI,eAAe,KAAK,EAAE,EACpE,iBAAiB,MAClB,CAAC,IAAI,EAAE,EACkE,UAAU;AAGtF,MAAK,MAAM,QAAQ,0BAA0B;AAC3C,YAAU,IAAI,GAAG,KAAK;AACtB,UAAQ,IAAI,GAAG,KAAK;;CAGtB,MAAM,eAAe,MAAM,KAAK,UAAU,QAAQ,CAAC;CAEnD,IAAI,2BACF,QAAQ,YACL,SACC,UAAU,KAAK,IACf,KAAK,SAAS,MAAM,aAAa;EAC/B,MAAM,SAAS,UAAU,SAAS;AAClC,SAAO,aAAa,MAAM,qBACxB,YAAY,UAAU,iBAAiB,EAAE,OAAO,CACjD;GACD,EACJ;EAAE,iBAAiB;EAAM,yBAAyB;EAAO,CAC1D,IAAI,EAAE,EACP,QAAQ,WAAW,CAAC,cAAc,OAAO,KAAK,CAAC;AAGjD,MAAK,MAAM,KAAK,wBACd,MAAK,MAAM,QAAQ,sBAAsB,EAAE,KAAK,SAAS,EAAE;EACzD,MAAM,MAAM,UAAU,KAAK;AAC3B,UAAQ,IAAI,iBAAiB,IAAI,EAAE,KAAK;;CAI5C,MAAM,aAAa,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAE/C,4BACE,QAAQ,YACL,SACC,UAAU,KAAK,IACf,KAAK,SAAS,OAAO,aAAa;EAChC,MAAM,SAAS,UAAU,SAAS;AAClC,SAAO,WAAW,MAAM,qBACtB,YAAY,UAAU,iBAAiB,EAAE,OAAO,CACjD;GACD,EACJ;EAAE,iBAAiB;EAAM,yBAAyB;EAAO,CAC1D,IAAI,EAAE,EACP,QAAQ,WAAW,CAAC,cAAc,OAAO,KAAK,CAAC;CAGjD,MAAM,oBACJ,QAAQ,YACL,SACC,UAAU,KAAK,IACf,KAAK,SAAS,MAAM,aAAa;EAC/B,MAAM,SAAS,UAAU,SAAS;AAClC,SAAO,WAAW,MAAM,qBACtB,YAAY,UAAU,iBAAiB,EAAE,OAAO,CACjD;GACD,EACJ;EAAE,iBAAiB;EAAM,yBAAyB;EAAO,CAC1D,IAAI,EAAE,EACP,QAAQ,WAAW,cAAc,OAAO,KAAK,CAAC;AAOhD,QAFwB,iBAAiB,WAHtB,CAAC,GAAG,yBAAyB,GAAG,iBAAiB,CAGL"}
1
+ {"version":3,"file":"columns.js","names":[],"sources":["../../src/pframe_utils/columns.ts"],"sourcesContent":["import type {\n PColumn,\n PColumnSpec,\n PColumnLazy,\n PFrameDef,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport {\n getNormalizedAxesList,\n getAxisId,\n canonicalizeJson,\n isLinkerColumn,\n matchAxisId,\n isLabelColumn,\n} from \"@milaboratories/pl-model-common\";\nimport type { AxesVault } from \"./axes\";\nimport { enrichCompatible, getAvailableWithLinkersAxes } from \"./axes\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../render\";\nimport { PColumnCollection } from \"../render\";\nimport { ColumnCollectionBuilder } from \"../columns\";\nimport { collectCtxColumnSnapshotProviders } from \"../columns/ctx_column_sources\";\n\nexport function getAllRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n predicate: (spec: PColumnSpec) => boolean,\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block doesn't produce own columns then use all columns from result pool\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n const allColumns =\n columns.getColumns(predicate, {\n dontWaitAllData: true,\n overrideLabelAnnotation: false,\n }) ?? [];\n\n const allAxes: AxesVault = new Map(\n allColumns\n .flatMap((column) => getNormalizedAxesList(column.spec.axesSpec))\n .map((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return [canonicalizeJson(axisId), axisSpec];\n }),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(allAxes, allColumns);\n\n return extendedColumns;\n}\n\nexport function getRelatedColumns<A, U>(\n ctx: RenderCtxBase<A, U>,\n {\n columns: rootColumns,\n predicate,\n }: {\n columns: PColumn<PColumnDataUniversal>[];\n predicate: (spec: PColumnSpec) => boolean;\n },\n): PFrameDef<PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>> {\n // if current block has its own columns then take from result pool only compatible with them\n const columns = new PColumnCollection();\n columns.addColumnProvider(ctx.resultPool);\n columns.addColumns(rootColumns);\n\n // all possible axes from block columns\n const blockAxes: AxesVault = new Map();\n // axes from block columns and compatible result pool columns\n const allAxes: AxesVault = new Map();\n for (const c of rootColumns) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n blockAxes.set(canonicalizeJson(aid), spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n // all linker columns always go to pFrame - even it's impossible to use some of them they all are hidden\n const linkerColumns =\n columns.getColumns((spec) => predicate(spec) && isLinkerColumn(spec), {\n dontWaitAllData: true,\n }) ?? [];\n const availableWithLinkersAxes = getAvailableWithLinkersAxes(linkerColumns, blockAxes);\n\n // all possible axes from connected linkers\n for (const item of availableWithLinkersAxes) {\n blockAxes.set(...item);\n allAxes.set(...item);\n }\n\n const blockAxesArr = Array.from(blockAxes.values());\n // all compatible with block columns but without label columns\n let compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return blockAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // extend axes set for label columns request\n for (const c of compatibleWithoutLabels) {\n for (const spec of getNormalizedAxesList(c.spec.axesSpec)) {\n const aid = getAxisId(spec);\n allAxes.set(canonicalizeJson(aid), spec);\n }\n }\n\n const allAxesArr = Array.from(allAxes.values());\n // extend allowed columns - add columns thad doesn't have axes from block, but have all axes in 'allAxes' list (that means all axes from linkers or from 'hanging' of other selected columns)\n compatibleWithoutLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.every((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => !isLabelColumn(column.spec));\n\n // label columns must be compatible with full set of axes - block axes and axes from compatible columns from result pool\n const compatibleLabels = (\n columns.getColumns(\n (spec) =>\n predicate(spec) &&\n spec.axesSpec.some((axisSpec) => {\n const axisId = getAxisId(axisSpec);\n return allAxesArr.some((selectorAxisSpec) =>\n matchAxisId(getAxisId(selectorAxisSpec), axisId),\n );\n }),\n { dontWaitAllData: true, overrideLabelAnnotation: false },\n ) ?? []\n ).filter((column) => isLabelColumn(column.spec));\n\n const compatible = [...compatibleWithoutLabels, ...compatibleLabels];\n\n // Drop result-pool columns that share an axis with the block but cannot join it.\n const integrableIds = discoverIntegrableColumnIds(ctx, rootColumns);\n const rootIds = new Set(rootColumns.map((c) => c.id));\n const connected = compatible.filter(\n (c) => rootIds.has(c.id) || isLinkerColumn(c.spec) || (integrableIds?.has(c.id) ?? true),\n );\n\n // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match\n const extendedColumns = enrichCompatible(blockAxes, connected);\n\n return extendedColumns;\n}\n\n/** Column ids that discovery confirms integrate with the block, or `undefined` when it can't decide. */\nfunction discoverIntegrableColumnIds<A, U>(\n ctx: RenderCtxBase<A, U>,\n rootColumns: PColumn<PColumnDataUniversal>[],\n): Set<PObjectId> | undefined {\n const anchorSpecs = Array.from(\n new Map(rootColumns.map((c) => [canonicalizeJson(c.spec), c.spec])).values(),\n );\n if (anchorSpecs.length === 0) return undefined;\n\n try {\n const collection = new ColumnCollectionBuilder()\n .addSources(collectCtxColumnSnapshotProviders(ctx))\n .build({\n allowPartialColumnList: true,\n anchors: Object.fromEntries(anchorSpecs.map((spec, i) => [`anchor_${i}`, spec])),\n });\n try {\n return new Set(collection.findColumns({ mode: \"enrichment\" }).map((m) => m.column.id));\n } finally {\n collection.dispose();\n }\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -3,8 +3,9 @@ const require_block_storage = require("./block_storage.cjs");
3
3
  //#region src/plugin_model.ts
4
4
  /** Symbol for internal builder creation method */
5
5
  const FROM_BUILDER = Symbol("fromBuilder");
6
- /** Symbol for internal plugin model creation — not accessible to external consumers */
7
- const CREATE_PLUGIN_MODEL = Symbol("createPluginModel");
6
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
7
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
8
+ const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
8
9
  /** Sentinel for PluginInstance without transferAt — no transfer possible. */
9
10
  const NO_TRANSFER_VERSION = "";
10
11
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.cjs","names":["DATA_MODEL_LEGACY_VERSION","DataModelBuilder"],"sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags, OutputWithStatus } from \"@milaboratories/pl-model-common\";\nimport type { ResolveModelServices, ResolveUiServices } from \"./services/service_resolve\";\nimport {\n type DataModel,\n DataModelBuilder,\n type DataRecoverFn,\n type DataVersioned,\n type TransferTarget,\n} from \"./block_migrations\";\nimport { type PluginName, DATA_MODEL_LEGACY_VERSION } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n/** Output function signature for plugin render context. */\ntype PluginOutputFn<\n Data extends PluginData,\n Params extends PluginParams,\n ModelServices,\n UiServices,\n T,\n> = (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n) => T;\n\n/** Mapped output functions for a plugin's outputs. */\ntype PluginOutputFns<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n ModelServices,\n UiServices,\n> = {\n [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;\n};\n\n/** Symbol for internal plugin model creation — not accessible to external consumers */\nexport const CREATE_PLUGIN_MODEL = Symbol(\"createPluginModel\");\n\n/** Sentinel for PluginInstance without transferAt — no transfer possible. */\nconst NO_TRANSFER_VERSION = \"\";\n\n/**\n * Runtime definition for a single public output field.\n * Stored in PluginModel and passed through BlockModelInfo to the UI layer.\n */\nexport type PublicOutputFieldDef = {\n readonly getter: (data: unknown) => unknown;\n};\n\nexport type PublicOutputDef<PublicOutputs extends PluginPublicOutputs> = {\n [K in keyof PublicOutputs]: PublicOutputFieldDef;\n};\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginPublicOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Plugin data model with typed migration chain and config-aware initialization.\n *\n * @typeParam Data - Current (latest) plugin data type\n * @typeParam Versions - Map of version keys to their data types (accumulated by the chain)\n * @typeParam Config - Config type passed to init function (undefined if none)\n */\nexport class PluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown> = {},\n Config = undefined,\n> {\n readonly dataModel: DataModel<Data>;\n private readonly configInitFn: (config?: Config) => Data;\n\n /** @internal Phantom field to anchor the Versions type parameter. */\n declare readonly __versions?: Versions;\n\n private constructor(dataModel: DataModel<Data>, configInitFn: (config?: Config) => Data) {\n this.dataModel = dataModel;\n this.configInitFn = configInitFn;\n }\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>, Config>(\n dataModel: DataModel<Data>,\n configInitFn: (config?: Config) => Data,\n ): PluginDataModel<Data, Versions, Config> {\n return new PluginDataModel<Data, Versions, Config>(dataModel, configInitFn);\n }\n\n /** Create fresh data with optional config. */\n getDefaultData(config?: Config): DataVersioned<Data> {\n const data = this.configInitFn(config);\n return { version: this.dataModel.version, data };\n }\n}\n\n/** Internal state for plugin data model chain. */\ntype PluginChainState = {\n initialVersion: string;\n migrations: Array<{ toVersion: string; fn: (data: unknown) => unknown }>;\n recoverFn?: (version: string, data: unknown) => unknown;\n recoverAtIndex?: number;\n};\n\n/** Version → persisted data shape for each migration step (third generic of `PluginModel.define` when `data` is a `PluginDataModel`). */\nexport type PluginDataModelVersions<\n M extends PluginDataModel<PluginData, Record<string, unknown>, unknown>,\n> = M extends PluginDataModel<PluginData, infer Versions, unknown> ? Versions : never;\n\n/**\n * Builder for creating PluginDataModel with type-safe migrations.\n * Mirrors DataModelBuilder — same .from(), .migrate(), .recover(), .init() chain.\n *\n * @example\n * const pluginData = new PluginDataModelBuilder()\n * .from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n */\nexport class PluginDataModelBuilder {\n from<Data extends PluginData, const V extends string>(\n version: V,\n ): PluginDataModelInitialChain<Data, Record<V, Data>> {\n return PluginDataModelInitialChain[FROM_BUILDER]<Data, Record<V, Data>>({\n initialVersion: version,\n migrations: [],\n });\n }\n}\n\n/**\n * Chain returned by .migrate(). Supports .migrate(), .recover(), .init().\n * No .upgradeLegacy() — that is only available on the initial chain.\n */\nexport class PluginDataModelChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n protected constructor(protected readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelChain<Data, Versions> {\n return new PluginDataModelChain(state);\n }\n\n /**\n * Add a migration step transforming data from the current version to the next.\n */\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelChain<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelChain[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n /**\n * Set a recovery handler for unknown or legacy versions.\n * Can only be called once — the returned chain has no recover() method.\n */\n recover(fn: DataRecoverFn<Data>): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n recoverFn: fn as (version: string, data: unknown) => unknown,\n recoverAtIndex: this.state.migrations.length,\n });\n }\n\n /** Finalize the PluginDataModel. */\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Initial chain returned by new PluginDataModelBuilder().from().\n * Extends PluginDataModelChain with .upgradeLegacy() — available only before\n * any .migrate() calls, matching the block's DataModelInitialChain pattern.\n */\nexport class PluginDataModelInitialChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> extends PluginDataModelChain<Data, Versions> {\n /** @internal */\n static override [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelInitialChain<Data, Versions> {\n return new PluginDataModelInitialChain(state);\n }\n\n /**\n * Handle data from a previous plugin type occupying this slot.\n * Prepends a migration from DATA_MODEL_LEGACY_VERSION to the initial version.\n * When a plugin type changes, the old data arrives with DATA_MODEL_LEGACY_VERSION —\n * this function transforms it into the initial version, then the normal chain runs.\n *\n * Must be called right after .from() — not available after .migrate().\n * Mutually exclusive with recover().\n *\n * @param fn - Transform from old plugin's raw data to this plugin's initial data type\n */\n upgradeLegacy(fn: (data: unknown) => Data): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n migrations: [\n { toVersion: this.state.initialVersion, fn: fn as (data: unknown) => unknown },\n ...this.state.migrations,\n ],\n initialVersion: DATA_MODEL_LEGACY_VERSION,\n });\n }\n}\n\n/**\n * Chain after .recover() — supports .migrate(), .init(). No second recover().\n */\nexport class PluginDataModelWithRecover<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n private constructor(private readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelWithRecover<Data, Versions> {\n return new PluginDataModelWithRecover(state);\n }\n\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelWithRecover<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Builds a PluginDataModel by replaying the stored chain state through DataModelBuilder.\n * @internal\n */\nfunction buildPluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n Config,\n>(\n state: PluginChainState,\n configInitFn: (config?: Config) => Data,\n): PluginDataModel<Data, Versions, Config> {\n // Build inner DataModel by replaying migrations through DataModelBuilder chain.\n // Uses `any` internally — type safety is maintained by the public chain types.\n let chain: any = new DataModelBuilder().from(state.initialVersion);\n\n for (let i = 0; i < state.migrations.length; i++) {\n if (state.recoverFn !== undefined && state.recoverAtIndex === i) {\n chain = chain.recover(state.recoverFn);\n }\n chain = chain.migrate(state.migrations[i].toVersion, state.migrations[i].fn);\n }\n\n // If recover was placed at or after the last migration\n if (state.recoverFn !== undefined && state.recoverAtIndex === state.migrations.length) {\n chain = chain.recover(state.recoverFn);\n }\n\n const dataModel: DataModel<Data> = chain.init(() => configInitFn());\n\n return PluginDataModel[FROM_BUILDER]<Data, Versions, Config>(dataModel, configInitFn);\n}\n\n/**\n * A named plugin instance created by `factory.create({ pluginId, ... })`.\n * Passed to both `.transfer()` (on migration chain) and `.plugin()` (on BlockModelV3).\n * Implements TransferTarget so the migration chain can accept it.\n *\n * @typeParam Id - Plugin instance ID literal type\n * @typeParam Data - Plugin data type\n * @typeParam Params - Plugin params type\n * @typeParam Outputs - Plugin outputs type\n * @typeParam TransferData - Type of data entering the plugin via transfer (never if no transfer)\n */\nexport class PluginInstance<\n Id extends string = string,\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n ModelServices = unknown,\n UiServices = unknown,\n> implements TransferTarget<Id, TransferData> {\n readonly id: Id;\n readonly transferVersion: string;\n /** @internal Phantom for type inference; never set at runtime. */\n readonly __instanceTypes?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n publicOutputs: PublicOutputs;\n };\n /** Bound closure that creates the PluginModel. Config is captured at factory.create() time. */\n private readonly createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >;\n\n private constructor(\n id: Id,\n createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n ) {\n this.id = id;\n this.createPluginModel = createPluginModel;\n this.transferVersion = transferVersion;\n }\n\n /** @internal Accepts concrete Config — binds it into a closure, avoiding Config variance issues. */\n static [FROM_BUILDER]<\n Id extends string,\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n Config extends PluginConfig = PluginConfig,\n ModelServices = unknown,\n UiServices = unknown,\n >(\n id: Id,\n factory: PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Record<string, unknown>,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n config?: Config,\n ): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n TransferData,\n ModelServices,\n UiServices\n > {\n return new PluginInstance(id, () => factory[CREATE_PLUGIN_MODEL](config), transferVersion);\n }\n\n /** @internal Create a PluginModel from this instance. Used by BlockModelV3.plugin(). */\n [CREATE_PLUGIN_MODEL](): PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n > {\n return this.createPluginModel();\n }\n}\n\n/**\n * Configured plugin instance returned by PluginModelFactory[CREATE_PLUGIN_MODEL]().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n /** Create fresh default data. Config (if any) is captured at creation time. */\n readonly getDefaultData: () => DataVersioned<Data>;\n /** Public output definitions — accessible without usePlugin() via app.plugins */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.getDefaultData = options.getDefaultData;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n return new PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices>(\n options,\n );\n }\n\n /**\n * Creates a new PluginModelBuilder with a PluginDataModel (supports transfer / config).\n *\n * @example\n * const pluginData = new PluginDataModelBuilder().from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: pluginData,\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Versions extends Record<string, unknown> = {},\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: PluginDataModel<Data, Versions, Config>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n Versions,\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n /**\n * Creates a new PluginModelBuilder with a data model factory function (backward compatible).\n *\n * @example\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n {},\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n static define(options: {\n name: PluginName;\n data: PluginDataModel<any, any, any> | ((config?: any) => DataModel<any>);\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder {\n if (options.data instanceof PluginDataModel) {\n const pdm = options.data;\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: () => pdm.dataModel,\n getDefaultDataFn: (config: any) => pdm.getDefaultData(config),\n featureFlags: options.featureFlags,\n });\n }\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: options.data,\n featureFlags: options.featureFlags,\n });\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices> {\n /** Create a named plugin instance, optionally with transfer at a specific version. */\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n >;\n\n /** Public output field definitions declared via .publicOutput(). */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n config: Config;\n versions: Versions;\n publicOutputs: PublicOutputs;\n };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> implements PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n> {\n private readonly name: PluginName;\n private readonly dataFn: (config?: Config) => DataModel<Data>;\n private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelFactory(options);\n }\n\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n > {\n const transferVersion = options.transferAt ?? NO_TRANSFER_VERSION;\n return PluginInstance[FROM_BUILDER]<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n Config,\n ModelServices,\n UiServices\n >(options.pluginId as Id, this, transferVersion, options.config);\n }\n\n /** @internal Create a PluginModel from config. Config is captured in getDefaultData closure. */\n [CREATE_PLUGIN_MODEL](\n config?: Config,\n ): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n const dataModel = this.dataFn(config);\n const getDefaultDataFn = this.getDefaultDataFn;\n return PluginModel[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataModel,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n getDefaultData: getDefaultDataFn\n ? () => getDefaultDataFn(config)\n : () => dataModel.getDefaultData(),\n publicOutputDef: this.publicOutputDef,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n * @typeParam Versions - Version map from PluginDataModel (empty for function-based data)\n *\n * @example\n * const dataTable = PluginModel.define({\n * name: 'dataTable' as PluginName,\n * data: pluginDataModel,\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> {\n protected readonly name: PluginName;\n protected readonly dataFn: (config?: Config) => DataModel<Data>;\n protected readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n private readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n protected readonly featureFlags?: BlockCodeKnownFeatureFlags;\n private readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n protected constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs =\n options.outputs ?? ({} as PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>);\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n * All plugin outputs are always wrapped with status — the UI receives\n * {@link OutputWithStatus} for every output, allowing it to distinguish\n * between pending, success, and error states.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns Builder with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('pFrame', (ctx) => ctx.createPFrame([...]))\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n ) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as unknown as PluginOutputFns<\n Data,\n Params,\n Outputs & { [P in Key]: OutputWithStatus<T> },\n ModelServices,\n UiServices\n >,\n publicOutputDef: this.publicOutputDef,\n });\n }\n\n /**\n * Exposes a plugin data field as a public output — accessible without `usePlugin()`\n * via `app.plugins.pluginName.publicOutputs.key`.\n *\n * The getter runs against the plugin's reactive data object.\n * Public outputs are read-only.\n *\n * @param key - Name of the public output field\n * @param getter - Function deriving the value from plugin data\n *\n * @example\n * .publicOutput('selection', (d) => d.selection)\n */\n publicOutput<const Key extends string, T>(\n key: Key,\n getter: (data: Data) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: this.outputs,\n publicOutputDef: {\n ...this.publicOutputDef,\n [key]: { getter: getter as (data: unknown) => unknown },\n } as PublicOutputDef<PublicOutputs & { [K in Key]: T }>,\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a PluginFactory.\n *\n * @returns Plugin factory that creates named plugin instances via .create()\n *\n * @example\n * const myPlugin = PluginModel.define({ ... })\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Create a named instance:\n * const table = myPlugin.create({ pluginId: 'mainTable', config: { ... } });\n */\n build(): PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelFactory[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n outputs: this.outputs,\n publicOutputDef: this.publicOutputDef,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Initial builder returned by PluginModel.define(). Extends PluginModelBuilder with .params().\n * Once .params() or .output() is called, transitions to PluginModelBuilder (no second .params()).\n */\nclass PluginModelInitialBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginModelBuilder<Data, Params, {}, {}, Config, Versions, ModelServices, UiServices> {\n /** @internal */\n static create<\n Data extends PluginData,\n Config extends PluginConfig,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder<Data, undefined, Config, Versions, ModelServices, UiServices> {\n return new PluginModelInitialBuilder({ ...options, publicOutputDef: {} });\n }\n\n /**\n * Sets the Params type for this plugin — the shape of data derived from the block's\n * render context and passed into plugin output functions via `ctx.params`.\n * Must be called before .output(). Available only on the initial builder.\n *\n * @example\n * .params<{ title: string }>()\n * .output('displayText', (ctx) => ctx.params.title)\n */\n params<P extends PluginParams>(): PluginModelBuilder<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelBuilder[FROM_BUILDER]<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n publicOutputDef: {},\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin_model.cjs","names":["DATA_MODEL_LEGACY_VERSION","DataModelBuilder"],"sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags, OutputWithStatus } from \"@milaboratories/pl-model-common\";\nimport type { ResolveModelServices, ResolveUiServices } from \"./services/service_resolve\";\nimport {\n type DataModel,\n DataModelBuilder,\n type DataRecoverFn,\n type DataVersioned,\n type TransferTarget,\n} from \"./block_migrations\";\nimport { type PluginName, DATA_MODEL_LEGACY_VERSION } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n/** Output function signature for plugin render context. */\ntype PluginOutputFn<\n Data extends PluginData,\n Params extends PluginParams,\n ModelServices,\n UiServices,\n T,\n> = (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n) => T;\n\n/** Mapped output functions for a plugin's outputs. */\ntype PluginOutputFns<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n ModelServices,\n UiServices,\n> = {\n [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;\n};\n\n/** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays\n * identical across multiple `@platforma-sdk/model` copies in one process. */\nexport const CREATE_PLUGIN_MODEL = Symbol.for(\"@platforma-sdk/model:createPluginModel\");\n\n/** Sentinel for PluginInstance without transferAt — no transfer possible. */\nconst NO_TRANSFER_VERSION = \"\";\n\n/**\n * Runtime definition for a single public output field.\n * Stored in PluginModel and passed through BlockModelInfo to the UI layer.\n */\nexport type PublicOutputFieldDef = {\n readonly getter: (data: unknown) => unknown;\n};\n\nexport type PublicOutputDef<PublicOutputs extends PluginPublicOutputs> = {\n [K in keyof PublicOutputs]: PublicOutputFieldDef;\n};\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginPublicOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Plugin data model with typed migration chain and config-aware initialization.\n *\n * @typeParam Data - Current (latest) plugin data type\n * @typeParam Versions - Map of version keys to their data types (accumulated by the chain)\n * @typeParam Config - Config type passed to init function (undefined if none)\n */\nexport class PluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown> = {},\n Config = undefined,\n> {\n readonly dataModel: DataModel<Data>;\n private readonly configInitFn: (config?: Config) => Data;\n\n /** @internal Phantom field to anchor the Versions type parameter. */\n declare readonly __versions?: Versions;\n\n private constructor(dataModel: DataModel<Data>, configInitFn: (config?: Config) => Data) {\n this.dataModel = dataModel;\n this.configInitFn = configInitFn;\n }\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>, Config>(\n dataModel: DataModel<Data>,\n configInitFn: (config?: Config) => Data,\n ): PluginDataModel<Data, Versions, Config> {\n return new PluginDataModel<Data, Versions, Config>(dataModel, configInitFn);\n }\n\n /** Create fresh data with optional config. */\n getDefaultData(config?: Config): DataVersioned<Data> {\n const data = this.configInitFn(config);\n return { version: this.dataModel.version, data };\n }\n}\n\n/** Internal state for plugin data model chain. */\ntype PluginChainState = {\n initialVersion: string;\n migrations: Array<{ toVersion: string; fn: (data: unknown) => unknown }>;\n recoverFn?: (version: string, data: unknown) => unknown;\n recoverAtIndex?: number;\n};\n\n/** Version → persisted data shape for each migration step (third generic of `PluginModel.define` when `data` is a `PluginDataModel`). */\nexport type PluginDataModelVersions<\n M extends PluginDataModel<PluginData, Record<string, unknown>, unknown>,\n> = M extends PluginDataModel<PluginData, infer Versions, unknown> ? Versions : never;\n\n/**\n * Builder for creating PluginDataModel with type-safe migrations.\n * Mirrors DataModelBuilder — same .from(), .migrate(), .recover(), .init() chain.\n *\n * @example\n * const pluginData = new PluginDataModelBuilder()\n * .from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n */\nexport class PluginDataModelBuilder {\n from<Data extends PluginData, const V extends string>(\n version: V,\n ): PluginDataModelInitialChain<Data, Record<V, Data>> {\n return PluginDataModelInitialChain[FROM_BUILDER]<Data, Record<V, Data>>({\n initialVersion: version,\n migrations: [],\n });\n }\n}\n\n/**\n * Chain returned by .migrate(). Supports .migrate(), .recover(), .init().\n * No .upgradeLegacy() — that is only available on the initial chain.\n */\nexport class PluginDataModelChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n protected constructor(protected readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelChain<Data, Versions> {\n return new PluginDataModelChain(state);\n }\n\n /**\n * Add a migration step transforming data from the current version to the next.\n */\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelChain<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelChain[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n /**\n * Set a recovery handler for unknown or legacy versions.\n * Can only be called once — the returned chain has no recover() method.\n */\n recover(fn: DataRecoverFn<Data>): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n recoverFn: fn as (version: string, data: unknown) => unknown,\n recoverAtIndex: this.state.migrations.length,\n });\n }\n\n /** Finalize the PluginDataModel. */\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Initial chain returned by new PluginDataModelBuilder().from().\n * Extends PluginDataModelChain with .upgradeLegacy() — available only before\n * any .migrate() calls, matching the block's DataModelInitialChain pattern.\n */\nexport class PluginDataModelInitialChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> extends PluginDataModelChain<Data, Versions> {\n /** @internal */\n static override [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelInitialChain<Data, Versions> {\n return new PluginDataModelInitialChain(state);\n }\n\n /**\n * Handle data from a previous plugin type occupying this slot.\n * Prepends a migration from DATA_MODEL_LEGACY_VERSION to the initial version.\n * When a plugin type changes, the old data arrives with DATA_MODEL_LEGACY_VERSION —\n * this function transforms it into the initial version, then the normal chain runs.\n *\n * Must be called right after .from() — not available after .migrate().\n * Mutually exclusive with recover().\n *\n * @param fn - Transform from old plugin's raw data to this plugin's initial data type\n */\n upgradeLegacy(fn: (data: unknown) => Data): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n migrations: [\n { toVersion: this.state.initialVersion, fn: fn as (data: unknown) => unknown },\n ...this.state.migrations,\n ],\n initialVersion: DATA_MODEL_LEGACY_VERSION,\n });\n }\n}\n\n/**\n * Chain after .recover() — supports .migrate(), .init(). No second recover().\n */\nexport class PluginDataModelWithRecover<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n private constructor(private readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelWithRecover<Data, Versions> {\n return new PluginDataModelWithRecover(state);\n }\n\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelWithRecover<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Builds a PluginDataModel by replaying the stored chain state through DataModelBuilder.\n * @internal\n */\nfunction buildPluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n Config,\n>(\n state: PluginChainState,\n configInitFn: (config?: Config) => Data,\n): PluginDataModel<Data, Versions, Config> {\n // Build inner DataModel by replaying migrations through DataModelBuilder chain.\n // Uses `any` internally — type safety is maintained by the public chain types.\n let chain: any = new DataModelBuilder().from(state.initialVersion);\n\n for (let i = 0; i < state.migrations.length; i++) {\n if (state.recoverFn !== undefined && state.recoverAtIndex === i) {\n chain = chain.recover(state.recoverFn);\n }\n chain = chain.migrate(state.migrations[i].toVersion, state.migrations[i].fn);\n }\n\n // If recover was placed at or after the last migration\n if (state.recoverFn !== undefined && state.recoverAtIndex === state.migrations.length) {\n chain = chain.recover(state.recoverFn);\n }\n\n const dataModel: DataModel<Data> = chain.init(() => configInitFn());\n\n return PluginDataModel[FROM_BUILDER]<Data, Versions, Config>(dataModel, configInitFn);\n}\n\n/**\n * A named plugin instance created by `factory.create({ pluginId, ... })`.\n * Passed to both `.transfer()` (on migration chain) and `.plugin()` (on BlockModelV3).\n * Implements TransferTarget so the migration chain can accept it.\n *\n * @typeParam Id - Plugin instance ID literal type\n * @typeParam Data - Plugin data type\n * @typeParam Params - Plugin params type\n * @typeParam Outputs - Plugin outputs type\n * @typeParam TransferData - Type of data entering the plugin via transfer (never if no transfer)\n */\nexport class PluginInstance<\n Id extends string = string,\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n ModelServices = unknown,\n UiServices = unknown,\n> implements TransferTarget<Id, TransferData> {\n readonly id: Id;\n readonly transferVersion: string;\n /** @internal Phantom for type inference; never set at runtime. */\n readonly __instanceTypes?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n publicOutputs: PublicOutputs;\n };\n /** Bound closure that creates the PluginModel. Config is captured at factory.create() time. */\n private readonly createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >;\n\n private constructor(\n id: Id,\n createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n ) {\n this.id = id;\n this.createPluginModel = createPluginModel;\n this.transferVersion = transferVersion;\n }\n\n /** @internal Accepts concrete Config — binds it into a closure, avoiding Config variance issues. */\n static [FROM_BUILDER]<\n Id extends string,\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n Config extends PluginConfig = PluginConfig,\n ModelServices = unknown,\n UiServices = unknown,\n >(\n id: Id,\n factory: PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Record<string, unknown>,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n config?: Config,\n ): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n TransferData,\n ModelServices,\n UiServices\n > {\n return new PluginInstance(id, () => factory[CREATE_PLUGIN_MODEL](config), transferVersion);\n }\n\n /** @internal Create a PluginModel from this instance. Used by BlockModelV3.plugin(). */\n [CREATE_PLUGIN_MODEL](): PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n > {\n return this.createPluginModel();\n }\n}\n\n/**\n * Configured plugin instance returned by PluginModelFactory[CREATE_PLUGIN_MODEL]().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n /** Create fresh default data. Config (if any) is captured at creation time. */\n readonly getDefaultData: () => DataVersioned<Data>;\n /** Public output definitions — accessible without usePlugin() via app.plugins */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.getDefaultData = options.getDefaultData;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n return new PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices>(\n options,\n );\n }\n\n /**\n * Creates a new PluginModelBuilder with a PluginDataModel (supports transfer / config).\n *\n * @example\n * const pluginData = new PluginDataModelBuilder().from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: pluginData,\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Versions extends Record<string, unknown> = {},\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: PluginDataModel<Data, Versions, Config>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n Versions,\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n /**\n * Creates a new PluginModelBuilder with a data model factory function (backward compatible).\n *\n * @example\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n {},\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n static define(options: {\n name: PluginName;\n data: PluginDataModel<any, any, any> | ((config?: any) => DataModel<any>);\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder {\n if (options.data instanceof PluginDataModel) {\n const pdm = options.data;\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: () => pdm.dataModel,\n getDefaultDataFn: (config: any) => pdm.getDefaultData(config),\n featureFlags: options.featureFlags,\n });\n }\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: options.data,\n featureFlags: options.featureFlags,\n });\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices> {\n /** Create a named plugin instance, optionally with transfer at a specific version. */\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n >;\n\n /** Public output field definitions declared via .publicOutput(). */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n config: Config;\n versions: Versions;\n publicOutputs: PublicOutputs;\n };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> implements PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n> {\n private readonly name: PluginName;\n private readonly dataFn: (config?: Config) => DataModel<Data>;\n private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelFactory(options);\n }\n\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n > {\n const transferVersion = options.transferAt ?? NO_TRANSFER_VERSION;\n return PluginInstance[FROM_BUILDER]<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n Config,\n ModelServices,\n UiServices\n >(options.pluginId as Id, this, transferVersion, options.config);\n }\n\n /** @internal Create a PluginModel from config. Config is captured in getDefaultData closure. */\n [CREATE_PLUGIN_MODEL](\n config?: Config,\n ): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n const dataModel = this.dataFn(config);\n const getDefaultDataFn = this.getDefaultDataFn;\n return PluginModel[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataModel,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n getDefaultData: getDefaultDataFn\n ? () => getDefaultDataFn(config)\n : () => dataModel.getDefaultData(),\n publicOutputDef: this.publicOutputDef,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n * @typeParam Versions - Version map from PluginDataModel (empty for function-based data)\n *\n * @example\n * const dataTable = PluginModel.define({\n * name: 'dataTable' as PluginName,\n * data: pluginDataModel,\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> {\n protected readonly name: PluginName;\n protected readonly dataFn: (config?: Config) => DataModel<Data>;\n protected readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n private readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n protected readonly featureFlags?: BlockCodeKnownFeatureFlags;\n private readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n protected constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs =\n options.outputs ?? ({} as PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>);\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n * All plugin outputs are always wrapped with status — the UI receives\n * {@link OutputWithStatus} for every output, allowing it to distinguish\n * between pending, success, and error states.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns Builder with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('pFrame', (ctx) => ctx.createPFrame([...]))\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n ) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as unknown as PluginOutputFns<\n Data,\n Params,\n Outputs & { [P in Key]: OutputWithStatus<T> },\n ModelServices,\n UiServices\n >,\n publicOutputDef: this.publicOutputDef,\n });\n }\n\n /**\n * Exposes a plugin data field as a public output — accessible without `usePlugin()`\n * via `app.plugins.pluginName.publicOutputs.key`.\n *\n * The getter runs against the plugin's reactive data object.\n * Public outputs are read-only.\n *\n * @param key - Name of the public output field\n * @param getter - Function deriving the value from plugin data\n *\n * @example\n * .publicOutput('selection', (d) => d.selection)\n */\n publicOutput<const Key extends string, T>(\n key: Key,\n getter: (data: Data) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: this.outputs,\n publicOutputDef: {\n ...this.publicOutputDef,\n [key]: { getter: getter as (data: unknown) => unknown },\n } as PublicOutputDef<PublicOutputs & { [K in Key]: T }>,\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a PluginFactory.\n *\n * @returns Plugin factory that creates named plugin instances via .create()\n *\n * @example\n * const myPlugin = PluginModel.define({ ... })\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Create a named instance:\n * const table = myPlugin.create({ pluginId: 'mainTable', config: { ... } });\n */\n build(): PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelFactory[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n outputs: this.outputs,\n publicOutputDef: this.publicOutputDef,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Initial builder returned by PluginModel.define(). Extends PluginModelBuilder with .params().\n * Once .params() or .output() is called, transitions to PluginModelBuilder (no second .params()).\n */\nclass PluginModelInitialBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginModelBuilder<Data, Params, {}, {}, Config, Versions, ModelServices, UiServices> {\n /** @internal */\n static create<\n Data extends PluginData,\n Config extends PluginConfig,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder<Data, undefined, Config, Versions, ModelServices, UiServices> {\n return new PluginModelInitialBuilder({ ...options, publicOutputDef: {} });\n }\n\n /**\n * Sets the Params type for this plugin — the shape of data derived from the block's\n * render context and passed into plugin output functions via `ctx.params`.\n * Must be called before .output(). Available only on the initial builder.\n *\n * @example\n * .params<{ title: string }>()\n * .output('displayText', (ctx) => ctx.params.title)\n */\n params<P extends PluginParams>(): PluginModelBuilder<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelBuilder[FROM_BUILDER]<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n publicOutputDef: {},\n });\n }\n}\n"],"mappings":"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"}
@@ -12,7 +12,8 @@ declare const FROM_BUILDER: unique symbol;
12
12
  type PluginOutputFn<Data extends PluginData, Params extends PluginParams, ModelServices, UiServices, T> = (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>>) => T;
13
13
  /** Mapped output functions for a plugin's outputs. */
14
14
  type PluginOutputFns<Data extends PluginData, Params extends PluginParams, Outputs extends PluginOutputs, ModelServices, UiServices> = { [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]> };
15
- /** Symbol for internal plugin model creation — not accessible to external consumers */
15
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
16
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
16
17
  declare const CREATE_PLUGIN_MODEL: unique symbol;
17
18
  /**
18
19
  * Runtime definition for a single public output field.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.d.ts","names":[],"sources":["../src/plugin_model.ts"],"mappings":";;;;;;;;AAuB0C;AAAA,cAApC,YAAA;;KAGD,cAAA,cACU,UAAA,iBACE,YAAA,mCAKf,GAAA,EAAK,eAAA,CACH,iBAAA,CAAkB,IAAA,EAAM,MAAA,EAAQ,MAAA,mBAAyB,aAAA,EAAe,UAAA,OAEvE,CAAA;;KAGA,eAAA,cACU,UAAA,iBACE,YAAA,kBACC,aAAA,6CAIJ,OAAA,GAAU,cAAA,CAAe,IAAA,EAAM,MAAA,EAAQ,aAAA,EAAe,UAAA,EAAY,OAAA,CAAQ,CAAA;;cAI3E,mBAAA;;;;;KASD,oBAAA;EAAA,SACD,MAAA,GAAS,IAAA;AAAA;AAAA,KAGR,eAAA,uBAAsC,mBAAA,kBACpC,aAAA,GAAgB,oBAAA;AAAA,KAGlB,UAAA,GAAa,MAAA;AAAA,KACb,YAAA,eAA2B,MAAA;AAAA,KAC3B,aAAA,GAAgB,MAAA;AAAA,KAChB,mBAAA,GAAsB,MAAA;AAAA,KACtB,YAAA,eAA2B,MAAA;;;;;;;;cAS1B,eAAA,cACE,UAAA,mBACI,MAAA;EAAA,SAGR,SAAA,EAAW,SAAA,CAAU,IAAA;EAAA,iBACb,YAAA;EA/CC;EAAA,SAkDD,UAAA,GAAa,QAAA;EAAA,QAEvB,WAAA,CAAA;EAjDS;EAAA,QAuDR,YAAA,eAA2B,UAAA,mBAA6B,MAAA,2BAC9D,SAAA,EAAW,SAAA,CAAU,IAAA,GACrB,YAAA,GAAe,MAAA,GAAS,MAAA,KAAW,IAAA,GAClC,eAAA,CAAgB,IAAA,EAAM,QAAA,EAAU,MAAA;EAtDE;EA2DrC,cAAA,CAAe,MAAA,GAAS,MAAA,GAAS,aAAA,CAAc,IAAA;AAAA;;KAO5C,gBAAA;EACH,cAAA;EACA,UAAA,EAAY,KAAA;IAAQ,SAAA;IAAmB,EAAA,GAAK,IAAA;EAAA;EAC5C,SAAA,IAAa,OAAA,UAAiB,IAAA;EAC9B,cAAA;AAAA;;KAIU,uBAAA,WACA,eAAA,CAAgB,UAAA,EAAY,MAAA,+BACpC,CAAA,SAAU,eAAA,CAAgB,UAAA,6BAAuC,QAAA;;;;;;;;;;;;;;cAexD,sBAAA;EACX,IAAA,cAAkB,UAAA,yBAAA,CAChB,OAAA,EAAS,CAAA,GACR,2BAAA,CAA4B,IAAA,EAAM,MAAA,CAAO,CAAA,EAAG,IAAA;AAAA;;;AAjFjD;;cA6Fa,oBAAA,cACE,UAAA,mBACI,MAAA;EAAA,mBAEwB,KAAA,EAAO,gBAAA;EAAA,UAAvC,WAAA,CAAgC,KAAA,EAAO,gBAAA;EA7FtC;EAAA,QAgGF,YAAA,eAA2B,UAAA,mBAA6B,MAAA,mBAC9D,KAAA,EAAO,gBAAA,GACN,oBAAA,CAAqB,IAAA,EAAM,QAAA;EAlGL;;;EAyGzB,OAAA,cAAqB,UAAA,6BAAA,CACnB,OAAA,EAAS,KAAA,EACT,EAAA,GAAK,OAAA,EAAS,IAAA,KAAS,IAAA,GACtB,oBAAA,CAAqB,IAAA,EAAM,QAAA,GAAW,MAAA,CAAO,KAAA,EAAO,IAAA;EA3GP;;;;EAyHhD,OAAA,CAAQ,EAAA,EAAI,aAAA,CAAc,IAAA,IAAQ,0BAAA,CAA2B,IAAA,EAAM,QAAA;EAzHvD;EAkIZ,IAAA,oBAAA,CAAyB,EAAA,GAAK,MAAA,GAAS,MAAA,KAAW,IAAA,GAAO,eAAA,CAAgB,IAAA,EAAM,QAAA,EAAU,MAAA;AAAA;;AA/H3F;;;;cAyIa,2BAAA,cACE,UAAA,mBACI,MAAA,2BACT,oBAAA,CAAqB,IAAA,EAAM,QAAA;EA3IzB;EAAA,QA6IO,YAAA,eAA2B,UAAA,mBAA6B,MAAA,mBACvE,KAAA,EAAO,gBAAA,GACN,2BAAA,CAA4B,IAAA,EAAM,QAAA;;;;AA9IvC;;;;;AACA;;;EA4JE,aAAA,CAAc,EAAA,GAAK,IAAA,cAAkB,IAAA,GAAO,0BAAA,CAA2B,IAAA,EAAM,QAAA;AAAA;AA3J/E;;;AAAA,cA0Ka,0BAAA,cACE,UAAA,mBACI,MAAA;EAAA,iBAEoB,KAAA;EAAA,QAA9B,WAAA,CAAA;EArKmB;EAAA,QAwKlB,YAAA,eAA2B,UAAA,mBAA6B,MAAA,mBAC9D,KAAA,EAAO,gBAAA,GACN,0BAAA,CAA2B,IAAA,EAAM,QAAA;EAIpC,OAAA,cAAqB,UAAA,6BAAA,CACnB,OAAA,EAAS,KAAA,EACT,EAAA,GAAK,OAAA,EAAS,IAAA,KAAS,IAAA,GACtB,0BAAA,CAA2B,IAAA,EAAM,QAAA,GAAW,MAAA,CAAO,KAAA,EAAO,IAAA;EAU7D,IAAA,oBAAA,CAAyB,EAAA,GAAK,MAAA,GAAS,MAAA,KAAW,IAAA,GAAO,eAAA,CAAgB,IAAA,EAAM,QAAA,EAAU,MAAA;AAAA;;;;;;;;;;;;cAiD9E,cAAA,0CAEE,UAAA,GAAa,UAAA,iBACX,YAAA,8BACC,aAAA,GAAgB,aAAA,wBACV,mBAAA,GAAsB,mBAAA,kFAIjC,cAAA,CAAe,EAAA,EAAI,YAAA;EAAA,SACrB,EAAA,EAAI,EAAA;EAAA,SACJ,eAAA;EA9NsC;EAAA,SAgOtC,eAAA;IACP,IAAA,EAAM,IAAA;IACN,MAAA,EAAQ,MAAA;IACR,OAAA,EAAS,OAAA;IACT,aAAA,EAAe,aAAA;IACf,UAAA,EAAY,UAAA;IACZ,aAAA,EAAe,aAAA;EAAA;EA1PR;EAAA,iBA6PQ,iBAAA;EAAA,QASV,WAAA,CAAA;EArQU;EAAA,QAuRT,YAAA,kCAEO,UAAA,iBACE,YAAA,kBACC,aAAA,wBACM,mBAAA,GAAsB,mBAAA,uCAE7B,YAAA,GAAe,YAAA,iDAI9B,EAAA,EAAI,EAAA,EACJ,OAAA,EAAS,kBAAA,CACP,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACA,MAAA,mBACA,aAAA,EACA,UAAA,GAEF,eAAA,UACA,MAAA,GAAS,MAAA,GACR,cAAA,CACD,EAAA,EACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,YAAA,EACA,aAAA,EACA,UAAA;EApT4B;EAAA,CA0T7B,mBAAA,KAAwB,WAAA,CACvB,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,aAAA,EACA,UAAA;AAAA;;;;;cAUS,WAAA,cACE,UAAA,GAAa,UAAA,iBACX,YAAA,8BACC,aAAA,GAAgB,aAAA,wBACV,mBAAA,GAAsB,mBAAA;EArU/B;EAAA,SA0UJ,IAAA,EAAM,UAAA;EA1Ub;EAAA,SA4UO,SAAA,EAAW,SAAA,CAAU,IAAA;EA3Ub;EAAA,SA6UR,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;EA7UtE;EAAA,SA+UO,YAAA,GAAe,0BAAA;EA9UL;EAAA,SAgVV,cAAA,QAAsB,aAAA,CAAc,IAAA;EAhVV;EAAA,SAkV1B,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA,QAEnC,WAAA,CAAA;EA/UQ;;;;;EAAA,QAoWP,YAAA,eACO,UAAA,iBACE,YAAA,kBACC,aAAA,wBACM,mBAAA,GAAsB,mBAAA,uCAG5C,OAAA;IACA,IAAA,EAAM,UAAA;IACN,SAAA,EAAW,SAAA,CAAU,IAAA;IACrB,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;IAC/D,YAAA,GAAe,0BAAA;IACf,cAAA,QAAsB,aAAA,CAAc,IAAA;IACpC,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA,IAC/B,WAAA,CAAY,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,aAAA,EAAe,UAAA;EAzW9B;;;;;;;;AAMzC;;;;;;;;EANyC,OA+XhC,MAAA,cACQ,UAAA,iBACE,YAAA,+BACE,MAAA,uCACF,YAAA,4BACD,0BAAA,MAAA,CACd,OAAA;IACA,IAAA,EAAM,UAAA;IACN,IAAA,EAAM,eAAA,CAAgB,IAAA,EAAM,QAAA,EAAU,MAAA;IACtC,YAAA,GAAe,KAAA;EAAA,IACb,yBAAA,CACF,IAAA,EACA,MAAA,EACA,MAAA,EACA,QAAA,EACA,oBAAA,CAAqB,KAAA,GACrB,iBAAA,CAAkB,KAAA;EAxYM;;;;;;;;;EAAA,OAmZnB,MAAA,cACQ,UAAA,iBACE,YAAA,6BACA,YAAA,4BACD,0BAAA,MAAA,CACd,OAAA;IACA,IAAA,EAAM,UAAA;IACN,IAAA,GAAO,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;IACrC,YAAA,GAAe,KAAA;EAAA,IACb,yBAAA,CACF,IAAA,EACA,MAAA,EACA,MAAA,MAEA,oBAAA,CAAqB,KAAA,GACrB,iBAAA,CAAkB,KAAA;AAAA;;UAyBL,aAAA,cACF,UAAA,GAAa,UAAA,iBACX,YAAA,8BACC,aAAA,GAAgB,aAAA,wBACV,mBAAA,GAAsB,mBAAA,iBAC7B,YAAA,+BACE,MAAA,qEAGT,iBAAA,CAAkB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;EAjb3B;EAmbrC,MAAA,yDAA+D,QAAA,UAAkB,OAAA;IAC/E,QAAA,EAAU,EAAA;IACV,UAAA,GAAa,CAAA;IACb,MAAA,GAAS,MAAA;EAAA,IACP,cAAA,CACF,EAAA,EACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,QAAA,CAAS,CAAA,GACT,aAAA,EACA,UAAA;EAjcgB;EAAA,SAqcT,eAAA,EAAiB,eAAA,CAAgB,aAAA;EApc/B;;;;EAAA,SA0cF,OAAA;IACP,IAAA,EAAM,IAAA;IACN,MAAA,EAAQ,MAAA;IACR,OAAA,EAAS,OAAA;IACT,aAAA,EAAe,aAAA;IACf,UAAA,EAAY,UAAA;IACZ,MAAA,EAAQ,MAAA;IACR,QAAA,EAAU,QAAA;IACV,aAAA,EAAe,aAAA;EAAA;AAAA;AAAA,cAIb,kBAAA,cACS,UAAA,GAAa,UAAA,iBACX,YAAA,8BACC,aAAA,GAAgB,aAAA,wBACV,mBAAA,GAAsB,mBAAA,iBAC7B,YAAA,+BACE,MAAA,wEAGN,aAAA,CACX,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;EAAA,iBAEiB,IAAA;EAAA,iBACA,MAAA;EAAA,iBACA,gBAAA;EAAA,SACR,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;EAAA,iBACvD,YAAA;EAAA,SACR,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA,QAEnC,WAAA,CAAA;EAndc;EAAA,QAoeb,YAAA,eACO,UAAA,iBACE,YAAA,kBACC,aAAA,wBACM,mBAAA,GAAsB,mBAAA,iBAC7B,YAAA,+BACE,MAAA,6DAGjB,OAAA;IACA,IAAA,EAAM,UAAA;IACN,MAAA,GAAS,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;IACvC,gBAAA,IAAoB,MAAA,GAAS,MAAA,KAAW,aAAA,CAAc,IAAA;IACtD,OAAA,EAAS,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;IAC/D,YAAA,GAAe,0BAAA;IACf,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA,IAC/B,kBAAA,CACF,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;EAKF,MAAA,yDAA+D,QAAA,SAAA,CAAkB,OAAA;IAC/E,QAAA,EAAU,EAAA;IACV,UAAA,GAAa,CAAA;IACb,MAAA,GAAS,MAAA;EAAA,IACP,cAAA,CACF,EAAA,EACA,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,QAAA,CAAS,CAAA,GACT,aAAA,EACA,UAAA;EA5fgC;EAAA,CA6gBjC,mBAAA,EACC,MAAA,GAAS,MAAA,GACR,WAAA,CAAY,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,aAAA,EAAe,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;cA0ChE,kBAAA,cACS,UAAA,GAAa,UAAA,iBACX,YAAA,8BACC,aAAA,GAAgB,aAAA,wBACV,mBAAA,GAAsB,mBAAA,iBAC7B,YAAA,+BACE,MAAA;EAAA,mBAIE,IAAA,EAAM,UAAA;EAAA,mBACN,MAAA,GAAS,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;EAAA,mBACvC,gBAAA,IAAoB,MAAA,GAAS,MAAA,KAAW,aAAA,CAAc,IAAA;EAAA,iBACxD,OAAA;EAAA,mBACE,YAAA,GAAe,0BAAA;EAAA,iBACjB,eAAA;EAAA,UAER,WAAA,CAAa,OAAA;IACpB,IAAA,EAAM,UAAA;IACN,MAAA,GAAS,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;IACvC,gBAAA,IAAoB,MAAA,GAAS,MAAA,KAAW,aAAA,CAAc,IAAA;IACtD,OAAA,GAAU,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;IAChE,YAAA,GAAe,0BAAA;IACf,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA;EA/lBjC;EAAA,QA2mBM,YAAA,eACO,UAAA,iBACE,YAAA,kBACC,aAAA,wBACM,mBAAA,GAAsB,mBAAA,iBAC7B,YAAA,+BACE,MAAA,6DAGjB,OAAA;IACA,IAAA,EAAM,UAAA;IACN,MAAA,GAAS,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;IACvC,gBAAA,IAAoB,MAAA,GAAS,MAAA,KAAW,aAAA,CAAc,IAAA;IACtD,OAAA,GAAU,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAA,EAAe,UAAA;IAChE,YAAA,GAAe,0BAAA;IACf,eAAA,EAAiB,eAAA,CAAgB,aAAA;EAAA,IAC/B,kBAAA,CACF,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;EApnBwB;;;;;;;;;;;;;;EAuoB1B,MAAA,6BAAA,CACE,GAAA,EAAK,GAAA,EACL,EAAA,GACE,GAAA,EAAK,eAAA,CACH,iBAAA,CAAkB,IAAA,EAAM,MAAA,EAAQ,MAAA,mBAAyB,aAAA,EAAe,UAAA,OAEvE,CAAA,GACJ,kBAAA,CACD,IAAA,EACA,MAAA,EACA,OAAA,WAAkB,GAAA,GAAM,gBAAA,CAAiB,CAAA,KACzC,aAAA,EACA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;EAnoBS;;;;;;;;;;;;;EA8qBX,YAAA,6BAAA,CACE,GAAA,EAAK,GAAA,EACL,MAAA,GAAS,IAAA,EAAM,IAAA,KAAS,CAAA,GACvB,kBAAA,CACD,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,WAAwB,GAAA,GAAM,CAAA,IAC9B,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;EAnqB2E;;;;;;;;;;;;;EAwsB7E,KAAA,CAAA,GAAS,aAAA,CACP,IAAA,EACA,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;AAAA;;;;;cA0BE,yBAAA,cACS,UAAA,GAAa,UAAA,iBACX,YAAA,6BACA,YAAA,+BACE,MAAA,qEAGT,kBAAA,CAAmB,IAAA,EAAM,MAAA,UAAgB,MAAA,EAAQ,QAAA,EAAU,aAAA,EAAe,UAAA;EAhwBnD;EAAA,OAkwBxB,MAAA,cACQ,UAAA,iBACE,YAAA,mBACE,MAAA,4DAAA,CAGjB,OAAA;IACA,IAAA,EAAM,UAAA;IACN,MAAA,GAAS,MAAA,GAAS,MAAA,KAAW,SAAA,CAAU,IAAA;IACvC,gBAAA,IAAoB,MAAA,GAAS,MAAA,KAAW,aAAA,CAAc,IAAA;IACtD,YAAA,GAAe,0BAAA;EAAA,IACb,yBAAA,CAA0B,IAAA,aAAiB,MAAA,EAAQ,QAAA,EAAU,aAAA,EAAe,UAAA;EA9vBT;;;;AAezE;;;;;EA4vBE,MAAA,WAAiB,YAAA,CAAA,CAAA,GAAiB,kBAAA,CAChC,IAAA,EACA,CAAA,UAGA,MAAA,EACA,QAAA,EACA,aAAA,EACA,UAAA;AAAA"}
1
+ {"version":3,"file":"plugin_model.d.ts","names":[],"sources":["../src/plugin_model.ts"],"mappings":"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"}
@@ -3,8 +3,9 @@ import { DATA_MODEL_LEGACY_VERSION } from "./block_storage.js";
3
3
  //#region src/plugin_model.ts
4
4
  /** Symbol for internal builder creation method */
5
5
  const FROM_BUILDER = Symbol("fromBuilder");
6
- /** Symbol for internal plugin model creation — not accessible to external consumers */
7
- const CREATE_PLUGIN_MODEL = Symbol("createPluginModel");
6
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
7
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
8
+ const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
8
9
  /** Sentinel for PluginInstance without transferAt — no transfer possible. */
9
10
  const NO_TRANSFER_VERSION = "";
10
11
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.js","names":[],"sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags, OutputWithStatus } from \"@milaboratories/pl-model-common\";\nimport type { ResolveModelServices, ResolveUiServices } from \"./services/service_resolve\";\nimport {\n type DataModel,\n DataModelBuilder,\n type DataRecoverFn,\n type DataVersioned,\n type TransferTarget,\n} from \"./block_migrations\";\nimport { type PluginName, DATA_MODEL_LEGACY_VERSION } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n/** Output function signature for plugin render context. */\ntype PluginOutputFn<\n Data extends PluginData,\n Params extends PluginParams,\n ModelServices,\n UiServices,\n T,\n> = (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n) => T;\n\n/** Mapped output functions for a plugin's outputs. */\ntype PluginOutputFns<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n ModelServices,\n UiServices,\n> = {\n [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;\n};\n\n/** Symbol for internal plugin model creation — not accessible to external consumers */\nexport const CREATE_PLUGIN_MODEL = Symbol(\"createPluginModel\");\n\n/** Sentinel for PluginInstance without transferAt — no transfer possible. */\nconst NO_TRANSFER_VERSION = \"\";\n\n/**\n * Runtime definition for a single public output field.\n * Stored in PluginModel and passed through BlockModelInfo to the UI layer.\n */\nexport type PublicOutputFieldDef = {\n readonly getter: (data: unknown) => unknown;\n};\n\nexport type PublicOutputDef<PublicOutputs extends PluginPublicOutputs> = {\n [K in keyof PublicOutputs]: PublicOutputFieldDef;\n};\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginPublicOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Plugin data model with typed migration chain and config-aware initialization.\n *\n * @typeParam Data - Current (latest) plugin data type\n * @typeParam Versions - Map of version keys to their data types (accumulated by the chain)\n * @typeParam Config - Config type passed to init function (undefined if none)\n */\nexport class PluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown> = {},\n Config = undefined,\n> {\n readonly dataModel: DataModel<Data>;\n private readonly configInitFn: (config?: Config) => Data;\n\n /** @internal Phantom field to anchor the Versions type parameter. */\n declare readonly __versions?: Versions;\n\n private constructor(dataModel: DataModel<Data>, configInitFn: (config?: Config) => Data) {\n this.dataModel = dataModel;\n this.configInitFn = configInitFn;\n }\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>, Config>(\n dataModel: DataModel<Data>,\n configInitFn: (config?: Config) => Data,\n ): PluginDataModel<Data, Versions, Config> {\n return new PluginDataModel<Data, Versions, Config>(dataModel, configInitFn);\n }\n\n /** Create fresh data with optional config. */\n getDefaultData(config?: Config): DataVersioned<Data> {\n const data = this.configInitFn(config);\n return { version: this.dataModel.version, data };\n }\n}\n\n/** Internal state for plugin data model chain. */\ntype PluginChainState = {\n initialVersion: string;\n migrations: Array<{ toVersion: string; fn: (data: unknown) => unknown }>;\n recoverFn?: (version: string, data: unknown) => unknown;\n recoverAtIndex?: number;\n};\n\n/** Version → persisted data shape for each migration step (third generic of `PluginModel.define` when `data` is a `PluginDataModel`). */\nexport type PluginDataModelVersions<\n M extends PluginDataModel<PluginData, Record<string, unknown>, unknown>,\n> = M extends PluginDataModel<PluginData, infer Versions, unknown> ? Versions : never;\n\n/**\n * Builder for creating PluginDataModel with type-safe migrations.\n * Mirrors DataModelBuilder — same .from(), .migrate(), .recover(), .init() chain.\n *\n * @example\n * const pluginData = new PluginDataModelBuilder()\n * .from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n */\nexport class PluginDataModelBuilder {\n from<Data extends PluginData, const V extends string>(\n version: V,\n ): PluginDataModelInitialChain<Data, Record<V, Data>> {\n return PluginDataModelInitialChain[FROM_BUILDER]<Data, Record<V, Data>>({\n initialVersion: version,\n migrations: [],\n });\n }\n}\n\n/**\n * Chain returned by .migrate(). Supports .migrate(), .recover(), .init().\n * No .upgradeLegacy() — that is only available on the initial chain.\n */\nexport class PluginDataModelChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n protected constructor(protected readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelChain<Data, Versions> {\n return new PluginDataModelChain(state);\n }\n\n /**\n * Add a migration step transforming data from the current version to the next.\n */\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelChain<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelChain[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n /**\n * Set a recovery handler for unknown or legacy versions.\n * Can only be called once — the returned chain has no recover() method.\n */\n recover(fn: DataRecoverFn<Data>): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n recoverFn: fn as (version: string, data: unknown) => unknown,\n recoverAtIndex: this.state.migrations.length,\n });\n }\n\n /** Finalize the PluginDataModel. */\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Initial chain returned by new PluginDataModelBuilder().from().\n * Extends PluginDataModelChain with .upgradeLegacy() — available only before\n * any .migrate() calls, matching the block's DataModelInitialChain pattern.\n */\nexport class PluginDataModelInitialChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> extends PluginDataModelChain<Data, Versions> {\n /** @internal */\n static override [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelInitialChain<Data, Versions> {\n return new PluginDataModelInitialChain(state);\n }\n\n /**\n * Handle data from a previous plugin type occupying this slot.\n * Prepends a migration from DATA_MODEL_LEGACY_VERSION to the initial version.\n * When a plugin type changes, the old data arrives with DATA_MODEL_LEGACY_VERSION —\n * this function transforms it into the initial version, then the normal chain runs.\n *\n * Must be called right after .from() — not available after .migrate().\n * Mutually exclusive with recover().\n *\n * @param fn - Transform from old plugin's raw data to this plugin's initial data type\n */\n upgradeLegacy(fn: (data: unknown) => Data): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n migrations: [\n { toVersion: this.state.initialVersion, fn: fn as (data: unknown) => unknown },\n ...this.state.migrations,\n ],\n initialVersion: DATA_MODEL_LEGACY_VERSION,\n });\n }\n}\n\n/**\n * Chain after .recover() — supports .migrate(), .init(). No second recover().\n */\nexport class PluginDataModelWithRecover<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n private constructor(private readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelWithRecover<Data, Versions> {\n return new PluginDataModelWithRecover(state);\n }\n\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelWithRecover<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Builds a PluginDataModel by replaying the stored chain state through DataModelBuilder.\n * @internal\n */\nfunction buildPluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n Config,\n>(\n state: PluginChainState,\n configInitFn: (config?: Config) => Data,\n): PluginDataModel<Data, Versions, Config> {\n // Build inner DataModel by replaying migrations through DataModelBuilder chain.\n // Uses `any` internally — type safety is maintained by the public chain types.\n let chain: any = new DataModelBuilder().from(state.initialVersion);\n\n for (let i = 0; i < state.migrations.length; i++) {\n if (state.recoverFn !== undefined && state.recoverAtIndex === i) {\n chain = chain.recover(state.recoverFn);\n }\n chain = chain.migrate(state.migrations[i].toVersion, state.migrations[i].fn);\n }\n\n // If recover was placed at or after the last migration\n if (state.recoverFn !== undefined && state.recoverAtIndex === state.migrations.length) {\n chain = chain.recover(state.recoverFn);\n }\n\n const dataModel: DataModel<Data> = chain.init(() => configInitFn());\n\n return PluginDataModel[FROM_BUILDER]<Data, Versions, Config>(dataModel, configInitFn);\n}\n\n/**\n * A named plugin instance created by `factory.create({ pluginId, ... })`.\n * Passed to both `.transfer()` (on migration chain) and `.plugin()` (on BlockModelV3).\n * Implements TransferTarget so the migration chain can accept it.\n *\n * @typeParam Id - Plugin instance ID literal type\n * @typeParam Data - Plugin data type\n * @typeParam Params - Plugin params type\n * @typeParam Outputs - Plugin outputs type\n * @typeParam TransferData - Type of data entering the plugin via transfer (never if no transfer)\n */\nexport class PluginInstance<\n Id extends string = string,\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n ModelServices = unknown,\n UiServices = unknown,\n> implements TransferTarget<Id, TransferData> {\n readonly id: Id;\n readonly transferVersion: string;\n /** @internal Phantom for type inference; never set at runtime. */\n readonly __instanceTypes?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n publicOutputs: PublicOutputs;\n };\n /** Bound closure that creates the PluginModel. Config is captured at factory.create() time. */\n private readonly createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >;\n\n private constructor(\n id: Id,\n createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n ) {\n this.id = id;\n this.createPluginModel = createPluginModel;\n this.transferVersion = transferVersion;\n }\n\n /** @internal Accepts concrete Config — binds it into a closure, avoiding Config variance issues. */\n static [FROM_BUILDER]<\n Id extends string,\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n Config extends PluginConfig = PluginConfig,\n ModelServices = unknown,\n UiServices = unknown,\n >(\n id: Id,\n factory: PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Record<string, unknown>,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n config?: Config,\n ): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n TransferData,\n ModelServices,\n UiServices\n > {\n return new PluginInstance(id, () => factory[CREATE_PLUGIN_MODEL](config), transferVersion);\n }\n\n /** @internal Create a PluginModel from this instance. Used by BlockModelV3.plugin(). */\n [CREATE_PLUGIN_MODEL](): PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n > {\n return this.createPluginModel();\n }\n}\n\n/**\n * Configured plugin instance returned by PluginModelFactory[CREATE_PLUGIN_MODEL]().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n /** Create fresh default data. Config (if any) is captured at creation time. */\n readonly getDefaultData: () => DataVersioned<Data>;\n /** Public output definitions — accessible without usePlugin() via app.plugins */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.getDefaultData = options.getDefaultData;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n return new PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices>(\n options,\n );\n }\n\n /**\n * Creates a new PluginModelBuilder with a PluginDataModel (supports transfer / config).\n *\n * @example\n * const pluginData = new PluginDataModelBuilder().from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: pluginData,\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Versions extends Record<string, unknown> = {},\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: PluginDataModel<Data, Versions, Config>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n Versions,\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n /**\n * Creates a new PluginModelBuilder with a data model factory function (backward compatible).\n *\n * @example\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n {},\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n static define(options: {\n name: PluginName;\n data: PluginDataModel<any, any, any> | ((config?: any) => DataModel<any>);\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder {\n if (options.data instanceof PluginDataModel) {\n const pdm = options.data;\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: () => pdm.dataModel,\n getDefaultDataFn: (config: any) => pdm.getDefaultData(config),\n featureFlags: options.featureFlags,\n });\n }\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: options.data,\n featureFlags: options.featureFlags,\n });\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices> {\n /** Create a named plugin instance, optionally with transfer at a specific version. */\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n >;\n\n /** Public output field definitions declared via .publicOutput(). */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n config: Config;\n versions: Versions;\n publicOutputs: PublicOutputs;\n };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> implements PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n> {\n private readonly name: PluginName;\n private readonly dataFn: (config?: Config) => DataModel<Data>;\n private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelFactory(options);\n }\n\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n > {\n const transferVersion = options.transferAt ?? NO_TRANSFER_VERSION;\n return PluginInstance[FROM_BUILDER]<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n Config,\n ModelServices,\n UiServices\n >(options.pluginId as Id, this, transferVersion, options.config);\n }\n\n /** @internal Create a PluginModel from config. Config is captured in getDefaultData closure. */\n [CREATE_PLUGIN_MODEL](\n config?: Config,\n ): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n const dataModel = this.dataFn(config);\n const getDefaultDataFn = this.getDefaultDataFn;\n return PluginModel[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataModel,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n getDefaultData: getDefaultDataFn\n ? () => getDefaultDataFn(config)\n : () => dataModel.getDefaultData(),\n publicOutputDef: this.publicOutputDef,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n * @typeParam Versions - Version map from PluginDataModel (empty for function-based data)\n *\n * @example\n * const dataTable = PluginModel.define({\n * name: 'dataTable' as PluginName,\n * data: pluginDataModel,\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> {\n protected readonly name: PluginName;\n protected readonly dataFn: (config?: Config) => DataModel<Data>;\n protected readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n private readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n protected readonly featureFlags?: BlockCodeKnownFeatureFlags;\n private readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n protected constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs =\n options.outputs ?? ({} as PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>);\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n * All plugin outputs are always wrapped with status — the UI receives\n * {@link OutputWithStatus} for every output, allowing it to distinguish\n * between pending, success, and error states.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns Builder with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('pFrame', (ctx) => ctx.createPFrame([...]))\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n ) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as unknown as PluginOutputFns<\n Data,\n Params,\n Outputs & { [P in Key]: OutputWithStatus<T> },\n ModelServices,\n UiServices\n >,\n publicOutputDef: this.publicOutputDef,\n });\n }\n\n /**\n * Exposes a plugin data field as a public output — accessible without `usePlugin()`\n * via `app.plugins.pluginName.publicOutputs.key`.\n *\n * The getter runs against the plugin's reactive data object.\n * Public outputs are read-only.\n *\n * @param key - Name of the public output field\n * @param getter - Function deriving the value from plugin data\n *\n * @example\n * .publicOutput('selection', (d) => d.selection)\n */\n publicOutput<const Key extends string, T>(\n key: Key,\n getter: (data: Data) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: this.outputs,\n publicOutputDef: {\n ...this.publicOutputDef,\n [key]: { getter: getter as (data: unknown) => unknown },\n } as PublicOutputDef<PublicOutputs & { [K in Key]: T }>,\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a PluginFactory.\n *\n * @returns Plugin factory that creates named plugin instances via .create()\n *\n * @example\n * const myPlugin = PluginModel.define({ ... })\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Create a named instance:\n * const table = myPlugin.create({ pluginId: 'mainTable', config: { ... } });\n */\n build(): PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelFactory[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n outputs: this.outputs,\n publicOutputDef: this.publicOutputDef,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Initial builder returned by PluginModel.define(). Extends PluginModelBuilder with .params().\n * Once .params() or .output() is called, transitions to PluginModelBuilder (no second .params()).\n */\nclass PluginModelInitialBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginModelBuilder<Data, Params, {}, {}, Config, Versions, ModelServices, UiServices> {\n /** @internal */\n static create<\n Data extends PluginData,\n Config extends PluginConfig,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder<Data, undefined, Config, Versions, ModelServices, UiServices> {\n return new PluginModelInitialBuilder({ ...options, publicOutputDef: {} });\n }\n\n /**\n * Sets the Params type for this plugin — the shape of data derived from the block's\n * render context and passed into plugin output functions via `ctx.params`.\n * Must be called before .output(). Available only on the initial builder.\n *\n * @example\n * .params<{ title: string }>()\n * .output('displayText', (ctx) => ctx.params.title)\n */\n params<P extends PluginParams>(): PluginModelBuilder<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelBuilder[FROM_BUILDER]<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n publicOutputDef: {},\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin_model.js","names":[],"sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags, OutputWithStatus } from \"@milaboratories/pl-model-common\";\nimport type { ResolveModelServices, ResolveUiServices } from \"./services/service_resolve\";\nimport {\n type DataModel,\n DataModelBuilder,\n type DataRecoverFn,\n type DataVersioned,\n type TransferTarget,\n} from \"./block_migrations\";\nimport { type PluginName, DATA_MODEL_LEGACY_VERSION } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n/** Output function signature for plugin render context. */\ntype PluginOutputFn<\n Data extends PluginData,\n Params extends PluginParams,\n ModelServices,\n UiServices,\n T,\n> = (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n) => T;\n\n/** Mapped output functions for a plugin's outputs. */\ntype PluginOutputFns<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n ModelServices,\n UiServices,\n> = {\n [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;\n};\n\n/** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays\n * identical across multiple `@platforma-sdk/model` copies in one process. */\nexport const CREATE_PLUGIN_MODEL = Symbol.for(\"@platforma-sdk/model:createPluginModel\");\n\n/** Sentinel for PluginInstance without transferAt — no transfer possible. */\nconst NO_TRANSFER_VERSION = \"\";\n\n/**\n * Runtime definition for a single public output field.\n * Stored in PluginModel and passed through BlockModelInfo to the UI layer.\n */\nexport type PublicOutputFieldDef = {\n readonly getter: (data: unknown) => unknown;\n};\n\nexport type PublicOutputDef<PublicOutputs extends PluginPublicOutputs> = {\n [K in keyof PublicOutputs]: PublicOutputFieldDef;\n};\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginPublicOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Plugin data model with typed migration chain and config-aware initialization.\n *\n * @typeParam Data - Current (latest) plugin data type\n * @typeParam Versions - Map of version keys to their data types (accumulated by the chain)\n * @typeParam Config - Config type passed to init function (undefined if none)\n */\nexport class PluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown> = {},\n Config = undefined,\n> {\n readonly dataModel: DataModel<Data>;\n private readonly configInitFn: (config?: Config) => Data;\n\n /** @internal Phantom field to anchor the Versions type parameter. */\n declare readonly __versions?: Versions;\n\n private constructor(dataModel: DataModel<Data>, configInitFn: (config?: Config) => Data) {\n this.dataModel = dataModel;\n this.configInitFn = configInitFn;\n }\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>, Config>(\n dataModel: DataModel<Data>,\n configInitFn: (config?: Config) => Data,\n ): PluginDataModel<Data, Versions, Config> {\n return new PluginDataModel<Data, Versions, Config>(dataModel, configInitFn);\n }\n\n /** Create fresh data with optional config. */\n getDefaultData(config?: Config): DataVersioned<Data> {\n const data = this.configInitFn(config);\n return { version: this.dataModel.version, data };\n }\n}\n\n/** Internal state for plugin data model chain. */\ntype PluginChainState = {\n initialVersion: string;\n migrations: Array<{ toVersion: string; fn: (data: unknown) => unknown }>;\n recoverFn?: (version: string, data: unknown) => unknown;\n recoverAtIndex?: number;\n};\n\n/** Version → persisted data shape for each migration step (third generic of `PluginModel.define` when `data` is a `PluginDataModel`). */\nexport type PluginDataModelVersions<\n M extends PluginDataModel<PluginData, Record<string, unknown>, unknown>,\n> = M extends PluginDataModel<PluginData, infer Versions, unknown> ? Versions : never;\n\n/**\n * Builder for creating PluginDataModel with type-safe migrations.\n * Mirrors DataModelBuilder — same .from(), .migrate(), .recover(), .init() chain.\n *\n * @example\n * const pluginData = new PluginDataModelBuilder()\n * .from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n */\nexport class PluginDataModelBuilder {\n from<Data extends PluginData, const V extends string>(\n version: V,\n ): PluginDataModelInitialChain<Data, Record<V, Data>> {\n return PluginDataModelInitialChain[FROM_BUILDER]<Data, Record<V, Data>>({\n initialVersion: version,\n migrations: [],\n });\n }\n}\n\n/**\n * Chain returned by .migrate(). Supports .migrate(), .recover(), .init().\n * No .upgradeLegacy() — that is only available on the initial chain.\n */\nexport class PluginDataModelChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n protected constructor(protected readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelChain<Data, Versions> {\n return new PluginDataModelChain(state);\n }\n\n /**\n * Add a migration step transforming data from the current version to the next.\n */\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelChain<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelChain[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n /**\n * Set a recovery handler for unknown or legacy versions.\n * Can only be called once — the returned chain has no recover() method.\n */\n recover(fn: DataRecoverFn<Data>): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n recoverFn: fn as (version: string, data: unknown) => unknown,\n recoverAtIndex: this.state.migrations.length,\n });\n }\n\n /** Finalize the PluginDataModel. */\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Initial chain returned by new PluginDataModelBuilder().from().\n * Extends PluginDataModelChain with .upgradeLegacy() — available only before\n * any .migrate() calls, matching the block's DataModelInitialChain pattern.\n */\nexport class PluginDataModelInitialChain<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> extends PluginDataModelChain<Data, Versions> {\n /** @internal */\n static override [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelInitialChain<Data, Versions> {\n return new PluginDataModelInitialChain(state);\n }\n\n /**\n * Handle data from a previous plugin type occupying this slot.\n * Prepends a migration from DATA_MODEL_LEGACY_VERSION to the initial version.\n * When a plugin type changes, the old data arrives with DATA_MODEL_LEGACY_VERSION —\n * this function transforms it into the initial version, then the normal chain runs.\n *\n * Must be called right after .from() — not available after .migrate().\n * Mutually exclusive with recover().\n *\n * @param fn - Transform from old plugin's raw data to this plugin's initial data type\n */\n upgradeLegacy(fn: (data: unknown) => Data): PluginDataModelWithRecover<Data, Versions> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Data, Versions>({\n ...this.state,\n migrations: [\n { toVersion: this.state.initialVersion, fn: fn as (data: unknown) => unknown },\n ...this.state.migrations,\n ],\n initialVersion: DATA_MODEL_LEGACY_VERSION,\n });\n }\n}\n\n/**\n * Chain after .recover() — supports .migrate(), .init(). No second recover().\n */\nexport class PluginDataModelWithRecover<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n> {\n private constructor(private readonly state: PluginChainState) {}\n\n /** @internal */\n static [FROM_BUILDER]<Data extends PluginData, Versions extends Record<string, unknown>>(\n state: PluginChainState,\n ): PluginDataModelWithRecover<Data, Versions> {\n return new PluginDataModelWithRecover(state);\n }\n\n migrate<Next extends PluginData, const NextV extends string>(\n version: NextV,\n fn: (current: Data) => Next,\n ): PluginDataModelWithRecover<Next, Versions & Record<NextV, Next>> {\n return PluginDataModelWithRecover[FROM_BUILDER]<Next, Versions & Record<NextV, Next>>({\n ...this.state,\n migrations: [\n ...this.state.migrations,\n { toVersion: version, fn: fn as (data: unknown) => unknown },\n ],\n });\n }\n\n init<Config = undefined>(fn: (config?: Config) => Data): PluginDataModel<Data, Versions, Config> {\n return buildPluginDataModel(this.state, fn);\n }\n}\n\n/**\n * Builds a PluginDataModel by replaying the stored chain state through DataModelBuilder.\n * @internal\n */\nfunction buildPluginDataModel<\n Data extends PluginData,\n Versions extends Record<string, unknown>,\n Config,\n>(\n state: PluginChainState,\n configInitFn: (config?: Config) => Data,\n): PluginDataModel<Data, Versions, Config> {\n // Build inner DataModel by replaying migrations through DataModelBuilder chain.\n // Uses `any` internally — type safety is maintained by the public chain types.\n let chain: any = new DataModelBuilder().from(state.initialVersion);\n\n for (let i = 0; i < state.migrations.length; i++) {\n if (state.recoverFn !== undefined && state.recoverAtIndex === i) {\n chain = chain.recover(state.recoverFn);\n }\n chain = chain.migrate(state.migrations[i].toVersion, state.migrations[i].fn);\n }\n\n // If recover was placed at or after the last migration\n if (state.recoverFn !== undefined && state.recoverAtIndex === state.migrations.length) {\n chain = chain.recover(state.recoverFn);\n }\n\n const dataModel: DataModel<Data> = chain.init(() => configInitFn());\n\n return PluginDataModel[FROM_BUILDER]<Data, Versions, Config>(dataModel, configInitFn);\n}\n\n/**\n * A named plugin instance created by `factory.create({ pluginId, ... })`.\n * Passed to both `.transfer()` (on migration chain) and `.plugin()` (on BlockModelV3).\n * Implements TransferTarget so the migration chain can accept it.\n *\n * @typeParam Id - Plugin instance ID literal type\n * @typeParam Data - Plugin data type\n * @typeParam Params - Plugin params type\n * @typeParam Outputs - Plugin outputs type\n * @typeParam TransferData - Type of data entering the plugin via transfer (never if no transfer)\n */\nexport class PluginInstance<\n Id extends string = string,\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n ModelServices = unknown,\n UiServices = unknown,\n> implements TransferTarget<Id, TransferData> {\n readonly id: Id;\n readonly transferVersion: string;\n /** @internal Phantom for type inference; never set at runtime. */\n readonly __instanceTypes?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n publicOutputs: PublicOutputs;\n };\n /** Bound closure that creates the PluginModel. Config is captured at factory.create() time. */\n private readonly createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >;\n\n private constructor(\n id: Id,\n createPluginModel: () => PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n ) {\n this.id = id;\n this.createPluginModel = createPluginModel;\n this.transferVersion = transferVersion;\n }\n\n /** @internal Accepts concrete Config — binds it into a closure, avoiding Config variance issues. */\n static [FROM_BUILDER]<\n Id extends string,\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n TransferData = never,\n Config extends PluginConfig = PluginConfig,\n ModelServices = unknown,\n UiServices = unknown,\n >(\n id: Id,\n factory: PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Record<string, unknown>,\n ModelServices,\n UiServices\n >,\n transferVersion: string,\n config?: Config,\n ): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n TransferData,\n ModelServices,\n UiServices\n > {\n return new PluginInstance(id, () => factory[CREATE_PLUGIN_MODEL](config), transferVersion);\n }\n\n /** @internal Create a PluginModel from this instance. Used by BlockModelV3.plugin(). */\n [CREATE_PLUGIN_MODEL](): PluginModel<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n > {\n return this.createPluginModel();\n }\n}\n\n/**\n * Configured plugin instance returned by PluginModelFactory[CREATE_PLUGIN_MODEL]().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n /** Create fresh default data. Config (if any) is captured at creation time. */\n readonly getDefaultData: () => DataVersioned<Data>;\n /** Public output definitions — accessible without usePlugin() via app.plugins */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.getDefaultData = options.getDefaultData;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n getDefaultData: () => DataVersioned<Data>;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n return new PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices>(\n options,\n );\n }\n\n /**\n * Creates a new PluginModelBuilder with a PluginDataModel (supports transfer / config).\n *\n * @example\n * const pluginData = new PluginDataModelBuilder().from<TableData>(\"v1\")\n * .migrate<FilteredTableData>(\"v2\", (v1) => ({ ...v1, filters: [] }))\n * .init<TableConfig>((config?) => ({\n * state: createDefaultState(config?.ops),\n * filters: [],\n * }));\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: pluginData,\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Versions extends Record<string, unknown> = {},\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: PluginDataModel<Data, Versions, Config>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n Versions,\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n /**\n * Creates a new PluginModelBuilder with a data model factory function (backward compatible).\n *\n * @example\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * }).build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Flags extends BlockCodeKnownFeatureFlags = {},\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: Flags;\n }): PluginModelInitialBuilder<\n Data,\n Params,\n Config,\n {},\n ResolveModelServices<Flags>,\n ResolveUiServices<Flags>\n >;\n static define(options: {\n name: PluginName;\n data: PluginDataModel<any, any, any> | ((config?: any) => DataModel<any>);\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder {\n if (options.data instanceof PluginDataModel) {\n const pdm = options.data;\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: () => pdm.dataModel,\n getDefaultDataFn: (config: any) => pdm.getDefaultData(config),\n featureFlags: options.featureFlags,\n });\n }\n return PluginModelInitialBuilder.create({\n name: options.name,\n dataFn: options.data,\n featureFlags: options.featureFlags,\n });\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices> {\n /** Create a named plugin instance, optionally with transfer at a specific version. */\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n >;\n\n /** Public output field definitions declared via .publicOutput(). */\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: {\n data: Data;\n params: Params;\n outputs: Outputs;\n modelServices: ModelServices;\n uiServices: UiServices;\n config: Config;\n versions: Versions;\n publicOutputs: PublicOutputs;\n };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> implements PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n> {\n private readonly name: PluginName;\n private readonly dataFn: (config?: Config) => DataModel<Data>;\n private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n private constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelFactory(options);\n }\n\n create<const Id extends string, const V extends string & keyof Versions = never>(options: {\n pluginId: Id;\n transferAt?: V;\n config?: Config;\n }): PluginInstance<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n ModelServices,\n UiServices\n > {\n const transferVersion = options.transferAt ?? NO_TRANSFER_VERSION;\n return PluginInstance[FROM_BUILDER]<\n Id,\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Versions[V],\n Config,\n ModelServices,\n UiServices\n >(options.pluginId as Id, this, transferVersion, options.config);\n }\n\n /** @internal Create a PluginModel from config. Config is captured in getDefaultData closure. */\n [CREATE_PLUGIN_MODEL](\n config?: Config,\n ): PluginModel<Data, Params, Outputs, PublicOutputs, ModelServices, UiServices> {\n const dataModel = this.dataFn(config);\n const getDefaultDataFn = this.getDefaultDataFn;\n return PluginModel[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataModel,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n getDefaultData: getDefaultDataFn\n ? () => getDefaultDataFn(config)\n : () => dataModel.getDefaultData(),\n publicOutputDef: this.publicOutputDef,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n * @typeParam Versions - Version map from PluginDataModel (empty for function-based data)\n *\n * @example\n * const dataTable = PluginModel.define({\n * name: 'dataTable' as PluginName,\n * data: pluginDataModel,\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> {\n protected readonly name: PluginName;\n protected readonly dataFn: (config?: Config) => DataModel<Data>;\n protected readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n private readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n protected readonly featureFlags?: BlockCodeKnownFeatureFlags;\n private readonly publicOutputDef: PublicOutputDef<PublicOutputs>;\n\n protected constructor(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }) {\n this.name = options.name;\n this.dataFn = options.dataFn;\n this.getDefaultDataFn = options.getDefaultDataFn;\n this.outputs =\n options.outputs ?? ({} as PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>);\n this.featureFlags = options.featureFlags;\n this.publicOutputDef = options.publicOutputDef;\n }\n\n /** @internal */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n PublicOutputs extends PluginPublicOutputs = PluginPublicOutputs,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n publicOutputDef: PublicOutputDef<PublicOutputs>;\n }): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n * All plugin outputs are always wrapped with status — the UI receives\n * {@link OutputWithStatus} for every output, allowing it to distinguish\n * between pending, success, and error states.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns Builder with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('pFrame', (ctx) => ctx.createPFrame([...]))\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (\n ctx: PluginRenderCtx<\n PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>\n >,\n ) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs & { [K in Key]: OutputWithStatus<T> },\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as unknown as PluginOutputFns<\n Data,\n Params,\n Outputs & { [P in Key]: OutputWithStatus<T> },\n ModelServices,\n UiServices\n >,\n publicOutputDef: this.publicOutputDef,\n });\n }\n\n /**\n * Exposes a plugin data field as a public output — accessible without `usePlugin()`\n * via `app.plugins.pluginName.publicOutputs.key`.\n *\n * The getter runs against the plugin's reactive data object.\n * Public outputs are read-only.\n *\n * @param key - Name of the public output field\n * @param getter - Function deriving the value from plugin data\n *\n * @example\n * .publicOutput('selection', (d) => d.selection)\n */\n publicOutput<const Key extends string, T>(\n key: Key,\n getter: (data: Data) => T,\n ): PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return new PluginModelBuilder<\n Data,\n Params,\n Outputs,\n PublicOutputs & { [K in Key]: T },\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n outputs: this.outputs,\n publicOutputDef: {\n ...this.publicOutputDef,\n [key]: { getter: getter as (data: unknown) => unknown },\n } as PublicOutputDef<PublicOutputs & { [K in Key]: T }>,\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a PluginFactory.\n *\n * @returns Plugin factory that creates named plugin instances via .create()\n *\n * @example\n * const myPlugin = PluginModel.define({ ... })\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Create a named instance:\n * const table = myPlugin.create({ pluginId: 'mainTable', config: { ... } });\n */\n build(): PluginFactory<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelFactory[FROM_BUILDER]<\n Data,\n Params,\n Outputs,\n PublicOutputs,\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n outputs: this.outputs,\n publicOutputDef: this.publicOutputDef,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Initial builder returned by PluginModel.define(). Extends PluginModelBuilder with .params().\n * Once .params() or .output() is called, transitions to PluginModelBuilder (no second .params()).\n */\nclass PluginModelInitialBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Config extends PluginConfig = undefined,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n> extends PluginModelBuilder<Data, Params, {}, {}, Config, Versions, ModelServices, UiServices> {\n /** @internal */\n static create<\n Data extends PluginData,\n Config extends PluginConfig,\n Versions extends Record<string, unknown> = {},\n ModelServices = {},\n UiServices = {},\n >(options: {\n name: PluginName;\n dataFn: (config?: Config) => DataModel<Data>;\n getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelInitialBuilder<Data, undefined, Config, Versions, ModelServices, UiServices> {\n return new PluginModelInitialBuilder({ ...options, publicOutputDef: {} });\n }\n\n /**\n * Sets the Params type for this plugin — the shape of data derived from the block's\n * render context and passed into plugin output functions via `ctx.params`.\n * Must be called before .output(). Available only on the initial builder.\n *\n * @example\n * .params<{ title: string }>()\n * .output('displayText', (ctx) => ctx.params.title)\n */\n params<P extends PluginParams>(): PluginModelBuilder<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n > {\n return PluginModelBuilder[FROM_BUILDER]<\n Data,\n P,\n {},\n {},\n Config,\n Versions,\n ModelServices,\n UiServices\n >({\n name: this.name,\n dataFn: this.dataFn,\n getDefaultDataFn: this.getDefaultDataFn,\n featureFlags: this.featureFlags,\n publicOutputDef: {},\n });\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/model",
3
- "version": "1.79.6",
3
+ "version": "1.79.15",
4
4
  "description": "Platforma.bio SDK / Block Model",
5
5
  "files": [
6
6
  "./dist/**/*",
@@ -30,22 +30,22 @@
30
30
  "fast-json-patch": "^3.1.1",
31
31
  "utility-types": "^3.11.0",
32
32
  "zod": "~3.25.76",
33
+ "@milaboratories/ptabler-expression-js": "1.2.31",
34
+ "@milaboratories/pl-model-middle-layer": "1.30.7",
33
35
  "@milaboratories/helpers": "1.14.2",
34
36
  "@milaboratories/pl-error-like": "1.12.10",
35
- "@milaboratories/pl-model-middle-layer": "1.30.6",
36
- "@milaboratories/pl-model-common": "1.46.1",
37
- "@milaboratories/ptabler-expression-js": "1.2.30"
37
+ "@milaboratories/pl-model-common": "1.46.2"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@vitest/coverage-istanbul": "^4.1.3",
41
41
  "fast-json-patch": "^3.1.1",
42
42
  "typescript": "~5.9.3",
43
43
  "vitest": "^4.1.3",
44
+ "@milaboratories/pf-spec-driver": "1.4.14",
45
+ "@milaboratories/ts-configs": "1.2.3",
46
+ "@milaboratories/pf-driver": "1.7.12",
44
47
  "@milaboratories/build-configs": "2.0.0",
45
- "@milaboratories/pf-driver": "1.7.10",
46
- "@milaboratories/pf-spec-driver": "1.4.12",
47
- "@milaboratories/ts-builder": "1.5.0",
48
- "@milaboratories/ts-configs": "1.2.3"
48
+ "@milaboratories/ts-builder": "1.5.2"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "ts-builder build --target node",
@@ -1,4 +1,10 @@
1
- import type { PColumn, PColumnSpec, PColumnLazy, PFrameDef } from "@milaboratories/pl-model-common";
1
+ import type {
2
+ PColumn,
3
+ PColumnSpec,
4
+ PColumnLazy,
5
+ PFrameDef,
6
+ PObjectId,
7
+ } from "@milaboratories/pl-model-common";
2
8
  import {
3
9
  getNormalizedAxesList,
4
10
  getAxisId,
@@ -11,6 +17,8 @@ import type { AxesVault } from "./axes";
11
17
  import { enrichCompatible, getAvailableWithLinkersAxes } from "./axes";
12
18
  import type { RenderCtxBase, PColumnDataUniversal } from "../render";
13
19
  import { PColumnCollection } from "../render";
20
+ import { ColumnCollectionBuilder } from "../columns";
21
+ import { collectCtxColumnSnapshotProviders } from "../columns/ctx_column_sources";
14
22
 
15
23
  export function getAllRelatedColumns<A, U>(
16
24
  ctx: RenderCtxBase<A, U>,
@@ -137,8 +145,42 @@ export function getRelatedColumns<A, U>(
137
145
 
138
146
  const compatible = [...compatibleWithoutLabels, ...compatibleLabels];
139
147
 
148
+ // Drop result-pool columns that share an axis with the block but cannot join it.
149
+ const integrableIds = discoverIntegrableColumnIds(ctx, rootColumns);
150
+ const rootIds = new Set(rootColumns.map((c) => c.id));
151
+ const connected = compatible.filter(
152
+ (c) => rootIds.has(c.id) || isLinkerColumn(c.spec) || (integrableIds?.has(c.id) ?? true),
153
+ );
154
+
140
155
  // additional columns are duplicates with extra fields in domains for compatibility if there are ones with partial match
141
- const extendedColumns = enrichCompatible(blockAxes, compatible);
156
+ const extendedColumns = enrichCompatible(blockAxes, connected);
142
157
 
143
158
  return extendedColumns;
144
159
  }
160
+
161
+ /** Column ids that discovery confirms integrate with the block, or `undefined` when it can't decide. */
162
+ function discoverIntegrableColumnIds<A, U>(
163
+ ctx: RenderCtxBase<A, U>,
164
+ rootColumns: PColumn<PColumnDataUniversal>[],
165
+ ): Set<PObjectId> | undefined {
166
+ const anchorSpecs = Array.from(
167
+ new Map(rootColumns.map((c) => [canonicalizeJson(c.spec), c.spec])).values(),
168
+ );
169
+ if (anchorSpecs.length === 0) return undefined;
170
+
171
+ try {
172
+ const collection = new ColumnCollectionBuilder()
173
+ .addSources(collectCtxColumnSnapshotProviders(ctx))
174
+ .build({
175
+ allowPartialColumnList: true,
176
+ anchors: Object.fromEntries(anchorSpecs.map((spec, i) => [`anchor_${i}`, spec])),
177
+ });
178
+ try {
179
+ return new Set(collection.findColumns({ mode: "enrichment" }).map((m) => m.column.id));
180
+ } finally {
181
+ collection.dispose();
182
+ }
183
+ } catch {
184
+ return undefined;
185
+ }
186
+ }
@@ -47,8 +47,9 @@ type PluginOutputFns<
47
47
  [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;
48
48
  };
49
49
 
50
- /** Symbol for internal plugin model creation — not accessible to external consumers */
51
- export const CREATE_PLUGIN_MODEL = Symbol("createPluginModel");
50
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
51
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
52
+ export const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
52
53
 
53
54
  /** Sentinel for PluginInstance without transferAt — no transfer possible. */
54
55
  const NO_TRANSFER_VERSION = "";