@platforma-sdk/model 1.65.9 → 1.66.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/block_model.cjs +8 -11
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +8 -10
- package/dist/block_model.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +61 -74
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +16 -22
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +62 -75
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_selector.cjs.map +1 -1
- package/dist/columns/column_selector.d.ts +1 -1
- package/dist/columns/column_selector.js.map +1 -1
- package/dist/columns/column_snapshot.cjs.map +1 -1
- package/dist/columns/column_snapshot.d.ts +4 -4
- package/dist/columns/column_snapshot.d.ts.map +1 -1
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +16 -16
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +5 -5
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -3
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
- package/dist/components/PlDataTable/labels.cjs +1 -2
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +1 -2
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/filters/distill.cjs +73 -30
- package/dist/filters/distill.cjs.map +1 -1
- package/dist/filters/distill.d.ts.map +1 -1
- package/dist/filters/distill.js +73 -30
- package/dist/filters/distill.js.map +1 -1
- package/dist/index.cjs +19 -15
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -4
- package/dist/labels/derive_distinct_tooltips.cjs +85 -0
- package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
- package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
- package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
- package/dist/labels/derive_distinct_tooltips.js +84 -0
- package/dist/labels/derive_distinct_tooltips.js.map +1 -0
- package/dist/labels/index.cjs +1 -0
- package/dist/labels/index.d.ts +2 -1
- package/dist/labels/index.js +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +8 -13
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +8 -11
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +8 -13
- package/dist/render/api.js.map +1 -1
- package/dist/services/get_services.cjs +19 -0
- package/dist/services/get_services.cjs.map +1 -0
- package/dist/services/get_services.d.ts +7 -0
- package/dist/services/get_services.d.ts.map +1 -0
- package/dist/services/get_services.js +19 -0
- package/dist/services/get_services.js.map +1 -0
- package/dist/services/index.cjs +1 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +1 -0
- package/dist/services/service_bridge.cjs +4 -4
- package/dist/services/service_bridge.cjs.map +1 -1
- package/dist/services/service_bridge.d.ts +4 -4
- package/dist/services/service_bridge.d.ts.map +1 -1
- package/dist/services/service_bridge.js +4 -4
- package/dist/services/service_bridge.js.map +1 -1
- package/package.json +6 -6
- package/src/block_model.ts +8 -11
- package/src/columns/column_collection_builder.test.ts +75 -30
- package/src/columns/column_collection_builder.ts +96 -133
- package/src/columns/column_selector.ts +1 -1
- package/src/columns/column_snapshot.ts +7 -4
- package/src/columns/ctx_column_sources.ts +1 -3
- package/src/components/PFrameForGraphs.test.ts +4 -4
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
- package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
- package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
- package/src/components/PlDataTable/labels.ts +3 -7
- package/src/filters/distill.test.ts +91 -0
- package/src/filters/distill.ts +102 -46
- package/src/labels/derive_distinct_tooltips.test.ts +233 -0
- package/src/labels/derive_distinct_tooltips.ts +130 -0
- package/src/labels/index.ts +1 -0
- package/src/render/api.ts +15 -50
- package/src/services/get_services.ts +28 -0
- package/src/services/index.ts +1 -0
- package/src/services/service_bridge.ts +5 -5
package/dist/block_model.cjs
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
require("./_virtual/_rolldown/runtime.cjs");
|
|
2
1
|
const require_plugin_handle = require("./plugin_handle.cjs");
|
|
3
2
|
const require_internal = require("./internal.cjs");
|
|
4
3
|
const require_block_storage_facade = require("./block_storage_facade.cjs");
|
|
4
|
+
const require_block_services = require("./services/block_services.cjs");
|
|
5
5
|
const require_api = require("./render/api.cjs");
|
|
6
6
|
require("./render/index.cjs");
|
|
7
7
|
const require_version = require("./version.cjs");
|
|
8
8
|
const require_types = require("./bconfig/types.cjs");
|
|
9
9
|
const require_normalization = require("./bconfig/normalization.cjs");
|
|
10
10
|
require("./bconfig/index.cjs");
|
|
11
|
-
const require_block_services = require("./services/block_services.cjs");
|
|
12
11
|
const require_plugin_model = require("./plugin_model.cjs");
|
|
13
12
|
const require_block_storage_callbacks = require("./block_storage_callbacks.cjs");
|
|
14
|
-
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
15
13
|
//#region src/block_model.ts
|
|
16
14
|
/**
|
|
17
15
|
* Merges two feature flag objects with type-aware logic:
|
|
@@ -87,7 +85,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
87
85
|
...this.config.outputs,
|
|
88
86
|
[key]: require_internal.createAndRegisterRenderLambda({
|
|
89
87
|
handle: `block-output#${key}`,
|
|
90
|
-
lambda: () => cfgOrRf(new require_api.BlockRenderCtx(
|
|
88
|
+
lambda: () => cfgOrRf(new require_api.BlockRenderCtx()),
|
|
91
89
|
...flags
|
|
92
90
|
})
|
|
93
91
|
}
|
|
@@ -152,7 +150,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
152
150
|
...this.config,
|
|
153
151
|
sections: require_internal.createAndRegisterRenderLambda({
|
|
154
152
|
handle: "sections",
|
|
155
|
-
lambda: () => rf(new require_api.BlockRenderCtx(
|
|
153
|
+
lambda: () => rf(new require_api.BlockRenderCtx())
|
|
156
154
|
}, true)
|
|
157
155
|
});
|
|
158
156
|
}
|
|
@@ -162,7 +160,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
162
160
|
...this.config,
|
|
163
161
|
title: require_internal.createAndRegisterRenderLambda({
|
|
164
162
|
handle: "title",
|
|
165
|
-
lambda: () => rf(new require_api.BlockRenderCtx(
|
|
163
|
+
lambda: () => rf(new require_api.BlockRenderCtx())
|
|
166
164
|
})
|
|
167
165
|
});
|
|
168
166
|
}
|
|
@@ -171,7 +169,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
171
169
|
...this.config,
|
|
172
170
|
subtitle: require_internal.createAndRegisterRenderLambda({
|
|
173
171
|
handle: "subtitle",
|
|
174
|
-
lambda: () => rf(new require_api.BlockRenderCtx(
|
|
172
|
+
lambda: () => rf(new require_api.BlockRenderCtx())
|
|
175
173
|
})
|
|
176
174
|
});
|
|
177
175
|
}
|
|
@@ -180,7 +178,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
180
178
|
...this.config,
|
|
181
179
|
tags: require_internal.createAndRegisterRenderLambda({
|
|
182
180
|
handle: "tags",
|
|
183
|
-
lambda: () => rf(new require_api.BlockRenderCtx(
|
|
181
|
+
lambda: () => rf(new require_api.BlockRenderCtx())
|
|
184
182
|
})
|
|
185
183
|
});
|
|
186
184
|
}
|
|
@@ -242,7 +240,6 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
242
240
|
const pluginHandles = Object.keys(plugins);
|
|
243
241
|
for (const handle of pluginHandles) pluginRegistry[handle] = plugins[handle].model.name;
|
|
244
242
|
const { dataModel, argsFunction, prerunArgsFunction } = this.config;
|
|
245
|
-
const mergedServiceNames = (0, _milaboratories_pl_model_common.resolveRequiredServices)(this.config.featureFlags);
|
|
246
243
|
function getPlugin(handle) {
|
|
247
244
|
const plugin = plugins[handle];
|
|
248
245
|
if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);
|
|
@@ -272,14 +269,14 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
272
269
|
for (const handle of pluginHandles) {
|
|
273
270
|
const { model, inputs } = plugins[handle];
|
|
274
271
|
const wrappedInputs = {};
|
|
275
|
-
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new require_api.BlockRenderCtx(
|
|
272
|
+
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new require_api.BlockRenderCtx());
|
|
276
273
|
const outputs = model.outputs;
|
|
277
274
|
const { outputFlags } = model;
|
|
278
275
|
for (const [outputKey, outputFn] of Object.entries(outputs)) {
|
|
279
276
|
const key = require_plugin_handle.pluginOutputKey(handle, outputKey);
|
|
280
277
|
pluginOutputs[key] = require_internal.createAndRegisterRenderLambda({
|
|
281
278
|
handle: key,
|
|
282
|
-
lambda: () => outputFn(new require_api.PluginRenderCtx(handle, wrappedInputs
|
|
279
|
+
lambda: () => outputFn(new require_api.PluginRenderCtx(handle, wrappedInputs)),
|
|
283
280
|
withStatus: outputFlags[outputKey]?.withStatus
|
|
284
281
|
});
|
|
285
282
|
}
|
package/dist/block_model.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_model.cjs","names":["BLOCK_SERVICE_FLAGS","createAndRegisterRenderLambda","BlockRenderCtx","blockServiceNames","CREATE_PLUGIN_MODEL","BlockStorageFacadeCallbacks","applyStorageUpdate","getStorageDebugView","migrateStorage","createInitialStorage","deriveArgsFromStorage","derivePrerunArgsFromStorage","pluginOutputKey","PluginRenderCtx","isInUI","PlatformaSDKVersion","BlockStorageFacadeHandles","downgradeCfgOrLambda","getPlatformaInstance","isConfigLambda"],"sources":["../src/block_model.ts"],"sourcesContent":["import type {\n BlockRenderingMode,\n BlockSection,\n OutputWithStatus,\n PlRef,\n BlockCodeKnownFeatureFlags,\n BlockConfigContainer,\n} from \"@milaboratories/pl-model-common\";\nimport { resolveRequiredServices } from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { BlockDefaultUiServices } from \"./services/service_resolve\";\nimport { blockServiceNames, BLOCK_SERVICE_FLAGS } from \"./services/block_services\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } from \"./plugin_model\";\nimport { PluginInstance as PluginInstanceClass, CREATE_PLUGIN_MODEL } from \"./plugin_model\";\nimport { type PluginHandle, pluginOutputKey } from \"./plugin_handle\";\nimport type { RenderCtxBase } from \"./render\";\nimport { PlatformaSDKVersion } from \"./version\";\nimport {\n applyStorageUpdate,\n getStorageDebugView,\n migrateStorage,\n createInitialStorage,\n deriveArgsFromStorage,\n derivePrerunArgsFromStorage,\n} from \"./block_storage_callbacks\";\nimport { type PluginName } from \"./block_storage\";\nimport type {\n ConfigRenderLambda,\n DeriveHref,\n ConfigRenderLambdaFlags,\n InferOutputsFromLambdas,\n} from \"./bconfig\";\nimport { downgradeCfgOrLambda, isConfigLambda } from \"./bconfig\";\nimport type { PlatformaExtended } from \"./platforma\";\nimport {\n BLOCK_STORAGE_FACADE_VERSION,\n BlockStorageFacadeCallbacks,\n BlockStorageFacadeHandles,\n registerFacadeCallbacks,\n} from \"./block_storage_facade\";\n\ntype SectionsExpectedType = readonly BlockSection[];\n\ntype NoOb = Record<string, never>;\n\n/**\n * Per-property lambdas for deriving plugin params from block render context.\n * Each property is a function that receives the block's RenderCtxBase and returns the param value.\n */\nexport type ParamsInput<Params, BArgs = unknown, BData = unknown> = {\n [K in keyof Params]: (ctx: RenderCtxBase<BArgs, BData>) => Params[K];\n};\n\n/**\n * Type-erased version of ParamsInput for internal storage.\n */\ntype ParamsInputErased = Record<string, (ctx: RenderCtxBase) => unknown>;\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nfunction mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (typeof existing === \"boolean\" && existing) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max(typeof existing === \"number\" ? existing : 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\n/**\n * Plugin record: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginRecord<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n ModelServices = unknown,\n UiServices = unknown,\n> = {\n readonly model: PluginModel<Data, Params, Outputs, ModelServices, UiServices>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data, Transfers>;\n outputs: OutputsCfg;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n plugins: Plugins;\n}\n\n/** Main entry point that each block should use in it's \"config\" module. Don't forget\n * to call {@link done()} at the end of configuration. Value returned by this builder must be\n * exported as constant with name \"platforma\" from the \"config\" module.\n * API version is 3 (for UI) and 2 (for model) */\nexport class BlockModelV3<\n Args,\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data extends Record<string, unknown> = Record<string, unknown>,\n Href extends `/${string}` = \"/\",\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n private constructor(\n private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins, Transfers>,\n ) {}\n\n public static readonly FEATURE_FLAGS = {\n supportsLazyState: true,\n supportsPframeQueryRanking: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n ...BLOCK_SERVICE_FLAGS,\n } satisfies BlockCodeKnownFeatureFlags;\n\n /** @deprecated Use FEATURE_FLAGS */\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;\n\n /**\n * Creates a new BlockModelV3 builder with the specified data model.\n *\n * @example\n * const dataModel = new DataModelBuilder()\n * .from<BlockData>(\"v1\")\n * .init(() => ({ numbers: [], labels: [] }));\n *\n * BlockModelV3.create(dataModel)\n * .args((data) => ({ numbers: data.numbers }))\n * .sections(() => [{ type: 'link', href: '/', label: 'Main' }])\n * .done();\n *\n * @param dataModel The data model that defines initial data and migrations\n */\n public static create<\n Data extends Record<string, unknown>,\n Transfers extends Record<string, unknown> = {},\n >(dataModel: DataModel<Data, Transfers>): BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers> {\n return new BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers>({\n renderingMode: \"Heavy\",\n dataModel,\n outputs: {},\n sections: createAndRegisterRenderLambda({ handle: \"sections\", lambda: () => [] }, true),\n title: undefined,\n subtitle: undefined,\n tags: undefined,\n enrichmentTargets: undefined,\n featureFlags: { ...BlockModelV3.FEATURE_FLAGS },\n argsFunction: undefined,\n prerunArgsFunction: undefined,\n plugins: {},\n });\n }\n\n /**\n * Add output cell wrapped with additional status information to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags: ConfigRenderLambdaFlags & { withStatus: true },\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> & {\n withStatus: true;\n };\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n /**\n * Add output cell to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags?: ConfigRenderLambdaFlags,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3({\n ...this.config,\n outputs: {\n ...this.config.outputs,\n [key]: createAndRegisterRenderLambda({\n handle: `block-output#${key}`,\n lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n ...flags,\n }),\n },\n });\n }\n\n /** Shortcut for {@link output} with retentive flag set to true. */\n public retentiveOutput<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(\n key: Key,\n rf: RF,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n > {\n return this.output(key, rf, { retentive: true });\n }\n\n /** Shortcut for {@link output} with withStatus flag set to true. */\n public outputWithStatus<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(key: Key, rf: RF) {\n return this.output(key, rf, { withStatus: true });\n }\n\n /**\n * Sets a function to derive block args from data.\n * This is called during setData to compute the args that will be used for block execution.\n *\n * @example\n * .args<BlockArgs>((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .args<BlockArgs>((data) => {\n * if (data.numbers.length === 0) throw new Error('Numbers required'); // block not ready\n * return { numbers: data.numbers };\n * })\n */\n public args<A>(\n lambda: (data: Data) => A,\n ): BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n argsFunction: lambda as (data: unknown) => unknown,\n });\n }\n\n /**\n * Sets a function to derive pre-run args from data (optional).\n * This is called during setData to compute the args that will be used for staging/pre-run phase.\n *\n * If not defined, defaults to using the args() function result.\n * If defined, uses its return value for the staging / prerun phase.\n *\n * The staging / prerun phase runs only if currentPrerunArgs differs from the executed\n * version of prerunArgs (same comparison logic as currentArgs vs prodArgs).\n *\n * @example\n * .prerunArgs((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .prerunArgs((data) => {\n * // Return undefined to skip staging for this block\n * if (!data.isReady) return undefined;\n * return { numbers: data.numbers };\n * })\n */\n public prerunArgs(\n fn: (data: Data) => unknown,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n prerunArgsFunction: fn as (data: unknown) => unknown,\n });\n }\n\n /** Sets the lambda to generate list of sections in the left block overviews panel. */\n public sections<\n const Ret extends SectionsExpectedType,\n const RF extends RenderFunction<Args, Data, Ret>,\n >(rf: RF): BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers>(\n {\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n {\n handle: \"sections\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n },\n true,\n ),\n },\n );\n }\n\n /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */\n public title(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n title: createAndRegisterRenderLambda({\n handle: \"title\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n public subtitle(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n subtitle: createAndRegisterRenderLambda({\n handle: \"subtitle\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n public tags(\n rf: RenderFunction<Args, Data, string[]>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n tags: createAndRegisterRenderLambda({\n handle: \"tags\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n /** Sets or overrides feature flags for the block. */\n public withFeatureFlags(\n flags: Partial<BlockCodeKnownFeatureFlags>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n featureFlags: { ...this.config.featureFlags, ...flags },\n });\n }\n\n /**\n * Defines how to derive list of upstream references this block is meant to enrich with its exports from block args.\n * Influences dependency graph construction.\n */\n public enriches(\n lambda: (args: Args) => PlRef[],\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n enrichmentTargets: createAndRegisterRenderLambda({\n handle: \"enrichmentTargets\",\n lambda: lambda,\n }),\n });\n }\n\n /**\n * Registers a plugin instance with the block.\n * Consumes a transfer if one was defined for this plugin ID in the migration chain.\n *\n * Type checks:\n * - If Transfers[Id] exists, verifies it extends PTransferData (transfer type compatibility)\n * - If no Transfers[Id], rejects plugins with transferAt set (missing .transfer() in data model)\n * - Rejects duplicate plugin IDs (Id already in keyof Plugins)\n *\n * @param instance - PluginInstance created via factory.create({ pluginId, ... })\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin(mainTable, {\n * columns: (ctx) => ctx.outputs?.resolve(\"data\")?.getPColumns(),\n * sourceId: (ctx) => ctx.data.selectedSource,\n * })\n */\n public plugin<\n const PluginId extends string,\n PData extends PluginData,\n PParams extends PluginParams,\n POutputs extends PluginOutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices,\n >(\n instance: PluginInstanceClass<\n PluginId &\n (PluginId extends keyof Transfers\n ? Transfers[PluginId] extends PTransferData\n ? string\n : never\n : [PTransferData] extends [never]\n ? string\n : never) &\n (PluginId extends keyof Plugins ? never : string),\n PData,\n PParams,\n POutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices\n >,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & {\n [K in PluginId]: PluginRecord<\n PData,\n PParams,\n POutputs,\n PluginModelServices,\n PluginUiServices\n >;\n },\n Omit<Transfers, PluginId>\n >;\n public plugin(\n instance: PluginInstanceClass,\n params?: ParamsInput<Record<string, unknown>, unknown, unknown>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Record<string, PluginRecord>,\n Record<string, unknown>\n > {\n const pluginId = instance.id;\n const plugin = instance[CREATE_PLUGIN_MODEL]();\n const resolvedParams = (params ?? {}) as ParamsInputErased;\n\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const registered: PluginRecord = {\n model: plugin,\n inputs: resolvedParams,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: registered,\n },\n featureFlags: mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),\n });\n }\n\n /** Renders all provided block settings into a pre-configured platforma API\n * instance, that can be used in frontend to interact with block data, and\n * other features provided by the platforma to the block.\n *\n * Type-level check: if there are unconsumed transfers (from `.transfer()` calls\n * in the migration chain), this method requires an impossible `never` argument,\n * producing a compile error. Register all transferred plugins via `.plugin(instance)`\n * before calling `.done()`.\n */\n public done(\n ..._: keyof Transfers extends never ? [] : [never]\n ): PlatformaExtended<\n PlatformaV3<\n Data,\n Args,\n InferOutputsFromLambdas<OutputsCfg>,\n Href,\n Plugins,\n BlockDefaultUiServices\n >\n > {\n if (this.config.argsFunction === undefined) throw new Error(\"Args rendering function not set.\");\n\n const apiVersion = 3;\n\n // Build plugin registry\n const { plugins } = this.config;\n const pluginRegistry: Record<string, PluginName> = {};\n const pluginHandles = Object.keys(plugins) as PluginHandle[];\n for (const handle of pluginHandles) {\n pluginRegistry[handle] = plugins[handle].model.name;\n }\n\n const { dataModel, argsFunction, prerunArgsFunction } = this.config;\n\n const mergedServiceNames = resolveRequiredServices(this.config.featureFlags);\n\n function getPlugin(handle: PluginHandle): PluginRecord {\n const plugin = plugins[handle];\n if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);\n return plugin;\n }\n\n // Register ALL facade callbacks here, with dependencies captured via closures\n registerFacadeCallbacks({\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: applyStorageUpdate,\n [BlockStorageFacadeCallbacks.StorageDebugView]: getStorageDebugView,\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson) =>\n migrateStorage(currentStorageJson, {\n migrateBlockData: (v) => dataModel.migrate(v),\n getPluginRegistry: () => pluginRegistry,\n migratePluginData: (handle, v) => getPlugin(handle).model.dataModel.migrate(v),\n createPluginData: (handle, transfer) => {\n if (transfer) return transfer;\n return getPlugin(handle).model.getDefaultData();\n },\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) =>\n deriveArgsFromStorage(storageJson, argsFunction),\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) =>\n derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction),\n });\n\n // Register plugin input and output lambdas\n const pluginOutputs: Record<string, ConfigRenderLambda> = {};\n for (const handle of pluginHandles) {\n const { model, inputs } = plugins[handle];\n // Wrap plugin param lambdas: close over BlockRenderCtx creation\n const wrappedInputs: Record<string, () => unknown> = {};\n for (const [paramKey, paramFn] of Object.entries(inputs)) {\n wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx(mergedServiceNames));\n }\n\n // Register plugin outputs (in config pack, evaluated by middle layer)\n const outputs = model.outputs as Record<string, (ctx: PluginRenderCtx) => unknown>;\n const { outputFlags } = model;\n for (const [outputKey, outputFn] of Object.entries(outputs)) {\n const key = pluginOutputKey(handle, outputKey);\n pluginOutputs[key] = createAndRegisterRenderLambda({\n handle: key,\n lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs, mergedServiceNames)),\n withStatus: outputFlags[outputKey]?.withStatus,\n });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI()) {\n const blockConfig: BlockConfigContainer = {\n v4: {\n configVersion: 4,\n modelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n title: this.config.title,\n subtitle: this.config.subtitle,\n tags: this.config.tags,\n outputs: allOutputs,\n enrichmentTargets: this.config.enrichmentTargets,\n featureFlags: this.config.featureFlags,\n blockLifecycleCallbacks: { ...BlockStorageFacadeHandles },\n },\n\n // fields below are added to allow previous desktop versions read generated configs\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n outputs: Object.fromEntries(\n Object.entries(this.config.outputs).map(([key, value]) => [\n key,\n downgradeCfgOrLambda(value),\n ]),\n ),\n };\n // we are in the configuration rendering routine, not in actual UI\n return { config: blockConfig } as any;\n // normal operation inside the UI\n } else {\n return {\n ...getPlatformaInstance({\n sdkVersion: PlatformaSDKVersion,\n apiVersion,\n }),\n blockModelInfo: {\n outputs: Object.fromEntries(\n Object.entries(allOutputs).map(([key, value]) => [\n key,\n {\n withStatus: Boolean(isConfigLambda(value) && value.withStatus),\n },\n ]),\n ),\n pluginIds: pluginHandles,\n featureFlags: this.config.featureFlags,\n },\n } as any;\n }\n }\n}\n\n// Type tests for BlockModelV3\n\nexport type Expect<T extends true> = T;\n\nexport type Equal<X, Y> =\n (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;\n\nexport type Merge<A, B> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;\n};\n\n// Helper types for testing\ntype _TestArgs = { inputFile: string; threshold: number };\ntype _TestData = { selectedTab: string };\ntype _TestOutputs = {\n result: ConfigRenderLambda<string>;\n count: ConfigRenderLambda<number>;\n};\n\n// Test: Merge type works correctly\ntype _MergeTest1 = Expect<Equal<Merge<{ a: 1 }, { b: 2 }>, { a: 1; b: 2 }>>;\ntype _MergeTest2 = Expect<Equal<Merge<{ a: 1 }, { a: 2 }>, { a: 2 }>>;\ntype _MergeTest3 = Expect<Equal<Merge<{ a: 1; b: 1 }, { b: 2; c: 3 }>, { a: 1; b: 2; c: 3 }>>;\n\n// Test: create() returns a BlockModelV3 instance\n// Note: Due to function overloads, ReturnType uses the last overload signature.\n// We verify the structure is correct using a simpler assignability test.\ntype _CreateResult = ReturnType<typeof BlockModelV3.create>;\ntype _CreateIsBlockModelV3 =\n _CreateResult extends BlockModelV3<infer _A, infer _O, infer _S> ? true : false;\ntype _CreateTest = Expect<_CreateIsBlockModelV3>;\n\n// Test: BlockModelV3Config interface structure (default generics)\ntype _ConfigTest = Expect<\n Equal<\n BlockModelV3Config<_TestOutputs, _TestData>,\n {\n renderingMode: BlockRenderingMode;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n dataModel: DataModel<_TestData, {}>;\n outputs: _TestOutputs;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n plugins: {};\n }\n >\n>;\n\n// Test: Default Href is '/'\ntype _HrefDefaultTest =\n BlockModelV3<_TestArgs, {}, _TestData> extends BlockModelV3<_TestArgs, {}, _TestData, \"/\">\n ? true\n : false;\ntype _VerifyHrefDefault = Expect<_HrefDefaultTest>;\n\n// Test: Custom Href can be specified\ntype _CustomHref = \"/settings\" | \"/main\";\ntype _HrefCustomBuilder = BlockModelV3<_TestArgs, {}, _TestData, _CustomHref>;\ntype _HrefCustomTest =\n _HrefCustomBuilder extends BlockModelV3<_TestArgs, {}, _TestData, _CustomHref> ? true : false;\ntype _VerifyHrefCustom = Expect<_HrefCustomTest>;\n\n// Test: Output type accumulation with & intersection\ntype _OutputsAccumulation = { a: ConfigRenderLambda<string> } & {\n b: ConfigRenderLambda<number>;\n};\ntype _VerifyOutputsHaveKeys = Expect<Equal<keyof _OutputsAccumulation, \"a\" | \"b\">>;\n\n// Test: Builder with all type parameters specified compiles\ntype _FullBuilder = BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\">;\ntype _FullBuilderTest =\n _FullBuilder extends BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\"> ? true : false;\ntype _VerifyFullBuilder = Expect<_FullBuilderTest>;\n\n// Test: InferOutputsFromLambdas maps outputs correctly\ntype _InferOutputsTest = InferOutputsFromLambdas<{\n myOutput: ConfigRenderLambda<number>;\n}>;\ntype _VerifyInferOutputs = Expect<\n Equal<_InferOutputsTest, { myOutput: OutputWithStatus<number> & { __unwrap: true } }>\n>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"block_model.cjs","names":["BLOCK_SERVICE_FLAGS","createAndRegisterRenderLambda","BlockRenderCtx","CREATE_PLUGIN_MODEL","BlockStorageFacadeCallbacks","applyStorageUpdate","getStorageDebugView","migrateStorage","createInitialStorage","deriveArgsFromStorage","derivePrerunArgsFromStorage","pluginOutputKey","PluginRenderCtx","isInUI","PlatformaSDKVersion","BlockStorageFacadeHandles","downgradeCfgOrLambda","getPlatformaInstance","isConfigLambda"],"sources":["../src/block_model.ts"],"sourcesContent":["import type {\n BlockRenderingMode,\n BlockSection,\n OutputWithStatus,\n PlRef,\n BlockCodeKnownFeatureFlags,\n BlockConfigContainer,\n} from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { BlockDefaultUiServices } from \"./services/service_resolve\";\nimport { BLOCK_SERVICE_FLAGS } from \"./services/block_services\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } from \"./plugin_model\";\nimport { PluginInstance as PluginInstanceClass, CREATE_PLUGIN_MODEL } from \"./plugin_model\";\nimport { type PluginHandle, pluginOutputKey } from \"./plugin_handle\";\nimport type { RenderCtxBase } from \"./render\";\nimport { PlatformaSDKVersion } from \"./version\";\nimport {\n applyStorageUpdate,\n getStorageDebugView,\n migrateStorage,\n createInitialStorage,\n deriveArgsFromStorage,\n derivePrerunArgsFromStorage,\n} from \"./block_storage_callbacks\";\nimport { type PluginName } from \"./block_storage\";\nimport type {\n ConfigRenderLambda,\n DeriveHref,\n ConfigRenderLambdaFlags,\n InferOutputsFromLambdas,\n} from \"./bconfig\";\nimport { downgradeCfgOrLambda, isConfigLambda } from \"./bconfig\";\nimport type { PlatformaExtended } from \"./platforma\";\nimport {\n BLOCK_STORAGE_FACADE_VERSION,\n BlockStorageFacadeCallbacks,\n BlockStorageFacadeHandles,\n registerFacadeCallbacks,\n} from \"./block_storage_facade\";\n\ntype SectionsExpectedType = readonly BlockSection[];\n\ntype NoOb = Record<string, never>;\n\n/**\n * Per-property lambdas for deriving plugin params from block render context.\n * Each property is a function that receives the block's RenderCtxBase and returns the param value.\n */\nexport type ParamsInput<Params, BArgs = unknown, BData = unknown> = {\n [K in keyof Params]: (ctx: RenderCtxBase<BArgs, BData>) => Params[K];\n};\n\n/**\n * Type-erased version of ParamsInput for internal storage.\n */\ntype ParamsInputErased = Record<string, (ctx: RenderCtxBase) => unknown>;\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nfunction mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (typeof existing === \"boolean\" && existing) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max(typeof existing === \"number\" ? existing : 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\n/**\n * Plugin record: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginRecord<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n ModelServices = unknown,\n UiServices = unknown,\n> = {\n readonly model: PluginModel<Data, Params, Outputs, ModelServices, UiServices>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data, Transfers>;\n outputs: OutputsCfg;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n plugins: Plugins;\n}\n\n/** Main entry point that each block should use in it's \"config\" module. Don't forget\n * to call {@link done()} at the end of configuration. Value returned by this builder must be\n * exported as constant with name \"platforma\" from the \"config\" module.\n * API version is 3 (for UI) and 2 (for model) */\nexport class BlockModelV3<\n Args,\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data extends Record<string, unknown> = Record<string, unknown>,\n Href extends `/${string}` = \"/\",\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n private constructor(\n private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins, Transfers>,\n ) {}\n\n public static readonly FEATURE_FLAGS = {\n supportsLazyState: true,\n supportsPframeQueryRanking: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n ...BLOCK_SERVICE_FLAGS,\n } satisfies BlockCodeKnownFeatureFlags;\n\n /** @deprecated Use FEATURE_FLAGS */\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;\n\n /**\n * Creates a new BlockModelV3 builder with the specified data model.\n *\n * @example\n * const dataModel = new DataModelBuilder()\n * .from<BlockData>(\"v1\")\n * .init(() => ({ numbers: [], labels: [] }));\n *\n * BlockModelV3.create(dataModel)\n * .args((data) => ({ numbers: data.numbers }))\n * .sections(() => [{ type: 'link', href: '/', label: 'Main' }])\n * .done();\n *\n * @param dataModel The data model that defines initial data and migrations\n */\n public static create<\n Data extends Record<string, unknown>,\n Transfers extends Record<string, unknown> = {},\n >(dataModel: DataModel<Data, Transfers>): BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers> {\n return new BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers>({\n renderingMode: \"Heavy\",\n dataModel,\n outputs: {},\n sections: createAndRegisterRenderLambda({ handle: \"sections\", lambda: () => [] }, true),\n title: undefined,\n subtitle: undefined,\n tags: undefined,\n enrichmentTargets: undefined,\n featureFlags: { ...BlockModelV3.FEATURE_FLAGS },\n argsFunction: undefined,\n prerunArgsFunction: undefined,\n plugins: {},\n });\n }\n\n /**\n * Add output cell wrapped with additional status information to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags: ConfigRenderLambdaFlags & { withStatus: true },\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> & {\n withStatus: true;\n };\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n /**\n * Add output cell to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags?: ConfigRenderLambdaFlags,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3({\n ...this.config,\n outputs: {\n ...this.config.outputs,\n [key]: createAndRegisterRenderLambda({\n handle: `block-output#${key}`,\n lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>()),\n ...flags,\n }),\n },\n });\n }\n\n /** Shortcut for {@link output} with retentive flag set to true. */\n public retentiveOutput<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(\n key: Key,\n rf: RF,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n > {\n return this.output(key, rf, { retentive: true });\n }\n\n /** Shortcut for {@link output} with withStatus flag set to true. */\n public outputWithStatus<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(key: Key, rf: RF) {\n return this.output(key, rf, { withStatus: true });\n }\n\n /**\n * Sets a function to derive block args from data.\n * This is called during setData to compute the args that will be used for block execution.\n *\n * @example\n * .args<BlockArgs>((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .args<BlockArgs>((data) => {\n * if (data.numbers.length === 0) throw new Error('Numbers required'); // block not ready\n * return { numbers: data.numbers };\n * })\n */\n public args<A>(\n lambda: (data: Data) => A,\n ): BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n argsFunction: lambda as (data: unknown) => unknown,\n });\n }\n\n /**\n * Sets a function to derive pre-run args from data (optional).\n * This is called during setData to compute the args that will be used for staging/pre-run phase.\n *\n * If not defined, defaults to using the args() function result.\n * If defined, uses its return value for the staging / prerun phase.\n *\n * The staging / prerun phase runs only if currentPrerunArgs differs from the executed\n * version of prerunArgs (same comparison logic as currentArgs vs prodArgs).\n *\n * @example\n * .prerunArgs((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .prerunArgs((data) => {\n * // Return undefined to skip staging for this block\n * if (!data.isReady) return undefined;\n * return { numbers: data.numbers };\n * })\n */\n public prerunArgs(\n fn: (data: Data) => unknown,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n prerunArgsFunction: fn as (data: unknown) => unknown,\n });\n }\n\n /** Sets the lambda to generate list of sections in the left block overviews panel. */\n public sections<\n const Ret extends SectionsExpectedType,\n const RF extends RenderFunction<Args, Data, Ret>,\n >(rf: RF): BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers>(\n {\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n {\n handle: \"sections\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n },\n true,\n ),\n },\n );\n }\n\n /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */\n public title(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n title: createAndRegisterRenderLambda({\n handle: \"title\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n public subtitle(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n subtitle: createAndRegisterRenderLambda({\n handle: \"subtitle\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n public tags(\n rf: RenderFunction<Args, Data, string[]>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n tags: createAndRegisterRenderLambda({\n handle: \"tags\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n /** Sets or overrides feature flags for the block. */\n public withFeatureFlags(\n flags: Partial<BlockCodeKnownFeatureFlags>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n featureFlags: { ...this.config.featureFlags, ...flags },\n });\n }\n\n /**\n * Defines how to derive list of upstream references this block is meant to enrich with its exports from block args.\n * Influences dependency graph construction.\n */\n public enriches(\n lambda: (args: Args) => PlRef[],\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n enrichmentTargets: createAndRegisterRenderLambda({\n handle: \"enrichmentTargets\",\n lambda: lambda,\n }),\n });\n }\n\n /**\n * Registers a plugin instance with the block.\n * Consumes a transfer if one was defined for this plugin ID in the migration chain.\n *\n * Type checks:\n * - If Transfers[Id] exists, verifies it extends PTransferData (transfer type compatibility)\n * - If no Transfers[Id], rejects plugins with transferAt set (missing .transfer() in data model)\n * - Rejects duplicate plugin IDs (Id already in keyof Plugins)\n *\n * @param instance - PluginInstance created via factory.create({ pluginId, ... })\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin(mainTable, {\n * columns: (ctx) => ctx.outputs?.resolve(\"data\")?.getPColumns(),\n * sourceId: (ctx) => ctx.data.selectedSource,\n * })\n */\n public plugin<\n const PluginId extends string,\n PData extends PluginData,\n PParams extends PluginParams,\n POutputs extends PluginOutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices,\n >(\n instance: PluginInstanceClass<\n PluginId &\n (PluginId extends keyof Transfers\n ? Transfers[PluginId] extends PTransferData\n ? string\n : never\n : [PTransferData] extends [never]\n ? string\n : never) &\n (PluginId extends keyof Plugins ? never : string),\n PData,\n PParams,\n POutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices\n >,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & {\n [K in PluginId]: PluginRecord<\n PData,\n PParams,\n POutputs,\n PluginModelServices,\n PluginUiServices\n >;\n },\n Omit<Transfers, PluginId>\n >;\n public plugin(\n instance: PluginInstanceClass,\n params?: ParamsInput<Record<string, unknown>, unknown, unknown>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Record<string, PluginRecord>,\n Record<string, unknown>\n > {\n const pluginId = instance.id;\n const plugin = instance[CREATE_PLUGIN_MODEL]();\n const resolvedParams = (params ?? {}) as ParamsInputErased;\n\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const registered: PluginRecord = {\n model: plugin,\n inputs: resolvedParams,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: registered,\n },\n featureFlags: mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),\n });\n }\n\n /** Renders all provided block settings into a pre-configured platforma API\n * instance, that can be used in frontend to interact with block data, and\n * other features provided by the platforma to the block.\n *\n * Type-level check: if there are unconsumed transfers (from `.transfer()` calls\n * in the migration chain), this method requires an impossible `never` argument,\n * producing a compile error. Register all transferred plugins via `.plugin(instance)`\n * before calling `.done()`.\n */\n public done(\n ..._: keyof Transfers extends never ? [] : [never]\n ): PlatformaExtended<\n PlatformaV3<\n Data,\n Args,\n InferOutputsFromLambdas<OutputsCfg>,\n Href,\n Plugins,\n BlockDefaultUiServices\n >\n > {\n if (this.config.argsFunction === undefined) throw new Error(\"Args rendering function not set.\");\n\n const apiVersion = 3;\n\n // Build plugin registry\n const { plugins } = this.config;\n const pluginRegistry: Record<string, PluginName> = {};\n const pluginHandles = Object.keys(plugins) as PluginHandle[];\n for (const handle of pluginHandles) {\n pluginRegistry[handle] = plugins[handle].model.name;\n }\n\n const { dataModel, argsFunction, prerunArgsFunction } = this.config;\n\n function getPlugin(handle: PluginHandle): PluginRecord {\n const plugin = plugins[handle];\n if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);\n return plugin;\n }\n\n // Register ALL facade callbacks here, with dependencies captured via closures\n registerFacadeCallbacks({\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: applyStorageUpdate,\n [BlockStorageFacadeCallbacks.StorageDebugView]: getStorageDebugView,\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson) =>\n migrateStorage(currentStorageJson, {\n migrateBlockData: (v) => dataModel.migrate(v),\n getPluginRegistry: () => pluginRegistry,\n migratePluginData: (handle, v) => getPlugin(handle).model.dataModel.migrate(v),\n createPluginData: (handle, transfer) => {\n if (transfer) return transfer;\n return getPlugin(handle).model.getDefaultData();\n },\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) =>\n deriveArgsFromStorage(storageJson, argsFunction),\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) =>\n derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction),\n });\n\n // Register plugin input and output lambdas\n const pluginOutputs: Record<string, ConfigRenderLambda> = {};\n for (const handle of pluginHandles) {\n const { model, inputs } = plugins[handle];\n // Wrap plugin param lambdas: close over BlockRenderCtx creation\n const wrappedInputs: Record<string, () => unknown> = {};\n for (const [paramKey, paramFn] of Object.entries(inputs)) {\n wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());\n }\n\n // Register plugin outputs (in config pack, evaluated by middle layer)\n const outputs = model.outputs as Record<string, (ctx: PluginRenderCtx) => unknown>;\n const { outputFlags } = model;\n for (const [outputKey, outputFn] of Object.entries(outputs)) {\n const key = pluginOutputKey(handle, outputKey);\n pluginOutputs[key] = createAndRegisterRenderLambda({\n handle: key,\n lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),\n withStatus: outputFlags[outputKey]?.withStatus,\n });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI()) {\n const blockConfig: BlockConfigContainer = {\n v4: {\n configVersion: 4,\n modelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n title: this.config.title,\n subtitle: this.config.subtitle,\n tags: this.config.tags,\n outputs: allOutputs,\n enrichmentTargets: this.config.enrichmentTargets,\n featureFlags: this.config.featureFlags,\n blockLifecycleCallbacks: { ...BlockStorageFacadeHandles },\n },\n\n // fields below are added to allow previous desktop versions read generated configs\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n outputs: Object.fromEntries(\n Object.entries(this.config.outputs).map(([key, value]) => [\n key,\n downgradeCfgOrLambda(value),\n ]),\n ),\n };\n // we are in the configuration rendering routine, not in actual UI\n return { config: blockConfig } as any;\n // normal operation inside the UI\n } else {\n return {\n ...getPlatformaInstance({\n sdkVersion: PlatformaSDKVersion,\n apiVersion,\n }),\n blockModelInfo: {\n outputs: Object.fromEntries(\n Object.entries(allOutputs).map(([key, value]) => [\n key,\n {\n withStatus: Boolean(isConfigLambda(value) && value.withStatus),\n },\n ]),\n ),\n pluginIds: pluginHandles,\n featureFlags: this.config.featureFlags,\n },\n } as any;\n }\n }\n}\n\n// Type tests for BlockModelV3\n\nexport type Expect<T extends true> = T;\n\nexport type Equal<X, Y> =\n (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;\n\nexport type Merge<A, B> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;\n};\n\n// Helper types for testing\ntype _TestArgs = { inputFile: string; threshold: number };\ntype _TestData = { selectedTab: string };\ntype _TestOutputs = {\n result: ConfigRenderLambda<string>;\n count: ConfigRenderLambda<number>;\n};\n\n// Test: Merge type works correctly\ntype _MergeTest1 = Expect<Equal<Merge<{ a: 1 }, { b: 2 }>, { a: 1; b: 2 }>>;\ntype _MergeTest2 = Expect<Equal<Merge<{ a: 1 }, { a: 2 }>, { a: 2 }>>;\ntype _MergeTest3 = Expect<Equal<Merge<{ a: 1; b: 1 }, { b: 2; c: 3 }>, { a: 1; b: 2; c: 3 }>>;\n\n// Test: create() returns a BlockModelV3 instance\n// Note: Due to function overloads, ReturnType uses the last overload signature.\n// We verify the structure is correct using a simpler assignability test.\ntype _CreateResult = ReturnType<typeof BlockModelV3.create>;\ntype _CreateIsBlockModelV3 =\n _CreateResult extends BlockModelV3<infer _A, infer _O, infer _S> ? true : false;\ntype _CreateTest = Expect<_CreateIsBlockModelV3>;\n\n// Test: BlockModelV3Config interface structure (default generics)\ntype _ConfigTest = Expect<\n Equal<\n BlockModelV3Config<_TestOutputs, _TestData>,\n {\n renderingMode: BlockRenderingMode;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n dataModel: DataModel<_TestData, {}>;\n outputs: _TestOutputs;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n plugins: {};\n }\n >\n>;\n\n// Test: Default Href is '/'\ntype _HrefDefaultTest =\n BlockModelV3<_TestArgs, {}, _TestData> extends BlockModelV3<_TestArgs, {}, _TestData, \"/\">\n ? true\n : false;\ntype _VerifyHrefDefault = Expect<_HrefDefaultTest>;\n\n// Test: Custom Href can be specified\ntype _CustomHref = \"/settings\" | \"/main\";\ntype _HrefCustomBuilder = BlockModelV3<_TestArgs, {}, _TestData, _CustomHref>;\ntype _HrefCustomTest =\n _HrefCustomBuilder extends BlockModelV3<_TestArgs, {}, _TestData, _CustomHref> ? true : false;\ntype _VerifyHrefCustom = Expect<_HrefCustomTest>;\n\n// Test: Output type accumulation with & intersection\ntype _OutputsAccumulation = { a: ConfigRenderLambda<string> } & {\n b: ConfigRenderLambda<number>;\n};\ntype _VerifyOutputsHaveKeys = Expect<Equal<keyof _OutputsAccumulation, \"a\" | \"b\">>;\n\n// Test: Builder with all type parameters specified compiles\ntype _FullBuilder = BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\">;\ntype _FullBuilderTest =\n _FullBuilder extends BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\"> ? true : false;\ntype _VerifyFullBuilder = Expect<_FullBuilderTest>;\n\n// Test: InferOutputsFromLambdas maps outputs correctly\ntype _InferOutputsTest = InferOutputsFromLambdas<{\n myOutput: ConfigRenderLambda<number>;\n}>;\ntype _VerifyInferOutputs = Expect<\n Equal<_InferOutputsTest, { myOutput: OutputWithStatus<number> & { __unwrap: true } }>\n>;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_model.d.ts","names":[],"sources":["../src/block_model.ts"],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"block_model.d.ts","names":[],"sources":["../src/block_model.ts"],"mappings":"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"}
|
package/dist/block_model.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { pluginOutputKey } from "./plugin_handle.js";
|
|
2
2
|
import { createAndRegisterRenderLambda, getPlatformaInstance, isInUI } from "./internal.js";
|
|
3
3
|
import { BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, registerFacadeCallbacks } from "./block_storage_facade.js";
|
|
4
|
+
import { BLOCK_SERVICE_FLAGS } from "./services/block_services.js";
|
|
4
5
|
import { BlockRenderCtx, PluginRenderCtx } from "./render/api.js";
|
|
5
6
|
import "./render/index.js";
|
|
6
7
|
import { PlatformaSDKVersion } from "./version.js";
|
|
7
8
|
import { isConfigLambda } from "./bconfig/types.js";
|
|
8
9
|
import { downgradeCfgOrLambda } from "./bconfig/normalization.js";
|
|
9
10
|
import "./bconfig/index.js";
|
|
10
|
-
import { BLOCK_SERVICE_FLAGS, blockServiceNames } from "./services/block_services.js";
|
|
11
11
|
import { CREATE_PLUGIN_MODEL } from "./plugin_model.js";
|
|
12
12
|
import { applyStorageUpdate, createInitialStorage, deriveArgsFromStorage, derivePrerunArgsFromStorage, getStorageDebugView, migrateStorage } from "./block_storage_callbacks.js";
|
|
13
|
-
import { resolveRequiredServices } from "@milaboratories/pl-model-common";
|
|
14
13
|
//#region src/block_model.ts
|
|
15
14
|
/**
|
|
16
15
|
* Merges two feature flag objects with type-aware logic:
|
|
@@ -86,7 +85,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
86
85
|
...this.config.outputs,
|
|
87
86
|
[key]: createAndRegisterRenderLambda({
|
|
88
87
|
handle: `block-output#${key}`,
|
|
89
|
-
lambda: () => cfgOrRf(new BlockRenderCtx(
|
|
88
|
+
lambda: () => cfgOrRf(new BlockRenderCtx()),
|
|
90
89
|
...flags
|
|
91
90
|
})
|
|
92
91
|
}
|
|
@@ -151,7 +150,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
151
150
|
...this.config,
|
|
152
151
|
sections: createAndRegisterRenderLambda({
|
|
153
152
|
handle: "sections",
|
|
154
|
-
lambda: () => rf(new BlockRenderCtx(
|
|
153
|
+
lambda: () => rf(new BlockRenderCtx())
|
|
155
154
|
}, true)
|
|
156
155
|
});
|
|
157
156
|
}
|
|
@@ -161,7 +160,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
161
160
|
...this.config,
|
|
162
161
|
title: createAndRegisterRenderLambda({
|
|
163
162
|
handle: "title",
|
|
164
|
-
lambda: () => rf(new BlockRenderCtx(
|
|
163
|
+
lambda: () => rf(new BlockRenderCtx())
|
|
165
164
|
})
|
|
166
165
|
});
|
|
167
166
|
}
|
|
@@ -170,7 +169,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
170
169
|
...this.config,
|
|
171
170
|
subtitle: createAndRegisterRenderLambda({
|
|
172
171
|
handle: "subtitle",
|
|
173
|
-
lambda: () => rf(new BlockRenderCtx(
|
|
172
|
+
lambda: () => rf(new BlockRenderCtx())
|
|
174
173
|
})
|
|
175
174
|
});
|
|
176
175
|
}
|
|
@@ -179,7 +178,7 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
179
178
|
...this.config,
|
|
180
179
|
tags: createAndRegisterRenderLambda({
|
|
181
180
|
handle: "tags",
|
|
182
|
-
lambda: () => rf(new BlockRenderCtx(
|
|
181
|
+
lambda: () => rf(new BlockRenderCtx())
|
|
183
182
|
})
|
|
184
183
|
});
|
|
185
184
|
}
|
|
@@ -241,7 +240,6 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
241
240
|
const pluginHandles = Object.keys(plugins);
|
|
242
241
|
for (const handle of pluginHandles) pluginRegistry[handle] = plugins[handle].model.name;
|
|
243
242
|
const { dataModel, argsFunction, prerunArgsFunction } = this.config;
|
|
244
|
-
const mergedServiceNames = resolveRequiredServices(this.config.featureFlags);
|
|
245
243
|
function getPlugin(handle) {
|
|
246
244
|
const plugin = plugins[handle];
|
|
247
245
|
if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);
|
|
@@ -271,14 +269,14 @@ var BlockModelV3 = class BlockModelV3 {
|
|
|
271
269
|
for (const handle of pluginHandles) {
|
|
272
270
|
const { model, inputs } = plugins[handle];
|
|
273
271
|
const wrappedInputs = {};
|
|
274
|
-
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx(
|
|
272
|
+
for (const [paramKey, paramFn] of Object.entries(inputs)) wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());
|
|
275
273
|
const outputs = model.outputs;
|
|
276
274
|
const { outputFlags } = model;
|
|
277
275
|
for (const [outputKey, outputFn] of Object.entries(outputs)) {
|
|
278
276
|
const key = pluginOutputKey(handle, outputKey);
|
|
279
277
|
pluginOutputs[key] = createAndRegisterRenderLambda({
|
|
280
278
|
handle: key,
|
|
281
|
-
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs
|
|
279
|
+
lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),
|
|
282
280
|
withStatus: outputFlags[outputKey]?.withStatus
|
|
283
281
|
});
|
|
284
282
|
}
|
package/dist/block_model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_model.js","names":[],"sources":["../src/block_model.ts"],"sourcesContent":["import type {\n BlockRenderingMode,\n BlockSection,\n OutputWithStatus,\n PlRef,\n BlockCodeKnownFeatureFlags,\n BlockConfigContainer,\n} from \"@milaboratories/pl-model-common\";\nimport { resolveRequiredServices } from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { BlockDefaultUiServices } from \"./services/service_resolve\";\nimport { blockServiceNames, BLOCK_SERVICE_FLAGS } from \"./services/block_services\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } from \"./plugin_model\";\nimport { PluginInstance as PluginInstanceClass, CREATE_PLUGIN_MODEL } from \"./plugin_model\";\nimport { type PluginHandle, pluginOutputKey } from \"./plugin_handle\";\nimport type { RenderCtxBase } from \"./render\";\nimport { PlatformaSDKVersion } from \"./version\";\nimport {\n applyStorageUpdate,\n getStorageDebugView,\n migrateStorage,\n createInitialStorage,\n deriveArgsFromStorage,\n derivePrerunArgsFromStorage,\n} from \"./block_storage_callbacks\";\nimport { type PluginName } from \"./block_storage\";\nimport type {\n ConfigRenderLambda,\n DeriveHref,\n ConfigRenderLambdaFlags,\n InferOutputsFromLambdas,\n} from \"./bconfig\";\nimport { downgradeCfgOrLambda, isConfigLambda } from \"./bconfig\";\nimport type { PlatformaExtended } from \"./platforma\";\nimport {\n BLOCK_STORAGE_FACADE_VERSION,\n BlockStorageFacadeCallbacks,\n BlockStorageFacadeHandles,\n registerFacadeCallbacks,\n} from \"./block_storage_facade\";\n\ntype SectionsExpectedType = readonly BlockSection[];\n\ntype NoOb = Record<string, never>;\n\n/**\n * Per-property lambdas for deriving plugin params from block render context.\n * Each property is a function that receives the block's RenderCtxBase and returns the param value.\n */\nexport type ParamsInput<Params, BArgs = unknown, BData = unknown> = {\n [K in keyof Params]: (ctx: RenderCtxBase<BArgs, BData>) => Params[K];\n};\n\n/**\n * Type-erased version of ParamsInput for internal storage.\n */\ntype ParamsInputErased = Record<string, (ctx: RenderCtxBase) => unknown>;\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nfunction mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (typeof existing === \"boolean\" && existing) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max(typeof existing === \"number\" ? existing : 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\n/**\n * Plugin record: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginRecord<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n ModelServices = unknown,\n UiServices = unknown,\n> = {\n readonly model: PluginModel<Data, Params, Outputs, ModelServices, UiServices>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data, Transfers>;\n outputs: OutputsCfg;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n plugins: Plugins;\n}\n\n/** Main entry point that each block should use in it's \"config\" module. Don't forget\n * to call {@link done()} at the end of configuration. Value returned by this builder must be\n * exported as constant with name \"platforma\" from the \"config\" module.\n * API version is 3 (for UI) and 2 (for model) */\nexport class BlockModelV3<\n Args,\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data extends Record<string, unknown> = Record<string, unknown>,\n Href extends `/${string}` = \"/\",\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n private constructor(\n private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins, Transfers>,\n ) {}\n\n public static readonly FEATURE_FLAGS = {\n supportsLazyState: true,\n supportsPframeQueryRanking: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n ...BLOCK_SERVICE_FLAGS,\n } satisfies BlockCodeKnownFeatureFlags;\n\n /** @deprecated Use FEATURE_FLAGS */\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;\n\n /**\n * Creates a new BlockModelV3 builder with the specified data model.\n *\n * @example\n * const dataModel = new DataModelBuilder()\n * .from<BlockData>(\"v1\")\n * .init(() => ({ numbers: [], labels: [] }));\n *\n * BlockModelV3.create(dataModel)\n * .args((data) => ({ numbers: data.numbers }))\n * .sections(() => [{ type: 'link', href: '/', label: 'Main' }])\n * .done();\n *\n * @param dataModel The data model that defines initial data and migrations\n */\n public static create<\n Data extends Record<string, unknown>,\n Transfers extends Record<string, unknown> = {},\n >(dataModel: DataModel<Data, Transfers>): BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers> {\n return new BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers>({\n renderingMode: \"Heavy\",\n dataModel,\n outputs: {},\n sections: createAndRegisterRenderLambda({ handle: \"sections\", lambda: () => [] }, true),\n title: undefined,\n subtitle: undefined,\n tags: undefined,\n enrichmentTargets: undefined,\n featureFlags: { ...BlockModelV3.FEATURE_FLAGS },\n argsFunction: undefined,\n prerunArgsFunction: undefined,\n plugins: {},\n });\n }\n\n /**\n * Add output cell wrapped with additional status information to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags: ConfigRenderLambdaFlags & { withStatus: true },\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> & {\n withStatus: true;\n };\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n /**\n * Add output cell to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags?: ConfigRenderLambdaFlags,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3({\n ...this.config,\n outputs: {\n ...this.config.outputs,\n [key]: createAndRegisterRenderLambda({\n handle: `block-output#${key}`,\n lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n ...flags,\n }),\n },\n });\n }\n\n /** Shortcut for {@link output} with retentive flag set to true. */\n public retentiveOutput<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(\n key: Key,\n rf: RF,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n > {\n return this.output(key, rf, { retentive: true });\n }\n\n /** Shortcut for {@link output} with withStatus flag set to true. */\n public outputWithStatus<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(key: Key, rf: RF) {\n return this.output(key, rf, { withStatus: true });\n }\n\n /**\n * Sets a function to derive block args from data.\n * This is called during setData to compute the args that will be used for block execution.\n *\n * @example\n * .args<BlockArgs>((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .args<BlockArgs>((data) => {\n * if (data.numbers.length === 0) throw new Error('Numbers required'); // block not ready\n * return { numbers: data.numbers };\n * })\n */\n public args<A>(\n lambda: (data: Data) => A,\n ): BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n argsFunction: lambda as (data: unknown) => unknown,\n });\n }\n\n /**\n * Sets a function to derive pre-run args from data (optional).\n * This is called during setData to compute the args that will be used for staging/pre-run phase.\n *\n * If not defined, defaults to using the args() function result.\n * If defined, uses its return value for the staging / prerun phase.\n *\n * The staging / prerun phase runs only if currentPrerunArgs differs from the executed\n * version of prerunArgs (same comparison logic as currentArgs vs prodArgs).\n *\n * @example\n * .prerunArgs((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .prerunArgs((data) => {\n * // Return undefined to skip staging for this block\n * if (!data.isReady) return undefined;\n * return { numbers: data.numbers };\n * })\n */\n public prerunArgs(\n fn: (data: Data) => unknown,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n prerunArgsFunction: fn as (data: unknown) => unknown,\n });\n }\n\n /** Sets the lambda to generate list of sections in the left block overviews panel. */\n public sections<\n const Ret extends SectionsExpectedType,\n const RF extends RenderFunction<Args, Data, Ret>,\n >(rf: RF): BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers>(\n {\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n {\n handle: \"sections\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n },\n true,\n ),\n },\n );\n }\n\n /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */\n public title(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n title: createAndRegisterRenderLambda({\n handle: \"title\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n public subtitle(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n subtitle: createAndRegisterRenderLambda({\n handle: \"subtitle\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n public tags(\n rf: RenderFunction<Args, Data, string[]>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n tags: createAndRegisterRenderLambda({\n handle: \"tags\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>(blockServiceNames)),\n }),\n });\n }\n\n /** Sets or overrides feature flags for the block. */\n public withFeatureFlags(\n flags: Partial<BlockCodeKnownFeatureFlags>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n featureFlags: { ...this.config.featureFlags, ...flags },\n });\n }\n\n /**\n * Defines how to derive list of upstream references this block is meant to enrich with its exports from block args.\n * Influences dependency graph construction.\n */\n public enriches(\n lambda: (args: Args) => PlRef[],\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n enrichmentTargets: createAndRegisterRenderLambda({\n handle: \"enrichmentTargets\",\n lambda: lambda,\n }),\n });\n }\n\n /**\n * Registers a plugin instance with the block.\n * Consumes a transfer if one was defined for this plugin ID in the migration chain.\n *\n * Type checks:\n * - If Transfers[Id] exists, verifies it extends PTransferData (transfer type compatibility)\n * - If no Transfers[Id], rejects plugins with transferAt set (missing .transfer() in data model)\n * - Rejects duplicate plugin IDs (Id already in keyof Plugins)\n *\n * @param instance - PluginInstance created via factory.create({ pluginId, ... })\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin(mainTable, {\n * columns: (ctx) => ctx.outputs?.resolve(\"data\")?.getPColumns(),\n * sourceId: (ctx) => ctx.data.selectedSource,\n * })\n */\n public plugin<\n const PluginId extends string,\n PData extends PluginData,\n PParams extends PluginParams,\n POutputs extends PluginOutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices,\n >(\n instance: PluginInstanceClass<\n PluginId &\n (PluginId extends keyof Transfers\n ? Transfers[PluginId] extends PTransferData\n ? string\n : never\n : [PTransferData] extends [never]\n ? string\n : never) &\n (PluginId extends keyof Plugins ? never : string),\n PData,\n PParams,\n POutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices\n >,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & {\n [K in PluginId]: PluginRecord<\n PData,\n PParams,\n POutputs,\n PluginModelServices,\n PluginUiServices\n >;\n },\n Omit<Transfers, PluginId>\n >;\n public plugin(\n instance: PluginInstanceClass,\n params?: ParamsInput<Record<string, unknown>, unknown, unknown>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Record<string, PluginRecord>,\n Record<string, unknown>\n > {\n const pluginId = instance.id;\n const plugin = instance[CREATE_PLUGIN_MODEL]();\n const resolvedParams = (params ?? {}) as ParamsInputErased;\n\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const registered: PluginRecord = {\n model: plugin,\n inputs: resolvedParams,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: registered,\n },\n featureFlags: mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),\n });\n }\n\n /** Renders all provided block settings into a pre-configured platforma API\n * instance, that can be used in frontend to interact with block data, and\n * other features provided by the platforma to the block.\n *\n * Type-level check: if there are unconsumed transfers (from `.transfer()` calls\n * in the migration chain), this method requires an impossible `never` argument,\n * producing a compile error. Register all transferred plugins via `.plugin(instance)`\n * before calling `.done()`.\n */\n public done(\n ..._: keyof Transfers extends never ? [] : [never]\n ): PlatformaExtended<\n PlatformaV3<\n Data,\n Args,\n InferOutputsFromLambdas<OutputsCfg>,\n Href,\n Plugins,\n BlockDefaultUiServices\n >\n > {\n if (this.config.argsFunction === undefined) throw new Error(\"Args rendering function not set.\");\n\n const apiVersion = 3;\n\n // Build plugin registry\n const { plugins } = this.config;\n const pluginRegistry: Record<string, PluginName> = {};\n const pluginHandles = Object.keys(plugins) as PluginHandle[];\n for (const handle of pluginHandles) {\n pluginRegistry[handle] = plugins[handle].model.name;\n }\n\n const { dataModel, argsFunction, prerunArgsFunction } = this.config;\n\n const mergedServiceNames = resolveRequiredServices(this.config.featureFlags);\n\n function getPlugin(handle: PluginHandle): PluginRecord {\n const plugin = plugins[handle];\n if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);\n return plugin;\n }\n\n // Register ALL facade callbacks here, with dependencies captured via closures\n registerFacadeCallbacks({\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: applyStorageUpdate,\n [BlockStorageFacadeCallbacks.StorageDebugView]: getStorageDebugView,\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson) =>\n migrateStorage(currentStorageJson, {\n migrateBlockData: (v) => dataModel.migrate(v),\n getPluginRegistry: () => pluginRegistry,\n migratePluginData: (handle, v) => getPlugin(handle).model.dataModel.migrate(v),\n createPluginData: (handle, transfer) => {\n if (transfer) return transfer;\n return getPlugin(handle).model.getDefaultData();\n },\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) =>\n deriveArgsFromStorage(storageJson, argsFunction),\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) =>\n derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction),\n });\n\n // Register plugin input and output lambdas\n const pluginOutputs: Record<string, ConfigRenderLambda> = {};\n for (const handle of pluginHandles) {\n const { model, inputs } = plugins[handle];\n // Wrap plugin param lambdas: close over BlockRenderCtx creation\n const wrappedInputs: Record<string, () => unknown> = {};\n for (const [paramKey, paramFn] of Object.entries(inputs)) {\n wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx(mergedServiceNames));\n }\n\n // Register plugin outputs (in config pack, evaluated by middle layer)\n const outputs = model.outputs as Record<string, (ctx: PluginRenderCtx) => unknown>;\n const { outputFlags } = model;\n for (const [outputKey, outputFn] of Object.entries(outputs)) {\n const key = pluginOutputKey(handle, outputKey);\n pluginOutputs[key] = createAndRegisterRenderLambda({\n handle: key,\n lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs, mergedServiceNames)),\n withStatus: outputFlags[outputKey]?.withStatus,\n });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI()) {\n const blockConfig: BlockConfigContainer = {\n v4: {\n configVersion: 4,\n modelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n title: this.config.title,\n subtitle: this.config.subtitle,\n tags: this.config.tags,\n outputs: allOutputs,\n enrichmentTargets: this.config.enrichmentTargets,\n featureFlags: this.config.featureFlags,\n blockLifecycleCallbacks: { ...BlockStorageFacadeHandles },\n },\n\n // fields below are added to allow previous desktop versions read generated configs\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n outputs: Object.fromEntries(\n Object.entries(this.config.outputs).map(([key, value]) => [\n key,\n downgradeCfgOrLambda(value),\n ]),\n ),\n };\n // we are in the configuration rendering routine, not in actual UI\n return { config: blockConfig } as any;\n // normal operation inside the UI\n } else {\n return {\n ...getPlatformaInstance({\n sdkVersion: PlatformaSDKVersion,\n apiVersion,\n }),\n blockModelInfo: {\n outputs: Object.fromEntries(\n Object.entries(allOutputs).map(([key, value]) => [\n key,\n {\n withStatus: Boolean(isConfigLambda(value) && value.withStatus),\n },\n ]),\n ),\n pluginIds: pluginHandles,\n featureFlags: this.config.featureFlags,\n },\n } as any;\n }\n }\n}\n\n// Type tests for BlockModelV3\n\nexport type Expect<T extends true> = T;\n\nexport type Equal<X, Y> =\n (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;\n\nexport type Merge<A, B> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;\n};\n\n// Helper types for testing\ntype _TestArgs = { inputFile: string; threshold: number };\ntype _TestData = { selectedTab: string };\ntype _TestOutputs = {\n result: ConfigRenderLambda<string>;\n count: ConfigRenderLambda<number>;\n};\n\n// Test: Merge type works correctly\ntype _MergeTest1 = Expect<Equal<Merge<{ a: 1 }, { b: 2 }>, { a: 1; b: 2 }>>;\ntype _MergeTest2 = Expect<Equal<Merge<{ a: 1 }, { a: 2 }>, { a: 2 }>>;\ntype _MergeTest3 = Expect<Equal<Merge<{ a: 1; b: 1 }, { b: 2; c: 3 }>, { a: 1; b: 2; c: 3 }>>;\n\n// Test: create() returns a BlockModelV3 instance\n// Note: Due to function overloads, ReturnType uses the last overload signature.\n// We verify the structure is correct using a simpler assignability test.\ntype _CreateResult = ReturnType<typeof BlockModelV3.create>;\ntype _CreateIsBlockModelV3 =\n _CreateResult extends BlockModelV3<infer _A, infer _O, infer _S> ? true : false;\ntype _CreateTest = Expect<_CreateIsBlockModelV3>;\n\n// Test: BlockModelV3Config interface structure (default generics)\ntype _ConfigTest = Expect<\n Equal<\n BlockModelV3Config<_TestOutputs, _TestData>,\n {\n renderingMode: BlockRenderingMode;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n dataModel: DataModel<_TestData, {}>;\n outputs: _TestOutputs;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n plugins: {};\n }\n >\n>;\n\n// Test: Default Href is '/'\ntype _HrefDefaultTest =\n BlockModelV3<_TestArgs, {}, _TestData> extends BlockModelV3<_TestArgs, {}, _TestData, \"/\">\n ? true\n : false;\ntype _VerifyHrefDefault = Expect<_HrefDefaultTest>;\n\n// Test: Custom Href can be specified\ntype _CustomHref = \"/settings\" | \"/main\";\ntype _HrefCustomBuilder = BlockModelV3<_TestArgs, {}, _TestData, _CustomHref>;\ntype _HrefCustomTest =\n _HrefCustomBuilder extends BlockModelV3<_TestArgs, {}, _TestData, _CustomHref> ? true : false;\ntype _VerifyHrefCustom = Expect<_HrefCustomTest>;\n\n// Test: Output type accumulation with & intersection\ntype _OutputsAccumulation = { a: ConfigRenderLambda<string> } & {\n b: ConfigRenderLambda<number>;\n};\ntype _VerifyOutputsHaveKeys = Expect<Equal<keyof _OutputsAccumulation, \"a\" | \"b\">>;\n\n// Test: Builder with all type parameters specified compiles\ntype _FullBuilder = BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\">;\ntype _FullBuilderTest =\n _FullBuilder extends BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\"> ? true : false;\ntype _VerifyFullBuilder = Expect<_FullBuilderTest>;\n\n// Test: InferOutputsFromLambdas maps outputs correctly\ntype _InferOutputsTest = InferOutputsFromLambdas<{\n myOutput: ConfigRenderLambda<number>;\n}>;\ntype _VerifyInferOutputs = Expect<\n Equal<_InferOutputsTest, { myOutput: OutputWithStatus<number> & { __unwrap: true } }>\n>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"block_model.js","names":[],"sources":["../src/block_model.ts"],"sourcesContent":["import type {\n BlockRenderingMode,\n BlockSection,\n OutputWithStatus,\n PlRef,\n BlockCodeKnownFeatureFlags,\n BlockConfigContainer,\n} from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { BlockDefaultUiServices } from \"./services/service_resolve\";\nimport { BLOCK_SERVICE_FLAGS } from \"./services/block_services\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } from \"./plugin_model\";\nimport { PluginInstance as PluginInstanceClass, CREATE_PLUGIN_MODEL } from \"./plugin_model\";\nimport { type PluginHandle, pluginOutputKey } from \"./plugin_handle\";\nimport type { RenderCtxBase } from \"./render\";\nimport { PlatformaSDKVersion } from \"./version\";\nimport {\n applyStorageUpdate,\n getStorageDebugView,\n migrateStorage,\n createInitialStorage,\n deriveArgsFromStorage,\n derivePrerunArgsFromStorage,\n} from \"./block_storage_callbacks\";\nimport { type PluginName } from \"./block_storage\";\nimport type {\n ConfigRenderLambda,\n DeriveHref,\n ConfigRenderLambdaFlags,\n InferOutputsFromLambdas,\n} from \"./bconfig\";\nimport { downgradeCfgOrLambda, isConfigLambda } from \"./bconfig\";\nimport type { PlatformaExtended } from \"./platforma\";\nimport {\n BLOCK_STORAGE_FACADE_VERSION,\n BlockStorageFacadeCallbacks,\n BlockStorageFacadeHandles,\n registerFacadeCallbacks,\n} from \"./block_storage_facade\";\n\ntype SectionsExpectedType = readonly BlockSection[];\n\ntype NoOb = Record<string, never>;\n\n/**\n * Per-property lambdas for deriving plugin params from block render context.\n * Each property is a function that receives the block's RenderCtxBase and returns the param value.\n */\nexport type ParamsInput<Params, BArgs = unknown, BData = unknown> = {\n [K in keyof Params]: (ctx: RenderCtxBase<BArgs, BData>) => Params[K];\n};\n\n/**\n * Type-erased version of ParamsInput for internal storage.\n */\ntype ParamsInputErased = Record<string, (ctx: RenderCtxBase) => unknown>;\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nfunction mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (typeof existing === \"boolean\" && existing) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max(typeof existing === \"number\" ? existing : 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\n/**\n * Plugin record: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginRecord<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n ModelServices = unknown,\n UiServices = unknown,\n> = {\n readonly model: PluginModel<Data, Params, Outputs, ModelServices, UiServices>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data, Transfers>;\n outputs: OutputsCfg;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n plugins: Plugins;\n}\n\n/** Main entry point that each block should use in it's \"config\" module. Don't forget\n * to call {@link done()} at the end of configuration. Value returned by this builder must be\n * exported as constant with name \"platforma\" from the \"config\" module.\n * API version is 3 (for UI) and 2 (for model) */\nexport class BlockModelV3<\n Args,\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data extends Record<string, unknown> = Record<string, unknown>,\n Href extends `/${string}` = \"/\",\n Plugins extends Record<string, PluginRecord> = {},\n Transfers extends Record<string, unknown> = {},\n> {\n private constructor(\n private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins, Transfers>,\n ) {}\n\n public static readonly FEATURE_FLAGS = {\n supportsLazyState: true,\n supportsPframeQueryRanking: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n ...BLOCK_SERVICE_FLAGS,\n } satisfies BlockCodeKnownFeatureFlags;\n\n /** @deprecated Use FEATURE_FLAGS */\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;\n\n /**\n * Creates a new BlockModelV3 builder with the specified data model.\n *\n * @example\n * const dataModel = new DataModelBuilder()\n * .from<BlockData>(\"v1\")\n * .init(() => ({ numbers: [], labels: [] }));\n *\n * BlockModelV3.create(dataModel)\n * .args((data) => ({ numbers: data.numbers }))\n * .sections(() => [{ type: 'link', href: '/', label: 'Main' }])\n * .done();\n *\n * @param dataModel The data model that defines initial data and migrations\n */\n public static create<\n Data extends Record<string, unknown>,\n Transfers extends Record<string, unknown> = {},\n >(dataModel: DataModel<Data, Transfers>): BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers> {\n return new BlockModelV3<NoOb, {}, Data, \"/\", {}, Transfers>({\n renderingMode: \"Heavy\",\n dataModel,\n outputs: {},\n sections: createAndRegisterRenderLambda({ handle: \"sections\", lambda: () => [] }, true),\n title: undefined,\n subtitle: undefined,\n tags: undefined,\n enrichmentTargets: undefined,\n featureFlags: { ...BlockModelV3.FEATURE_FLAGS },\n argsFunction: undefined,\n prerunArgsFunction: undefined,\n plugins: {},\n });\n }\n\n /**\n * Add output cell wrapped with additional status information to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags: ConfigRenderLambdaFlags & { withStatus: true },\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> & {\n withStatus: true;\n };\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n /**\n * Add output cell to the configuration\n *\n * @param key output cell name, that can be later used to retrieve the rendered value\n * @param rf callback calculating output value using context, that allows to access\n * workflows outputs and interact with platforma drivers\n * @param flags additional flags that may alter lambda rendering procedure\n * */\n public output<const Key extends string, const RF extends RenderFunction<Args, Data, unknown>>(\n key: Key,\n rf: RF,\n flags?: ConfigRenderLambdaFlags,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3({\n ...this.config,\n outputs: {\n ...this.config.outputs,\n [key]: createAndRegisterRenderLambda({\n handle: `block-output#${key}`,\n lambda: () => cfgOrRf(new BlockRenderCtx<Args, Data>()),\n ...flags,\n }),\n },\n });\n }\n\n /** Shortcut for {@link output} with retentive flag set to true. */\n public retentiveOutput<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(\n key: Key,\n rf: RF,\n ): BlockModelV3<\n Args,\n OutputsCfg & {\n [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>>;\n },\n Data,\n Href,\n Plugins,\n Transfers\n > {\n return this.output(key, rf, { retentive: true });\n }\n\n /** Shortcut for {@link output} with withStatus flag set to true. */\n public outputWithStatus<\n const Key extends string,\n const RF extends RenderFunction<Args, Data, unknown>,\n >(key: Key, rf: RF) {\n return this.output(key, rf, { withStatus: true });\n }\n\n /**\n * Sets a function to derive block args from data.\n * This is called during setData to compute the args that will be used for block execution.\n *\n * @example\n * .args<BlockArgs>((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .args<BlockArgs>((data) => {\n * if (data.numbers.length === 0) throw new Error('Numbers required'); // block not ready\n * return { numbers: data.numbers };\n * })\n */\n public args<A>(\n lambda: (data: Data) => A,\n ): BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<A, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n argsFunction: lambda as (data: unknown) => unknown,\n });\n }\n\n /**\n * Sets a function to derive pre-run args from data (optional).\n * This is called during setData to compute the args that will be used for staging/pre-run phase.\n *\n * If not defined, defaults to using the args() function result.\n * If defined, uses its return value for the staging / prerun phase.\n *\n * The staging / prerun phase runs only if currentPrerunArgs differs from the executed\n * version of prerunArgs (same comparison logic as currentArgs vs prodArgs).\n *\n * @example\n * .prerunArgs((data) => ({ numbers: data.numbers }))\n *\n * @example\n * .prerunArgs((data) => {\n * // Return undefined to skip staging for this block\n * if (!data.isReady) return undefined;\n * return { numbers: data.numbers };\n * })\n */\n public prerunArgs(\n fn: (data: Data) => unknown,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n prerunArgsFunction: fn as (data: unknown) => unknown,\n });\n }\n\n /** Sets the lambda to generate list of sections in the left block overviews panel. */\n public sections<\n const Ret extends SectionsExpectedType,\n const RF extends RenderFunction<Args, Data, Ret>,\n >(rf: RF): BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins, Transfers>(\n {\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n {\n handle: \"sections\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n },\n true,\n ),\n },\n );\n }\n\n /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */\n public title(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n title: createAndRegisterRenderLambda({\n handle: \"title\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n public subtitle(\n rf: RenderFunction<Args, Data, string>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n subtitle: createAndRegisterRenderLambda({\n handle: \"subtitle\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n public tags(\n rf: RenderFunction<Args, Data, string[]>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n tags: createAndRegisterRenderLambda({\n handle: \"tags\",\n lambda: () => rf(new BlockRenderCtx<Args, Data>()),\n }),\n });\n }\n\n /** Sets or overrides feature flags for the block. */\n public withFeatureFlags(\n flags: Partial<BlockCodeKnownFeatureFlags>,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n featureFlags: { ...this.config.featureFlags, ...flags },\n });\n }\n\n /**\n * Defines how to derive list of upstream references this block is meant to enrich with its exports from block args.\n * Influences dependency graph construction.\n */\n public enriches(\n lambda: (args: Args) => PlRef[],\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins, Transfers>({\n ...this.config,\n enrichmentTargets: createAndRegisterRenderLambda({\n handle: \"enrichmentTargets\",\n lambda: lambda,\n }),\n });\n }\n\n /**\n * Registers a plugin instance with the block.\n * Consumes a transfer if one was defined for this plugin ID in the migration chain.\n *\n * Type checks:\n * - If Transfers[Id] exists, verifies it extends PTransferData (transfer type compatibility)\n * - If no Transfers[Id], rejects plugins with transferAt set (missing .transfer() in data model)\n * - Rejects duplicate plugin IDs (Id already in keyof Plugins)\n *\n * @param instance - PluginInstance created via factory.create({ pluginId, ... })\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin(mainTable, {\n * columns: (ctx) => ctx.outputs?.resolve(\"data\")?.getPColumns(),\n * sourceId: (ctx) => ctx.data.selectedSource,\n * })\n */\n public plugin<\n const PluginId extends string,\n PData extends PluginData,\n PParams extends PluginParams,\n POutputs extends PluginOutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices,\n >(\n instance: PluginInstanceClass<\n PluginId &\n (PluginId extends keyof Transfers\n ? Transfers[PluginId] extends PTransferData\n ? string\n : never\n : [PTransferData] extends [never]\n ? string\n : never) &\n (PluginId extends keyof Plugins ? never : string),\n PData,\n PParams,\n POutputs,\n PTransferData,\n PluginModelServices,\n PluginUiServices\n >,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & {\n [K in PluginId]: PluginRecord<\n PData,\n PParams,\n POutputs,\n PluginModelServices,\n PluginUiServices\n >;\n },\n Omit<Transfers, PluginId>\n >;\n public plugin(\n instance: PluginInstanceClass,\n params?: ParamsInput<Record<string, unknown>, unknown, unknown>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Record<string, PluginRecord>,\n Record<string, unknown>\n > {\n const pluginId = instance.id;\n const plugin = instance[CREATE_PLUGIN_MODEL]();\n const resolvedParams = (params ?? {}) as ParamsInputErased;\n\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const registered: PluginRecord = {\n model: plugin,\n inputs: resolvedParams,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: registered,\n },\n featureFlags: mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),\n });\n }\n\n /** Renders all provided block settings into a pre-configured platforma API\n * instance, that can be used in frontend to interact with block data, and\n * other features provided by the platforma to the block.\n *\n * Type-level check: if there are unconsumed transfers (from `.transfer()` calls\n * in the migration chain), this method requires an impossible `never` argument,\n * producing a compile error. Register all transferred plugins via `.plugin(instance)`\n * before calling `.done()`.\n */\n public done(\n ..._: keyof Transfers extends never ? [] : [never]\n ): PlatformaExtended<\n PlatformaV3<\n Data,\n Args,\n InferOutputsFromLambdas<OutputsCfg>,\n Href,\n Plugins,\n BlockDefaultUiServices\n >\n > {\n if (this.config.argsFunction === undefined) throw new Error(\"Args rendering function not set.\");\n\n const apiVersion = 3;\n\n // Build plugin registry\n const { plugins } = this.config;\n const pluginRegistry: Record<string, PluginName> = {};\n const pluginHandles = Object.keys(plugins) as PluginHandle[];\n for (const handle of pluginHandles) {\n pluginRegistry[handle] = plugins[handle].model.name;\n }\n\n const { dataModel, argsFunction, prerunArgsFunction } = this.config;\n\n function getPlugin(handle: PluginHandle): PluginRecord {\n const plugin = plugins[handle];\n if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);\n return plugin;\n }\n\n // Register ALL facade callbacks here, with dependencies captured via closures\n registerFacadeCallbacks({\n [BlockStorageFacadeCallbacks.StorageApplyUpdate]: applyStorageUpdate,\n [BlockStorageFacadeCallbacks.StorageDebugView]: getStorageDebugView,\n [BlockStorageFacadeCallbacks.StorageMigrate]: (currentStorageJson) =>\n migrateStorage(currentStorageJson, {\n migrateBlockData: (v) => dataModel.migrate(v),\n getPluginRegistry: () => pluginRegistry,\n migratePluginData: (handle, v) => getPlugin(handle).model.dataModel.migrate(v),\n createPluginData: (handle, transfer) => {\n if (transfer) return transfer;\n return getPlugin(handle).model.getDefaultData();\n },\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) =>\n deriveArgsFromStorage(storageJson, argsFunction),\n [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) =>\n derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction),\n });\n\n // Register plugin input and output lambdas\n const pluginOutputs: Record<string, ConfigRenderLambda> = {};\n for (const handle of pluginHandles) {\n const { model, inputs } = plugins[handle];\n // Wrap plugin param lambdas: close over BlockRenderCtx creation\n const wrappedInputs: Record<string, () => unknown> = {};\n for (const [paramKey, paramFn] of Object.entries(inputs)) {\n wrappedInputs[paramKey] = () => paramFn(new BlockRenderCtx());\n }\n\n // Register plugin outputs (in config pack, evaluated by middle layer)\n const outputs = model.outputs as Record<string, (ctx: PluginRenderCtx) => unknown>;\n const { outputFlags } = model;\n for (const [outputKey, outputFn] of Object.entries(outputs)) {\n const key = pluginOutputKey(handle, outputKey);\n pluginOutputs[key] = createAndRegisterRenderLambda({\n handle: key,\n lambda: () => outputFn(new PluginRenderCtx(handle, wrappedInputs)),\n withStatus: outputFlags[outputKey]?.withStatus,\n });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI()) {\n const blockConfig: BlockConfigContainer = {\n v4: {\n configVersion: 4,\n modelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n title: this.config.title,\n subtitle: this.config.subtitle,\n tags: this.config.tags,\n outputs: allOutputs,\n enrichmentTargets: this.config.enrichmentTargets,\n featureFlags: this.config.featureFlags,\n blockLifecycleCallbacks: { ...BlockStorageFacadeHandles },\n },\n\n // fields below are added to allow previous desktop versions read generated configs\n sdkVersion: PlatformaSDKVersion,\n renderingMode: this.config.renderingMode,\n sections: this.config.sections,\n outputs: Object.fromEntries(\n Object.entries(this.config.outputs).map(([key, value]) => [\n key,\n downgradeCfgOrLambda(value),\n ]),\n ),\n };\n // we are in the configuration rendering routine, not in actual UI\n return { config: blockConfig } as any;\n // normal operation inside the UI\n } else {\n return {\n ...getPlatformaInstance({\n sdkVersion: PlatformaSDKVersion,\n apiVersion,\n }),\n blockModelInfo: {\n outputs: Object.fromEntries(\n Object.entries(allOutputs).map(([key, value]) => [\n key,\n {\n withStatus: Boolean(isConfigLambda(value) && value.withStatus),\n },\n ]),\n ),\n pluginIds: pluginHandles,\n featureFlags: this.config.featureFlags,\n },\n } as any;\n }\n }\n}\n\n// Type tests for BlockModelV3\n\nexport type Expect<T extends true> = T;\n\nexport type Equal<X, Y> =\n (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;\n\nexport type Merge<A, B> = {\n [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;\n};\n\n// Helper types for testing\ntype _TestArgs = { inputFile: string; threshold: number };\ntype _TestData = { selectedTab: string };\ntype _TestOutputs = {\n result: ConfigRenderLambda<string>;\n count: ConfigRenderLambda<number>;\n};\n\n// Test: Merge type works correctly\ntype _MergeTest1 = Expect<Equal<Merge<{ a: 1 }, { b: 2 }>, { a: 1; b: 2 }>>;\ntype _MergeTest2 = Expect<Equal<Merge<{ a: 1 }, { a: 2 }>, { a: 2 }>>;\ntype _MergeTest3 = Expect<Equal<Merge<{ a: 1; b: 1 }, { b: 2; c: 3 }>, { a: 1; b: 2; c: 3 }>>;\n\n// Test: create() returns a BlockModelV3 instance\n// Note: Due to function overloads, ReturnType uses the last overload signature.\n// We verify the structure is correct using a simpler assignability test.\ntype _CreateResult = ReturnType<typeof BlockModelV3.create>;\ntype _CreateIsBlockModelV3 =\n _CreateResult extends BlockModelV3<infer _A, infer _O, infer _S> ? true : false;\ntype _CreateTest = Expect<_CreateIsBlockModelV3>;\n\n// Test: BlockModelV3Config interface structure (default generics)\ntype _ConfigTest = Expect<\n Equal<\n BlockModelV3Config<_TestOutputs, _TestData>,\n {\n renderingMode: BlockRenderingMode;\n argsFunction: ((data: unknown) => unknown) | undefined;\n prerunArgsFunction: ((data: unknown) => unknown) | undefined;\n dataModel: DataModel<_TestData, {}>;\n outputs: _TestOutputs;\n sections: ConfigRenderLambda;\n title: ConfigRenderLambda | undefined;\n subtitle: ConfigRenderLambda | undefined;\n tags: ConfigRenderLambda | undefined;\n enrichmentTargets: ConfigRenderLambda | undefined;\n featureFlags: BlockCodeKnownFeatureFlags;\n plugins: {};\n }\n >\n>;\n\n// Test: Default Href is '/'\ntype _HrefDefaultTest =\n BlockModelV3<_TestArgs, {}, _TestData> extends BlockModelV3<_TestArgs, {}, _TestData, \"/\">\n ? true\n : false;\ntype _VerifyHrefDefault = Expect<_HrefDefaultTest>;\n\n// Test: Custom Href can be specified\ntype _CustomHref = \"/settings\" | \"/main\";\ntype _HrefCustomBuilder = BlockModelV3<_TestArgs, {}, _TestData, _CustomHref>;\ntype _HrefCustomTest =\n _HrefCustomBuilder extends BlockModelV3<_TestArgs, {}, _TestData, _CustomHref> ? true : false;\ntype _VerifyHrefCustom = Expect<_HrefCustomTest>;\n\n// Test: Output type accumulation with & intersection\ntype _OutputsAccumulation = { a: ConfigRenderLambda<string> } & {\n b: ConfigRenderLambda<number>;\n};\ntype _VerifyOutputsHaveKeys = Expect<Equal<keyof _OutputsAccumulation, \"a\" | \"b\">>;\n\n// Test: Builder with all type parameters specified compiles\ntype _FullBuilder = BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\">;\ntype _FullBuilderTest =\n _FullBuilder extends BlockModelV3<_TestArgs, _TestOutputs, _TestData, \"/main\"> ? true : false;\ntype _VerifyFullBuilder = Expect<_FullBuilderTest>;\n\n// Test: InferOutputsFromLambdas maps outputs correctly\ntype _InferOutputsTest = InferOutputsFromLambdas<{\n myOutput: ConfigRenderLambda<number>;\n}>;\ntype _VerifyInferOutputs = Expect<\n Equal<_InferOutputsTest, { myOutput: OutputWithStatus<number> & { __unwrap: true } }>\n>;\n"],"mappings":"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"}
|