@platforma-sdk/model 1.58.2 → 1.58.5

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.
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var plModelCommon = require('@milaboratories/pl-model-common');
4
3
  var internal = require('./internal.cjs');
5
4
  var api = require('./render/api.cjs');
5
+ require('@milaboratories/pl-model-common');
6
6
  require('./render/util/label.cjs');
7
7
  require('canonicalize');
8
8
  var plugin_handle = require('./plugin_handle.cjs');
@@ -12,6 +12,26 @@ var normalization = require('./bconfig/normalization.cjs');
12
12
  var types = require('./bconfig/types.cjs');
13
13
  var block_storage_facade = require('./block_storage_facade.cjs');
14
14
 
15
+ /**
16
+ * Merges two feature flag objects with type-aware logic:
17
+ * - `supports*` (boolean): OR — `true` if either side is `true`
18
+ * - `requires*` (numeric): MAX — take the higher version requirement
19
+ */
20
+ function mergeFeatureFlags(base, override) {
21
+ const result = { ...base };
22
+ for (const [key, value] of Object.entries(override)) {
23
+ if (value === undefined)
24
+ continue;
25
+ const existing = result[key];
26
+ if (typeof value === "boolean") {
27
+ result[key] = (typeof existing === "boolean" && existing) || value;
28
+ }
29
+ else if (typeof value === "number") {
30
+ result[key] = Math.max(typeof existing === "number" ? existing : 0, value);
31
+ }
32
+ }
33
+ return result;
34
+ }
15
35
  /** Main entry point that each block should use in it's "config" module. Don't forget
16
36
  * to call {@link done()} at the end of configuration. Value returned by this builder must be
17
37
  * exported as constant with name "platforma" from the "config" module.
@@ -211,7 +231,7 @@ class BlockModelV3 {
211
231
  ...this.config.plugins,
212
232
  [pluginId]: instance,
213
233
  },
214
- featureFlags: plModelCommon.mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),
234
+ featureFlags: mergeFeatureFlags(this.config.featureFlags, plugin.featureFlags ?? {}),
215
235
  });
216
236
  }
217
237
  /** Renders all provided block settings into a pre-configured platforma API
@@ -1 +1 @@
1
- {"version":3,"file":"block_model.cjs","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 { mergeFeatureFlags } from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } 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 * Registered plugin: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginInstance<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> = {\n readonly model: PluginModel<Data, Params, Outputs>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginInstance> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data>;\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, PluginInstance> = {},\n> {\n private constructor(private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins>) {}\n\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS: BlockCodeKnownFeatureFlags = {\n supportsLazyState: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n };\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<Data extends Record<string, unknown>>(\n dataModel: DataModel<Data>,\n ): BlockModelV3<NoOb, {}, Data> {\n return new BlockModelV3<NoOb, {}, Data>({\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.INITIAL_BLOCK_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 >;\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 >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\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 > {\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<Args>(\n lambda: (data: Data) => Args,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins>({\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n { handle: \"sections\", lambda: () => rf(new BlockRenderCtx<Args, Data>()) },\n true,\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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 *\n * Plugins are UI components with their own model logic and persistent state.\n * Each plugin must have a unique pluginId within the block.\n *\n * @param pluginId - Unique identifier for this plugin instance within the block\n * @param plugin - Configured PluginModel instance (created via factory.create(config))\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin('mainTable', dataTablePlugin.create({ defaultOps: {...} }), {\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 >(\n pluginId: PluginId,\n plugin: PluginModel<PData, PParams, POutputs>,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & { [K in PluginId]: PluginInstance<PData, PParams, POutputs> }\n > {\n // Validate pluginId uniqueness\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const instance: PluginInstance<PData, PParams, POutputs> = {\n model: plugin,\n inputs: (params ?? {}) as ParamsInputErased,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: instance,\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 public done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\n > {\n return this.withFeatureFlags({\n ...this.config.featureFlags,\n })._done();\n }\n\n public _done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\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): PluginInstance {\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) => getPlugin(handle).model.dataModel.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.dataModel.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 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 });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\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\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI())\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 },\n } as any;\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\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"],"names":["BLOCK_STORAGE_FACADE_VERSION","createAndRegisterRenderLambda","BlockRenderCtx","mergeFeatureFlags","registerFacadeCallbacks","BlockStorageFacadeCallbacks","applyStorageUpdate","getStorageDebugView","migrateStorage","createInitialStorage","deriveArgsFromStorage","derivePrerunArgsFromStorage","pluginOutputKey","PluginRenderCtx","PlatformaSDKVersion","BlockStorageFacadeHandles","downgradeCfgOrLambda","isInUI","getPlatformaInstance","isConfigLambda"],"mappings":"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"}
1
+ {"version":3,"file":"block_model.cjs","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 { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } 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 * Registered plugin: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginInstance<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> = {\n readonly model: PluginModel<Data, Params, Outputs>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginInstance> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data>;\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, PluginInstance> = {},\n> {\n private constructor(private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins>) {}\n\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS: BlockCodeKnownFeatureFlags = {\n supportsLazyState: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n };\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<Data extends Record<string, unknown>>(\n dataModel: DataModel<Data>,\n ): BlockModelV3<NoOb, {}, Data> {\n return new BlockModelV3<NoOb, {}, Data>({\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.INITIAL_BLOCK_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 >;\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 >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\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 > {\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<Args>(\n lambda: (data: Data) => Args,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins>({\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n { handle: \"sections\", lambda: () => rf(new BlockRenderCtx<Args, Data>()) },\n true,\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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 *\n * Plugins are UI components with their own model logic and persistent state.\n * Each plugin must have a unique pluginId within the block.\n *\n * @param pluginId - Unique identifier for this plugin instance within the block\n * @param plugin - Configured PluginModel instance (created via factory.create(config))\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin('mainTable', dataTablePlugin.create({ defaultOps: {...} }), {\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 >(\n pluginId: PluginId,\n plugin: PluginModel<PData, PParams, POutputs>,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & { [K in PluginId]: PluginInstance<PData, PParams, POutputs> }\n > {\n // Validate pluginId uniqueness\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const instance: PluginInstance<PData, PParams, POutputs> = {\n model: plugin,\n inputs: (params ?? {}) as ParamsInputErased,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: instance,\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 public done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\n > {\n return this.withFeatureFlags({\n ...this.config.featureFlags,\n })._done();\n }\n\n public _done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\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): PluginInstance {\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) => getPlugin(handle).model.dataModel.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.dataModel.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 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 });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\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\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI())\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 },\n } as any;\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\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"],"names":["BLOCK_STORAGE_FACADE_VERSION","createAndRegisterRenderLambda","BlockRenderCtx","registerFacadeCallbacks","BlockStorageFacadeCallbacks","applyStorageUpdate","getStorageDebugView","migrateStorage","createInitialStorage","deriveArgsFromStorage","derivePrerunArgsFromStorage","pluginOutputKey","PluginRenderCtx","PlatformaSDKVersion","BlockStorageFacadeHandles","downgradeCfgOrLambda","isInUI","getPlatformaInstance","isConfigLambda"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"block_model.d.ts","sourceRoot":"","sources":["../src/block_model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_model.d.ts","sourceRoot":"","sources":["../src/block_model.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { mergeFeatureFlags } from '@milaboratories/pl-model-common';
2
1
  import { createAndRegisterRenderLambda, isInUI, getPlatformaInstance } from './internal.js';
3
2
  import { BlockRenderCtx, PluginRenderCtx } from './render/api.js';
3
+ import '@milaboratories/pl-model-common';
4
4
  import './render/util/label.js';
5
5
  import 'canonicalize';
6
6
  import { pluginOutputKey } from './plugin_handle.js';
@@ -10,6 +10,26 @@ import { downgradeCfgOrLambda } from './bconfig/normalization.js';
10
10
  import { isConfigLambda } from './bconfig/types.js';
11
11
  import { BLOCK_STORAGE_FACADE_VERSION, registerFacadeCallbacks, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles } from './block_storage_facade.js';
12
12
 
13
+ /**
14
+ * Merges two feature flag objects with type-aware logic:
15
+ * - `supports*` (boolean): OR — `true` if either side is `true`
16
+ * - `requires*` (numeric): MAX — take the higher version requirement
17
+ */
18
+ function mergeFeatureFlags(base, override) {
19
+ const result = { ...base };
20
+ for (const [key, value] of Object.entries(override)) {
21
+ if (value === undefined)
22
+ continue;
23
+ const existing = result[key];
24
+ if (typeof value === "boolean") {
25
+ result[key] = (typeof existing === "boolean" && existing) || value;
26
+ }
27
+ else if (typeof value === "number") {
28
+ result[key] = Math.max(typeof existing === "number" ? existing : 0, value);
29
+ }
30
+ }
31
+ return result;
32
+ }
13
33
  /** Main entry point that each block should use in it's "config" module. Don't forget
14
34
  * to call {@link done()} at the end of configuration. Value returned by this builder must be
15
35
  * exported as constant with name "platforma" from the "config" module.
@@ -1 +1 @@
1
- {"version":3,"file":"block_model.js","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 { mergeFeatureFlags } from \"@milaboratories/pl-model-common\";\nimport { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from \"./internal\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PlatformaV3 } from \"./platforma\";\nimport type { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } 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 * Registered plugin: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginInstance<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> = {\n readonly model: PluginModel<Data, Params, Outputs>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginInstance> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data>;\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, PluginInstance> = {},\n> {\n private constructor(private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins>) {}\n\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS: BlockCodeKnownFeatureFlags = {\n supportsLazyState: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n };\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<Data extends Record<string, unknown>>(\n dataModel: DataModel<Data>,\n ): BlockModelV3<NoOb, {}, Data> {\n return new BlockModelV3<NoOb, {}, Data>({\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.INITIAL_BLOCK_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 >;\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 >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\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 > {\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<Args>(\n lambda: (data: Data) => Args,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins>({\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n { handle: \"sections\", lambda: () => rf(new BlockRenderCtx<Args, Data>()) },\n true,\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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 *\n * Plugins are UI components with their own model logic and persistent state.\n * Each plugin must have a unique pluginId within the block.\n *\n * @param pluginId - Unique identifier for this plugin instance within the block\n * @param plugin - Configured PluginModel instance (created via factory.create(config))\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin('mainTable', dataTablePlugin.create({ defaultOps: {...} }), {\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 >(\n pluginId: PluginId,\n plugin: PluginModel<PData, PParams, POutputs>,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & { [K in PluginId]: PluginInstance<PData, PParams, POutputs> }\n > {\n // Validate pluginId uniqueness\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const instance: PluginInstance<PData, PParams, POutputs> = {\n model: plugin,\n inputs: (params ?? {}) as ParamsInputErased,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: instance,\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 public done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\n > {\n return this.withFeatureFlags({\n ...this.config.featureFlags,\n })._done();\n }\n\n public _done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\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): PluginInstance {\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) => getPlugin(handle).model.dataModel.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.dataModel.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 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 });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\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\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI())\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 },\n } as any;\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\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"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_model.js","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 { InferRenderFunctionReturn, RenderFunction } from \"./render\";\nimport { BlockRenderCtx, PluginRenderCtx } from \"./render\";\nimport type { PluginData, PluginModel, PluginOutputs, PluginParams } 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 * Registered plugin: model + param derivation lambdas.\n * Type parameters are carried by PluginModel generic.\n */\nexport type PluginInstance<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> = {\n readonly model: PluginModel<Data, Params, Outputs>;\n readonly inputs: ParamsInputErased;\n};\n\ninterface BlockModelV3Config<\n OutputsCfg extends Record<string, ConfigRenderLambda>,\n Data,\n Plugins extends Record<string, PluginInstance> = {},\n> {\n renderingMode: BlockRenderingMode;\n dataModel: DataModel<Data>;\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, PluginInstance> = {},\n> {\n private constructor(private readonly config: BlockModelV3Config<OutputsCfg, Data, Plugins>) {}\n\n public static readonly INITIAL_BLOCK_FEATURE_FLAGS: BlockCodeKnownFeatureFlags = {\n supportsLazyState: true,\n requiresUIAPIVersion: 3,\n requiresModelAPIVersion: BLOCK_STORAGE_FACADE_VERSION,\n requiresCreatePTable: 2,\n };\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<Data extends Record<string, unknown>>(\n dataModel: DataModel<Data>,\n ): BlockModelV3<NoOb, {}, Data> {\n return new BlockModelV3<NoOb, {}, Data>({\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.INITIAL_BLOCK_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 >;\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 >;\n public output(\n key: string,\n cfgOrRf: RenderFunction<Args, Data, unknown>,\n flags: ConfigRenderLambdaFlags = {},\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\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 > {\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<Args>(\n lambda: (data: Data) => Args,\n ): BlockModelV3<Args, OutputsCfg, Data, Href, Plugins> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, DeriveHref<ReturnType<RF>>, Plugins>({\n ...this.config,\n // Replace the default sections callback with the user-provided one\n sections: createAndRegisterRenderLambda(\n { handle: \"sections\", lambda: () => rf(new BlockRenderCtx<Args, Data>()) },\n true,\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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> {\n return new BlockModelV3<Args, OutputsCfg, Data, Href, Plugins>({\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 *\n * Plugins are UI components with their own model logic and persistent state.\n * Each plugin must have a unique pluginId within the block.\n *\n * @param pluginId - Unique identifier for this plugin instance within the block\n * @param plugin - Configured PluginModel instance (created via factory.create(config))\n * @param params - Per-property lambdas deriving plugin params from block RenderCtx\n *\n * @example\n * .plugin('mainTable', dataTablePlugin.create({ defaultOps: {...} }), {\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 >(\n pluginId: PluginId,\n plugin: PluginModel<PData, PParams, POutputs>,\n params?: ParamsInput<PParams, Args, Data>,\n ): BlockModelV3<\n Args,\n OutputsCfg,\n Data,\n Href,\n Plugins & { [K in PluginId]: PluginInstance<PData, PParams, POutputs> }\n > {\n // Validate pluginId uniqueness\n if (pluginId in this.config.plugins) {\n throw new Error(`Plugin '${pluginId}' already registered`);\n }\n\n const instance: PluginInstance<PData, PParams, POutputs> = {\n model: plugin,\n inputs: (params ?? {}) as ParamsInputErased,\n };\n\n return new BlockModelV3({\n ...this.config,\n plugins: {\n ...this.config.plugins,\n [pluginId]: instance,\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 public done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\n > {\n return this.withFeatureFlags({\n ...this.config.featureFlags,\n })._done();\n }\n\n public _done(): PlatformaExtended<\n PlatformaV3<Data, Args, InferOutputsFromLambdas<OutputsCfg>, Href, Plugins>\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): PluginInstance {\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) => getPlugin(handle).model.dataModel.getDefaultData(),\n }),\n [BlockStorageFacadeCallbacks.StorageInitial]: () =>\n createInitialStorage({\n getDefaultBlockData: () => dataModel.getDefaultData(),\n getPluginRegistry: () => pluginRegistry,\n createPluginData: (handle) => getPlugin(handle).model.dataModel.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 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 });\n }\n }\n const allOutputs = { ...this.config.outputs, ...pluginOutputs };\n\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\n globalThis.platformaApiVersion = apiVersion;\n\n if (!isInUI())\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 },\n } as any;\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\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"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var traverse = require('./traverse.cjs');
4
+ var compat = require('es-toolkit/compat');
4
5
 
5
6
  /** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */
6
7
  const KNOWN_LEAF_KEYS_TUPLE = [
@@ -21,7 +22,17 @@ const KNOWN_LEAF_KEYS = new Set(KNOWN_LEAF_KEYS_TUPLE);
21
22
  function isFilledLeaf(node) {
22
23
  if (node.type == null)
23
24
  return false;
24
- return !Object.values(node).some((v) => v === undefined);
25
+ return !Object.values(node).some((value) => {
26
+ switch (typeof value) {
27
+ case "number":
28
+ case "boolean":
29
+ return false;
30
+ case "string":
31
+ return value.trim() === "";
32
+ default: // undefined, null, empty objects/arrays
33
+ return compat.isEmpty(value);
34
+ }
35
+ });
25
36
  }
26
37
  function distillLeaf(node) {
27
38
  const result = {};
@@ -41,9 +52,8 @@ function distillFilterSpec(filter) {
41
52
  return null;
42
53
  return traverse.traverseFilterSpec(filter, {
43
54
  leaf: (leaf) => {
44
- if (!isFilledLeaf(leaf))
45
- return null;
46
- return distillLeaf(leaf);
55
+ const distilled = distillLeaf(leaf);
56
+ return isFilledLeaf(distilled) ? distilled : null;
47
57
  },
48
58
  and: (results) => {
49
59
  const filtered = results.filter((f) => f !== null);
@@ -1 +1 @@
1
- {"version":3,"file":"distill.cjs","sources":["../../src/filters/distill.ts"],"sourcesContent":["import { DistributiveKeys, UnionToTuples } from \"@milaboratories/helpers\";\nimport {\n RootFilterSpec,\n type FilterSpec,\n type FilterSpecLeaf,\n} from \"@milaboratories/pl-model-common\";\nimport { traverseFilterSpec } from \"./traverse\";\nimport { InferFilterSpecLeaf } from \"@milaboratories/pl-model-common\";\n\n/** All possible field names that can appear in any FilterSpecLeaf variant. */\ntype FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;\n\n/** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */\nconst KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [\n \"n\",\n \"x\",\n \"rhs\",\n \"type\",\n \"value\",\n \"column\",\n \"minDiff\",\n \"maxEdits\",\n \"wildcard\",\n \"replacement\",\n \"substitutionsOnly\",\n];\nconst KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);\n\n/** Returns true if the leaf is filled — type is defined and no required fields are undefined. */\nfunction isFilledLeaf(node: Record<string, unknown>): boolean {\n if (node.type == null) return false;\n return !Object.values(node).some((v) => v === undefined);\n}\n\nfunction distillLeaf(node: Record<string, unknown>): FilterSpecLeaf<string> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {\n result[key] = value;\n }\n }\n return result as FilterSpecLeaf<string>;\n}\n\n/**\n * Strips non-FilterSpec metadata (whitelist approach) and removes\n * unfilled leaves (type is undefined or any required field is undefined).\n */\nexport function distillFilterSpec<\n FS extends FilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>,\n R extends FS extends RootFilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>\n ? RootFilterSpec<InferFilterSpecLeaf<FS>>\n : FilterSpec<InferFilterSpecLeaf<FS>>,\n>(filter: null | undefined | FS): null | R {\n if (filter == null) return null;\n return traverseFilterSpec<FS, null | R>(filter, {\n leaf: (leaf) => {\n if (!isFilledLeaf(leaf as Record<string, unknown>)) return null;\n return distillLeaf(leaf as Record<string, unknown>) as R;\n },\n and: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"and\", filters: filtered } as R);\n },\n or: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"or\", filters: filtered } as R);\n },\n not: (result) => (result === null ? null : ({ type: \"not\", filter: result } as R)),\n });\n}\n"],"names":["traverseFilterSpec"],"mappings":";;;;AAYA;AACA,MAAM,qBAAqB,GAAqC;IAC9D,GAAG;IACH,GAAG;IACH,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa;IACb,mBAAmB;CACpB;AACD,MAAM,eAAe,GAA2B,IAAI,GAAG,CAAC,qBAAqB,CAAC;AAE9E;AACA,SAAS,YAAY,CAAC,IAA6B,EAAA;AACjD,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;AAC1D;AAEA,SAAS,WAAW,CAAC,IAA6B,EAAA;IAChD,MAAM,MAAM,GAA4B,EAAE;AAC1C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,QAAA,IAAI,eAAe,CAAC,GAAG,CAAC,GAAwB,CAAC,EAAE;AACjD,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;QACrB;IACF;AACA,IAAA,OAAO,MAAgC;AACzC;AAEA;;;AAGG;AACG,SAAU,iBAAiB,CAK/B,MAA6B,EAAA;IAC7B,IAAI,MAAM,IAAI,IAAI;AAAE,QAAA,OAAO,IAAI;IAC/B,OAAOA,2BAAkB,CAAe,MAAM,EAAE;AAC9C,QAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,YAAA,IAAI,CAAC,YAAY,CAAC,IAA+B,CAAC;AAAE,gBAAA,OAAO,IAAI;AAC/D,YAAA,OAAO,WAAW,CAAC,IAA+B,CAAM;QAC1D,CAAC;AACD,QAAA,GAAG,EAAE,CAAC,OAAO,KAAI;AACf,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAQ;QACjF,CAAC;AACD,QAAA,EAAE,EAAE,CAAC,OAAO,KAAI;AACd,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAQ;QAChF,CAAC;QACD,GAAG,EAAE,CAAC,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAQ,CAAC;AACnF,KAAA,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"distill.cjs","sources":["../../src/filters/distill.ts"],"sourcesContent":["import { DistributiveKeys, UnionToTuples } from \"@milaboratories/helpers\";\nimport {\n RootFilterSpec,\n type FilterSpec,\n type FilterSpecLeaf,\n} from \"@milaboratories/pl-model-common\";\nimport { traverseFilterSpec } from \"./traverse\";\nimport { InferFilterSpecLeaf } from \"@milaboratories/pl-model-common\";\nimport { isEmpty } from \"es-toolkit/compat\";\n\n/** All possible field names that can appear in any FilterSpecLeaf variant. */\ntype FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;\n\n/** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */\nconst KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [\n \"n\",\n \"x\",\n \"rhs\",\n \"type\",\n \"value\",\n \"column\",\n \"minDiff\",\n \"maxEdits\",\n \"wildcard\",\n \"replacement\",\n \"substitutionsOnly\",\n];\nconst KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);\n\n/** Returns true if the leaf is filled — type is defined and no required fields are undefined. */\nfunction isFilledLeaf<T>(node: FilterSpecLeaf<T>): boolean {\n if (node.type == null) return false;\n return !Object.values(node).some((value) => {\n switch (typeof value) {\n case \"number\":\n case \"boolean\":\n return false;\n case \"string\":\n return value.trim() === \"\";\n default: // undefined, null, empty objects/arrays\n return isEmpty(value);\n }\n });\n}\n\nfunction distillLeaf<T>(node: FilterSpecLeaf<T>): FilterSpecLeaf<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {\n result[key] = value;\n }\n }\n return result as FilterSpecLeaf<T>;\n}\n\n/**\n * Strips non-FilterSpec metadata (whitelist approach) and removes\n * unfilled leaves (type is undefined or any required field is undefined).\n */\nexport function distillFilterSpec<\n FS extends FilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>,\n R extends FS extends RootFilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>\n ? RootFilterSpec<InferFilterSpecLeaf<FS>>\n : FilterSpec<InferFilterSpecLeaf<FS>>,\n>(filter: null | undefined | FS): null | R {\n if (filter == null) return null;\n return traverseFilterSpec<FS, null | R>(filter, {\n leaf: (leaf) => {\n const distilled = distillLeaf(leaf);\n return isFilledLeaf(distilled) ? (distilled as R) : null;\n },\n and: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"and\", filters: filtered } as R);\n },\n or: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"or\", filters: filtered } as R);\n },\n not: (result) => (result === null ? null : ({ type: \"not\", filter: result } as R)),\n });\n}\n"],"names":["isEmpty","traverseFilterSpec"],"mappings":";;;;;AAaA;AACA,MAAM,qBAAqB,GAAqC;IAC9D,GAAG;IACH,GAAG;IACH,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa;IACb,mBAAmB;CACpB;AACD,MAAM,eAAe,GAA2B,IAAI,GAAG,CAAC,qBAAqB,CAAC;AAE9E;AACA,SAAS,YAAY,CAAI,IAAuB,EAAA;AAC9C,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAI;QACzC,QAAQ,OAAO,KAAK;AAClB,YAAA,KAAK,QAAQ;AACb,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,KAAK;AACd,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;AAC5B,YAAA;AACE,gBAAA,OAAOA,cAAO,CAAC,KAAK,CAAC;;AAE3B,IAAA,CAAC,CAAC;AACJ;AAEA,SAAS,WAAW,CAAI,IAAuB,EAAA;IAC7C,MAAM,MAAM,GAA4B,EAAE;AAC1C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,QAAA,IAAI,eAAe,CAAC,GAAG,CAAC,GAAwB,CAAC,EAAE;AACjD,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;QACrB;IACF;AACA,IAAA,OAAO,MAA2B;AACpC;AAEA;;;AAGG;AACG,SAAU,iBAAiB,CAK/B,MAA6B,EAAA;IAC7B,IAAI,MAAM,IAAI,IAAI;AAAE,QAAA,OAAO,IAAI;IAC/B,OAAOC,2BAAkB,CAAe,MAAM,EAAE;AAC9C,QAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,YAAA,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC;AACnC,YAAA,OAAO,YAAY,CAAC,SAAS,CAAC,GAAI,SAAe,GAAG,IAAI;QAC1D,CAAC;AACD,QAAA,GAAG,EAAE,CAAC,OAAO,KAAI;AACf,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAQ;QACjF,CAAC;AACD,QAAA,EAAE,EAAE,CAAC,OAAO,KAAI;AACd,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAQ;QAChF,CAAC;QACD,GAAG,EAAE,CAAC,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAQ,CAAC;AACnF,KAAA,CAAC;AACJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"distill.d.ts","sourceRoot":"","sources":["../../src/filters/distill.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAqCtE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,SAAS,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAChE,CAAC,SAAS,EAAE,SAAS,cAAc,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAC1E,cAAc,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,GACvC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,EACvC,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,CAiBzC"}
1
+ {"version":3,"file":"distill.d.ts","sourceRoot":"","sources":["../../src/filters/distill.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAgDtE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,SAAS,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAChE,CAAC,SAAS,EAAE,SAAS,cAAc,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAC1E,cAAc,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,GACvC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,EACvC,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,CAiBzC"}
@@ -1,4 +1,5 @@
1
1
  import { traverseFilterSpec } from './traverse.js';
2
+ import { isEmpty } from 'es-toolkit/compat';
2
3
 
3
4
  /** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */
4
5
  const KNOWN_LEAF_KEYS_TUPLE = [
@@ -19,7 +20,17 @@ const KNOWN_LEAF_KEYS = new Set(KNOWN_LEAF_KEYS_TUPLE);
19
20
  function isFilledLeaf(node) {
20
21
  if (node.type == null)
21
22
  return false;
22
- return !Object.values(node).some((v) => v === undefined);
23
+ return !Object.values(node).some((value) => {
24
+ switch (typeof value) {
25
+ case "number":
26
+ case "boolean":
27
+ return false;
28
+ case "string":
29
+ return value.trim() === "";
30
+ default: // undefined, null, empty objects/arrays
31
+ return isEmpty(value);
32
+ }
33
+ });
23
34
  }
24
35
  function distillLeaf(node) {
25
36
  const result = {};
@@ -39,9 +50,8 @@ function distillFilterSpec(filter) {
39
50
  return null;
40
51
  return traverseFilterSpec(filter, {
41
52
  leaf: (leaf) => {
42
- if (!isFilledLeaf(leaf))
43
- return null;
44
- return distillLeaf(leaf);
53
+ const distilled = distillLeaf(leaf);
54
+ return isFilledLeaf(distilled) ? distilled : null;
45
55
  },
46
56
  and: (results) => {
47
57
  const filtered = results.filter((f) => f !== null);
@@ -1 +1 @@
1
- {"version":3,"file":"distill.js","sources":["../../src/filters/distill.ts"],"sourcesContent":["import { DistributiveKeys, UnionToTuples } from \"@milaboratories/helpers\";\nimport {\n RootFilterSpec,\n type FilterSpec,\n type FilterSpecLeaf,\n} from \"@milaboratories/pl-model-common\";\nimport { traverseFilterSpec } from \"./traverse\";\nimport { InferFilterSpecLeaf } from \"@milaboratories/pl-model-common\";\n\n/** All possible field names that can appear in any FilterSpecLeaf variant. */\ntype FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;\n\n/** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */\nconst KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [\n \"n\",\n \"x\",\n \"rhs\",\n \"type\",\n \"value\",\n \"column\",\n \"minDiff\",\n \"maxEdits\",\n \"wildcard\",\n \"replacement\",\n \"substitutionsOnly\",\n];\nconst KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);\n\n/** Returns true if the leaf is filled — type is defined and no required fields are undefined. */\nfunction isFilledLeaf(node: Record<string, unknown>): boolean {\n if (node.type == null) return false;\n return !Object.values(node).some((v) => v === undefined);\n}\n\nfunction distillLeaf(node: Record<string, unknown>): FilterSpecLeaf<string> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {\n result[key] = value;\n }\n }\n return result as FilterSpecLeaf<string>;\n}\n\n/**\n * Strips non-FilterSpec metadata (whitelist approach) and removes\n * unfilled leaves (type is undefined or any required field is undefined).\n */\nexport function distillFilterSpec<\n FS extends FilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>,\n R extends FS extends RootFilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>\n ? RootFilterSpec<InferFilterSpecLeaf<FS>>\n : FilterSpec<InferFilterSpecLeaf<FS>>,\n>(filter: null | undefined | FS): null | R {\n if (filter == null) return null;\n return traverseFilterSpec<FS, null | R>(filter, {\n leaf: (leaf) => {\n if (!isFilledLeaf(leaf as Record<string, unknown>)) return null;\n return distillLeaf(leaf as Record<string, unknown>) as R;\n },\n and: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"and\", filters: filtered } as R);\n },\n or: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"or\", filters: filtered } as R);\n },\n not: (result) => (result === null ? null : ({ type: \"not\", filter: result } as R)),\n });\n}\n"],"names":[],"mappings":";;AAYA;AACA,MAAM,qBAAqB,GAAqC;IAC9D,GAAG;IACH,GAAG;IACH,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa;IACb,mBAAmB;CACpB;AACD,MAAM,eAAe,GAA2B,IAAI,GAAG,CAAC,qBAAqB,CAAC;AAE9E;AACA,SAAS,YAAY,CAAC,IAA6B,EAAA;AACjD,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;AAC1D;AAEA,SAAS,WAAW,CAAC,IAA6B,EAAA;IAChD,MAAM,MAAM,GAA4B,EAAE;AAC1C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,QAAA,IAAI,eAAe,CAAC,GAAG,CAAC,GAAwB,CAAC,EAAE;AACjD,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;QACrB;IACF;AACA,IAAA,OAAO,MAAgC;AACzC;AAEA;;;AAGG;AACG,SAAU,iBAAiB,CAK/B,MAA6B,EAAA;IAC7B,IAAI,MAAM,IAAI,IAAI;AAAE,QAAA,OAAO,IAAI;IAC/B,OAAO,kBAAkB,CAAe,MAAM,EAAE;AAC9C,QAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,YAAA,IAAI,CAAC,YAAY,CAAC,IAA+B,CAAC;AAAE,gBAAA,OAAO,IAAI;AAC/D,YAAA,OAAO,WAAW,CAAC,IAA+B,CAAM;QAC1D,CAAC;AACD,QAAA,GAAG,EAAE,CAAC,OAAO,KAAI;AACf,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAQ;QACjF,CAAC;AACD,QAAA,EAAE,EAAE,CAAC,OAAO,KAAI;AACd,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAQ;QAChF,CAAC;QACD,GAAG,EAAE,CAAC,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAQ,CAAC;AACnF,KAAA,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"distill.js","sources":["../../src/filters/distill.ts"],"sourcesContent":["import { DistributiveKeys, UnionToTuples } from \"@milaboratories/helpers\";\nimport {\n RootFilterSpec,\n type FilterSpec,\n type FilterSpecLeaf,\n} from \"@milaboratories/pl-model-common\";\nimport { traverseFilterSpec } from \"./traverse\";\nimport { InferFilterSpecLeaf } from \"@milaboratories/pl-model-common\";\nimport { isEmpty } from \"es-toolkit/compat\";\n\n/** All possible field names that can appear in any FilterSpecLeaf variant. */\ntype FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;\n\n/** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */\nconst KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [\n \"n\",\n \"x\",\n \"rhs\",\n \"type\",\n \"value\",\n \"column\",\n \"minDiff\",\n \"maxEdits\",\n \"wildcard\",\n \"replacement\",\n \"substitutionsOnly\",\n];\nconst KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);\n\n/** Returns true if the leaf is filled — type is defined and no required fields are undefined. */\nfunction isFilledLeaf<T>(node: FilterSpecLeaf<T>): boolean {\n if (node.type == null) return false;\n return !Object.values(node).some((value) => {\n switch (typeof value) {\n case \"number\":\n case \"boolean\":\n return false;\n case \"string\":\n return value.trim() === \"\";\n default: // undefined, null, empty objects/arrays\n return isEmpty(value);\n }\n });\n}\n\nfunction distillLeaf<T>(node: FilterSpecLeaf<T>): FilterSpecLeaf<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {\n result[key] = value;\n }\n }\n return result as FilterSpecLeaf<T>;\n}\n\n/**\n * Strips non-FilterSpec metadata (whitelist approach) and removes\n * unfilled leaves (type is undefined or any required field is undefined).\n */\nexport function distillFilterSpec<\n FS extends FilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>,\n R extends FS extends RootFilterSpec<FilterSpecLeaf<unknown>, unknown, unknown>\n ? RootFilterSpec<InferFilterSpecLeaf<FS>>\n : FilterSpec<InferFilterSpecLeaf<FS>>,\n>(filter: null | undefined | FS): null | R {\n if (filter == null) return null;\n return traverseFilterSpec<FS, null | R>(filter, {\n leaf: (leaf) => {\n const distilled = distillLeaf(leaf);\n return isFilledLeaf(distilled) ? (distilled as R) : null;\n },\n and: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"and\", filters: filtered } as R);\n },\n or: (results) => {\n const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);\n return filtered.length === 0 ? null : ({ type: \"or\", filters: filtered } as R);\n },\n not: (result) => (result === null ? null : ({ type: \"not\", filter: result } as R)),\n });\n}\n"],"names":[],"mappings":";;;AAaA;AACA,MAAM,qBAAqB,GAAqC;IAC9D,GAAG;IACH,GAAG;IACH,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa;IACb,mBAAmB;CACpB;AACD,MAAM,eAAe,GAA2B,IAAI,GAAG,CAAC,qBAAqB,CAAC;AAE9E;AACA,SAAS,YAAY,CAAI,IAAuB,EAAA;AAC9C,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI;AAAE,QAAA,OAAO,KAAK;AACnC,IAAA,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAI;QACzC,QAAQ,OAAO,KAAK;AAClB,YAAA,KAAK,QAAQ;AACb,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,KAAK;AACd,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;AAC5B,YAAA;AACE,gBAAA,OAAO,OAAO,CAAC,KAAK,CAAC;;AAE3B,IAAA,CAAC,CAAC;AACJ;AAEA,SAAS,WAAW,CAAI,IAAuB,EAAA;IAC7C,MAAM,MAAM,GAA4B,EAAE;AAC1C,IAAA,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/C,QAAA,IAAI,eAAe,CAAC,GAAG,CAAC,GAAwB,CAAC,EAAE;AACjD,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;QACrB;IACF;AACA,IAAA,OAAO,MAA2B;AACpC;AAEA;;;AAGG;AACG,SAAU,iBAAiB,CAK/B,MAA6B,EAAA;IAC7B,IAAI,MAAM,IAAI,IAAI;AAAE,QAAA,OAAO,IAAI;IAC/B,OAAO,kBAAkB,CAAe,MAAM,EAAE;AAC9C,QAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,YAAA,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC;AACnC,YAAA,OAAO,YAAY,CAAC,SAAS,CAAC,GAAI,SAAe,GAAG,IAAI;QAC1D,CAAC;AACD,QAAA,GAAG,EAAE,CAAC,OAAO,KAAI;AACf,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAQ;QACjF,CAAC;AACD,QAAA,EAAE,EAAE,CAAC,OAAO,KAAI;AACd,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAiC,CAAC,KAAK,IAAI,CAAC;YAC9E,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAQ;QAChF,CAAC;QACD,GAAG,EAAE,CAAC,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,GAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAQ,CAAC;AACnF,KAAA,CAAC;AACJ;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.58.2";
3
+ var version = "1.58.5";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.map
@@ -1,4 +1,4 @@
1
- var version = "1.58.2";
1
+ var version = "1.58.5";
2
2
 
3
3
  export { version };
4
4
  //# sourceMappingURL=package.json.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/model",
3
- "version": "1.58.2",
3
+ "version": "1.58.5",
4
4
  "description": "Platforma.bio SDK / Block Model",
5
5
  "files": [
6
6
  "./dist/**/*",
@@ -25,18 +25,18 @@
25
25
  "utility-types": "^3.11.0",
26
26
  "zod": "~3.23.8",
27
27
  "@milaboratories/helpers": "1.13.5",
28
+ "@milaboratories/pl-error-like": "1.12.8",
28
29
  "@milaboratories/pl-model-common": "1.25.1",
29
- "@milaboratories/ptabler-expression-js": "1.1.23",
30
- "@milaboratories/pl-error-like": "1.12.8"
30
+ "@milaboratories/ptabler-expression-js": "1.1.23"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@vitest/coverage-istanbul": "^4.0.18",
34
34
  "fast-json-patch": "^3.1.1",
35
35
  "typescript": "~5.6.3",
36
36
  "vitest": "^4.0.18",
37
- "@milaboratories/ts-configs": "1.2.1",
37
+ "@milaboratories/ts-builder": "1.2.11",
38
38
  "@milaboratories/build-configs": "1.5.0",
39
- "@milaboratories/ts-builder": "1.2.11"
39
+ "@milaboratories/ts-configs": "1.2.1"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "ts-builder build --target node",
@@ -6,7 +6,6 @@ import type {
6
6
  BlockCodeKnownFeatureFlags,
7
7
  BlockConfigContainer,
8
8
  } from "@milaboratories/pl-model-common";
9
- import { mergeFeatureFlags } from "@milaboratories/pl-model-common";
10
9
  import { getPlatformaInstance, isInUI, createAndRegisterRenderLambda } from "./internal";
11
10
  import type { DataModel } from "./block_migrations";
12
11
  import type { PlatformaV3 } from "./platforma";
@@ -57,6 +56,28 @@ export type ParamsInput<Params, BArgs = unknown, BData = unknown> = {
57
56
  */
58
57
  type ParamsInputErased = Record<string, (ctx: RenderCtxBase) => unknown>;
59
58
 
59
+ /**
60
+ * Merges two feature flag objects with type-aware logic:
61
+ * - `supports*` (boolean): OR — `true` if either side is `true`
62
+ * - `requires*` (numeric): MAX — take the higher version requirement
63
+ */
64
+ function mergeFeatureFlags(
65
+ base: BlockCodeKnownFeatureFlags,
66
+ override: BlockCodeKnownFeatureFlags,
67
+ ): BlockCodeKnownFeatureFlags {
68
+ const result: Record<string, boolean | number | undefined> = { ...base };
69
+ for (const [key, value] of Object.entries(override)) {
70
+ if (value === undefined) continue;
71
+ const existing = result[key];
72
+ if (typeof value === "boolean") {
73
+ result[key] = (typeof existing === "boolean" && existing) || value;
74
+ } else if (typeof value === "number") {
75
+ result[key] = Math.max(typeof existing === "number" ? existing : 0, value);
76
+ }
77
+ }
78
+ return result as BlockCodeKnownFeatureFlags;
79
+ }
80
+
60
81
  /**
61
82
  * Registered plugin: model + param derivation lambdas.
62
83
  * Type parameters are carried by PluginModel generic.
@@ -6,6 +6,7 @@ import {
6
6
  } from "@milaboratories/pl-model-common";
7
7
  import { traverseFilterSpec } from "./traverse";
8
8
  import { InferFilterSpecLeaf } from "@milaboratories/pl-model-common";
9
+ import { isEmpty } from "es-toolkit/compat";
9
10
 
10
11
  /** All possible field names that can appear in any FilterSpecLeaf variant. */
11
12
  type FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;
@@ -27,19 +28,29 @@ const KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [
27
28
  const KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);
28
29
 
29
30
  /** Returns true if the leaf is filled — type is defined and no required fields are undefined. */
30
- function isFilledLeaf(node: Record<string, unknown>): boolean {
31
+ function isFilledLeaf<T>(node: FilterSpecLeaf<T>): boolean {
31
32
  if (node.type == null) return false;
32
- return !Object.values(node).some((v) => v === undefined);
33
+ return !Object.values(node).some((value) => {
34
+ switch (typeof value) {
35
+ case "number":
36
+ case "boolean":
37
+ return false;
38
+ case "string":
39
+ return value.trim() === "";
40
+ default: // undefined, null, empty objects/arrays
41
+ return isEmpty(value);
42
+ }
43
+ });
33
44
  }
34
45
 
35
- function distillLeaf(node: Record<string, unknown>): FilterSpecLeaf<string> {
46
+ function distillLeaf<T>(node: FilterSpecLeaf<T>): FilterSpecLeaf<T> {
36
47
  const result: Record<string, unknown> = {};
37
48
  for (const [key, value] of Object.entries(node)) {
38
49
  if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {
39
50
  result[key] = value;
40
51
  }
41
52
  }
42
- return result as FilterSpecLeaf<string>;
53
+ return result as FilterSpecLeaf<T>;
43
54
  }
44
55
 
45
56
  /**
@@ -55,8 +66,8 @@ export function distillFilterSpec<
55
66
  if (filter == null) return null;
56
67
  return traverseFilterSpec<FS, null | R>(filter, {
57
68
  leaf: (leaf) => {
58
- if (!isFilledLeaf(leaf as Record<string, unknown>)) return null;
59
- return distillLeaf(leaf as Record<string, unknown>) as R;
69
+ const distilled = distillLeaf(leaf);
70
+ return isFilledLeaf(distilled) ? (distilled as R) : null;
60
71
  },
61
72
  and: (results) => {
62
73
  const filtered = results.filter((f): f is NonNullable<typeof f> => f !== null);