@platforma-sdk/model 1.48.14 → 1.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"raw_globals.d.ts","sourceRoot":"","sources":["../src/raw_globals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAGrE,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlE,wBAAgB,sBAAsB,IAAI,mBAAmB,CAE5D;AAED,wBAAgB,uBAAuB,CACrC,IAAI,GAAG,OAAO,EACd,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,EAC/F,OAAO,GAAG,OAAO,EACjB,IAAI,SAAS,IAAI,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,KACrC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAE3C;AAED,wFAAwF"}
1
+ {"version":3,"file":"raw_globals.d.ts","sourceRoot":"","sources":["../src/raw_globals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlE,wBAAgB,sBAAsB,IAAI,mBAAmB,CAE5D;AAED,wBAAgB,uBAAuB,CACrC,IAAI,GAAG,OAAO,EACd,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EACrG,OAAO,GAAG,OAAO,EACjB,IAAI,SAAS,IAAI,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,KACrC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAE3C;AAED,wFAAwF"}
@@ -1 +1 @@
1
- {"version":3,"file":"raw_globals.js","sources":["../src/raw_globals.ts"],"sourcesContent":["import type { ValueOrErrors } from '@milaboratories/pl-model-common';\nimport {} from './global';\nimport { getPlatformaInstance } from './internal';\nimport type { Platforma, PlatformaApiVersion } from './platforma';\nimport { PlatformaSDKVersion } from './version';\n\nexport function getPlatformaApiVersion(): PlatformaApiVersion {\n return platformaApiVersion ?? 1; // undefined means 1 for backward compatibility\n}\n\nexport function getRawPlatformaInstance<\n Args = unknown,\n Outputs extends Record<string, ValueOrErrors<unknown>> = Record<string, ValueOrErrors<unknown>>,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(): Platforma<Args, Outputs, UiState, Href> {\n return getPlatformaInstance<Args, Outputs, UiState, Href>({ sdkVersion: PlatformaSDKVersion, apiVersion: platformaApiVersion });\n}\n\n/** Returns a global platforma instance or a provided fallback if it's not available. */\n// export function getPlatformaOrDefault<\n// Args = unknown,\n// Outputs extends Record<string, ValueOrErrors<unknown>> = Record<string, ValueOrErrors<unknown>>,\n// UiState = unknown,\n// Href extends `/${string}` = `/${string}`,\n// >(): PlatformaV1<Args, Outputs, UiState, Href> | PlatformaV2<Args, Outputs, UiState, Href> {\n// try {\n// return getRawPlatformaInstance<Args, Outputs, UiState, Href>();\n// } catch {\n// return platforma;\n// }\n// }\n"],"names":[],"mappings":";;;SAMgB,sBAAsB,GAAA;AACpC,IAAA,OAAO,mBAAmB,IAAI,CAAC,CAAC;AAClC;SAEgB,uBAAuB,GAAA;AAMrC,IAAA,OAAO,oBAAoB,CAA+B,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC;AACjI;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"raw_globals.js","sources":["../src/raw_globals.ts"],"sourcesContent":["import type { OutputWithStatus } from '@milaboratories/pl-model-common';\nimport {} from './global';\nimport { getPlatformaInstance } from './internal';\nimport type { Platforma, PlatformaApiVersion } from './platforma';\nimport { PlatformaSDKVersion } from './version';\n\nexport function getPlatformaApiVersion(): PlatformaApiVersion {\n return platformaApiVersion ?? 1; // undefined means 1 for backward compatibility\n}\n\nexport function getRawPlatformaInstance<\n Args = unknown,\n Outputs extends Record<string, OutputWithStatus<unknown>> = Record<string, OutputWithStatus<unknown>>,\n UiState = unknown,\n Href extends `/${string}` = `/${string}`,\n>(): Platforma<Args, Outputs, UiState, Href> {\n return getPlatformaInstance<Args, Outputs, UiState, Href>({ sdkVersion: PlatformaSDKVersion, apiVersion: platformaApiVersion });\n}\n\n/** Returns a global platforma instance or a provided fallback if it's not available. */\n// export function getPlatformaOrDefault<\n// Args = unknown,\n// Outputs extends Record<string, ValueOrErrors<unknown>> = Record<string, ValueOrErrors<unknown>>,\n// UiState = unknown,\n// Href extends `/${string}` = `/${string}`,\n// >(): PlatformaV1<Args, Outputs, UiState, Href> | PlatformaV2<Args, Outputs, UiState, Href> {\n// try {\n// return getRawPlatformaInstance<Args, Outputs, UiState, Href>();\n// } catch {\n// return platforma;\n// }\n// }\n"],"names":[],"mappings":";;;SAMgB,sBAAsB,GAAA;AACpC,IAAA,OAAO,mBAAmB,IAAI,CAAC,CAAC;AAClC;SAEgB,uBAAuB,GAAA;AAMrC,IAAA,OAAO,oBAAoB,CAA+B,EAAE,UAAU,EAAE,mBAAmB,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC;AACjI;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/model",
3
- "version": "1.48.14",
3
+ "version": "1.50.0",
4
4
  "description": "Platforma.bio SDK / Block Model",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -23,20 +23,20 @@
23
23
  "canonicalize": "~2.1.0",
24
24
  "es-toolkit": "^1.39.10",
25
25
  "zod": "~3.23.8",
26
+ "@milaboratories/ptabler-expression-js": "1.1.9",
26
27
  "@milaboratories/pl-error-like": "1.12.5",
27
- "@milaboratories/pl-model-common": "1.21.10",
28
- "@milaboratories/ptabler-expression-js": "1.1.7"
28
+ "@milaboratories/pl-model-common": "1.23.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "~5.6.3",
32
32
  "vitest": "^4.0.16",
33
33
  "@vitest/coverage-istanbul": "^4.0.16",
34
34
  "fast-json-patch": "^3.1.1",
35
- "@milaboratories/build-configs": "1.2.1",
36
- "@milaboratories/helpers": "1.12.1",
37
- "@milaboratories/ts-builder": "1.2.1",
35
+ "@milaboratories/eslint-config": "1.0.5",
36
+ "@milaboratories/helpers": "1.13.0",
38
37
  "@milaboratories/ts-configs": "1.2.0",
39
- "@milaboratories/eslint-config": "1.0.5"
38
+ "@milaboratories/ts-builder": "1.2.1",
39
+ "@milaboratories/build-configs": "1.2.1"
40
40
  },
41
41
  "scripts": {
42
42
  "type-check": "ts-builder types --target node",
@@ -29,13 +29,22 @@ export type ConfigRenderLambdaFlags = {
29
29
  * nobody is actively monitoring rendered values. Like file upload progress, that triggers upload itself.
30
30
  * */
31
31
  isActive?: boolean;
32
+
33
+ /**
34
+ * If true, result will be wrapped with additional status information,
35
+ * such as stability status and explicit error
36
+ */
37
+ withStatus?: boolean;
32
38
  };
33
39
 
34
40
  /** Creates branded Cfg type */
35
- export interface ConfigRenderLambda<_Return = unknown> extends ConfigRenderLambdaFlags {
41
+ export interface ConfigRenderLambda<Return = unknown> extends ConfigRenderLambdaFlags {
36
42
  /** Type marker */
37
43
  __renderLambda: true;
38
44
 
45
+ /** Phantom property for type inference. Never set at runtime. */
46
+ __phantomReturn?: Return;
47
+
39
48
  /** Reference to a callback registered inside the model code. */
40
49
  handle: string;
41
50
  }
@@ -1,4 +1,4 @@
1
- import type { BlockOutputsBase, ValueOrErrors } from '@milaboratories/pl-model-common';
1
+ import type { BlockOutputsBase, OutputWithStatus } from '@milaboratories/pl-model-common';
2
2
  import type { ErrorLike } from '@milaboratories/pl-error-like';
3
3
 
4
4
  export class OutputError extends Error {
@@ -10,12 +10,12 @@ export class OutputError extends Error {
10
10
  }
11
11
  }
12
12
 
13
- export function readOutput<T>(outputValue: ValueOrErrors<T>): T {
13
+ export function readOutput<T>(outputValue: OutputWithStatus<T>): T {
14
14
  if (!outputValue.ok) throw new OutputError(outputValue.errors, outputValue.moreErrors);
15
15
  return outputValue.value;
16
16
  }
17
17
 
18
- type ExtractValueType<V extends ValueOrErrors<unknown>> = Extract<V, { ok: true }>['value'];
18
+ type ExtractValueType<V extends OutputWithStatus<unknown>> = Extract<V, { ok: true }>['value'];
19
19
  type SimpleOutputs<Outputs extends BlockOutputsBase> = {
20
20
  [Key in keyof Outputs]: ExtractValueType<Outputs[Key]>;
21
21
  };
package/src/builder.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BlockRenderingMode, BlockSection, ValueOrErrors, AnyFunction, PlRef, BlockCodeKnownFeatureFlags, BlockConfigContainer } from '@milaboratories/pl-model-common';
1
+ import type { BlockRenderingMode, BlockSection, AnyFunction, PlRef, BlockCodeKnownFeatureFlags, BlockConfigContainer, OutputWithStatus } from '@milaboratories/pl-model-common';
2
2
  import type { Checked, ConfigResult, TypedConfig } from './config';
3
3
  import { getImmediate } from './config';
4
4
  import { getPlatformaInstance, isInUI, tryRegisterCallback } from './internal';
@@ -17,6 +17,7 @@ import type {
17
17
  } from './bconfig';
18
18
  import {
19
19
  downgradeCfgOrLambda,
20
+ isConfigLambda,
20
21
  } from './bconfig';
21
22
 
22
23
  type SectionsExpectedType = readonly BlockSection[];
@@ -57,22 +58,28 @@ export class BlockModel<
57
58
  Href extends `/${string}` = '/',
58
59
  > {
59
60
  private constructor(
60
- private readonly _renderingMode: BlockRenderingMode,
61
- private readonly _initialArgs: Args | undefined,
62
- private readonly _initialUiState: UiState,
63
- private readonly _outputs: OutputsCfg,
64
- private readonly _inputsValid: TypedConfigOrConfigLambda,
65
- private readonly _sections: TypedConfigOrConfigLambda,
66
- private readonly _title: ConfigRenderLambda | undefined,
67
- private readonly _enrichmentTargets: ConfigRenderLambda | undefined,
68
- private readonly _featureFlags: BlockCodeKnownFeatureFlags,
61
+ private config: {
62
+ readonly renderingMode: BlockRenderingMode;
63
+ readonly initialArgs?: Args;
64
+ readonly initialUiState: UiState;
65
+ readonly outputs: OutputsCfg;
66
+ readonly inputsValid: TypedConfigOrConfigLambda;
67
+ readonly sections: TypedConfigOrConfigLambda;
68
+ readonly title?: ConfigRenderLambda;
69
+ readonly subtitle?: ConfigRenderLambda;
70
+ readonly tags?: ConfigRenderLambda;
71
+ readonly enrichmentTargets?: ConfigRenderLambda;
72
+ readonly featureFlags: BlockCodeKnownFeatureFlags;
73
+ },
69
74
  ) {}
70
75
 
71
- public static readonly INITIAL_BLOCK_FEATURE_FLAGS: BlockCodeKnownFeatureFlags = {
72
- supportsLazyState: true,
73
- requiresUIAPIVersion: 1,
74
- requiresModelAPIVersion: 1,
75
- };
76
+ public static get INITIAL_BLOCK_FEATURE_FLAGS(): BlockCodeKnownFeatureFlags {
77
+ return {
78
+ supportsLazyState: true,
79
+ requiresUIAPIVersion: 1,
80
+ requiresModelAPIVersion: 1,
81
+ };
82
+ }
76
83
 
77
84
  /** Initiates configuration builder */
78
85
  public static create(renderingMode: BlockRenderingMode): BlockModel<NoOb, {}, NoOb>;
@@ -89,17 +96,14 @@ export class BlockModel<
89
96
  */
90
97
  public static create<Args>(): BlockModel<Args, {}, NoOb>;
91
98
  public static create(renderingMode: BlockRenderingMode = 'Heavy'): BlockModel<NoOb, {}, NoOb> {
92
- return new BlockModel<NoOb, {}, NoOb>(
99
+ return new BlockModel<NoOb, {}, NoOb>({
93
100
  renderingMode,
94
- undefined,
95
- {},
96
- {},
97
- getImmediate(true),
98
- getImmediate([]),
99
- undefined,
100
- undefined,
101
- { ...BlockModel.INITIAL_BLOCK_FEATURE_FLAGS },
102
- );
101
+ initialUiState: {},
102
+ outputs: {},
103
+ inputsValid: getImmediate(true),
104
+ sections: getImmediate([]),
105
+ featureFlags: BlockModel.INITIAL_BLOCK_FEATURE_FLAGS,
106
+ });
103
107
  }
104
108
 
105
109
  /**
@@ -114,6 +118,24 @@ export class BlockModel<
114
118
  key: Key,
115
119
  cfg: Cfg
116
120
  ): BlockModel<Args, OutputsCfg & { [K in Key]: Cfg }, UiState, Href>;
121
+ /**
122
+ * Add output cell wrapped with additional status information to the configuration
123
+ *
124
+ * @param key output cell name, that can be later used to retrieve the rendered value
125
+ * @param rf callback calculating output value using context, that allows to access
126
+ * workflows outputs and interact with platforma drivers
127
+ * @param flags additional flags that may alter lambda rendering procedure
128
+ * */
129
+ public output<const Key extends string, const RF extends RenderFunction<Args, UiState>>(
130
+ key: Key,
131
+ rf: RF,
132
+ flags: ConfigRenderLambdaFlags & { withStatus: true }
133
+ ): BlockModel<
134
+ Args,
135
+ OutputsCfg & { [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> & { withStatus: true } },
136
+ UiState,
137
+ Href
138
+ >;
117
139
  /**
118
140
  * Add output cell to the configuration
119
141
  *
@@ -140,54 +162,52 @@ export class BlockModel<
140
162
  if (typeof cfgOrRf === 'function') {
141
163
  const handle = `output#${key}`;
142
164
  tryRegisterCallback(handle, () => cfgOrRf(new RenderCtx()));
143
- return new BlockModel(
144
- this._renderingMode,
145
- this._initialArgs,
146
- this._initialUiState,
147
- {
148
- ...this._outputs,
165
+ return new BlockModel({
166
+ ...this.config,
167
+ outputs: {
168
+ ...this.config.outputs,
149
169
  [key]: {
150
170
  __renderLambda: true,
151
171
  handle,
152
172
  ...flags,
153
- } satisfies ConfigRenderLambda,
173
+ },
154
174
  },
155
- this._inputsValid,
156
- this._sections,
157
- this._title,
158
- this._enrichmentTargets,
159
- this._featureFlags,
160
- );
161
- } else
162
- return new BlockModel(
163
- this._renderingMode,
164
- this._initialArgs,
165
- this._initialUiState,
166
- {
167
- ...this._outputs,
175
+ });
176
+ } else {
177
+ return new BlockModel({
178
+ ...this.config,
179
+ outputs: {
180
+ ...this.config.outputs,
168
181
  [key]: cfgOrRf,
169
182
  },
170
- this._inputsValid,
171
- this._sections,
172
- this._title,
173
- this._enrichmentTargets,
174
- this._featureFlags,
175
- );
183
+ });
184
+ }
176
185
  }
177
186
 
178
187
  /** Shortcut for {@link output} with retentive flag set to true. */
179
188
  public retentiveOutput<const Key extends string, const RF extends RenderFunction<Args, UiState>>(
180
189
  key: Key,
181
190
  rf: RF,
182
- ): BlockModel<
183
- Args,
184
- OutputsCfg & { [K in Key]: ConfigRenderLambda<InferRenderFunctionReturn<RF>> },
185
- UiState,
186
- Href
187
- > {
191
+ ) {
188
192
  return this.output(key, rf, { retentive: true });
189
193
  }
190
194
 
195
+ /** Shortcut for {@link output} with withStatus flag set to true. */
196
+ public outputWithStatus<const Key extends string, const RF extends RenderFunction<Args, UiState>>(
197
+ key: Key,
198
+ rf: RF,
199
+ ) {
200
+ return this.output(key, rf, { withStatus: true });
201
+ }
202
+
203
+ /** Shortcut for {@link output} with retentive and withStatus flags set to true. */
204
+ public retentiveOutputWithStatus<const Key extends string, const RF extends RenderFunction<Args, UiState>>(
205
+ key: Key,
206
+ rf: RF,
207
+ ) {
208
+ return this.output(key, rf, { retentive: true, withStatus: true });
209
+ }
210
+
191
211
  /** Sets custom configuration predicate on the block args at which block can be executed
192
212
  * @deprecated use lambda-based API */
193
213
  public argsValid<Cfg extends TypedConfig>(
@@ -202,32 +222,19 @@ export class BlockModel<
202
222
  ): BlockModel<Args, OutputsCfg, UiState, `/${string}`> {
203
223
  if (typeof cfgOrRf === 'function') {
204
224
  tryRegisterCallback('inputsValid', () => cfgOrRf(new RenderCtx()));
205
- return new BlockModel<Args, OutputsCfg, UiState>(
206
- this._renderingMode,
207
- this._initialArgs,
208
- this._initialUiState,
209
- this._outputs,
210
- {
225
+ return new BlockModel<Args, OutputsCfg, UiState>({
226
+ ...this.config,
227
+ inputsValid: {
211
228
  __renderLambda: true,
212
229
  handle: 'inputsValid',
213
- } satisfies ConfigRenderLambda,
214
- this._sections,
215
- this._title,
216
- this._enrichmentTargets,
217
- this._featureFlags,
218
- );
219
- } else
220
- return new BlockModel<Args, OutputsCfg, UiState>(
221
- this._renderingMode,
222
- this._initialArgs,
223
- this._initialUiState,
224
- this._outputs,
225
- cfgOrRf,
226
- this._sections,
227
- this._title,
228
- this._enrichmentTargets,
229
- this._featureFlags,
230
- );
230
+ },
231
+ });
232
+ } else {
233
+ return new BlockModel<Args, OutputsCfg, UiState>({
234
+ ...this.config,
235
+ inputsValid: cfgOrRf,
236
+ });
237
+ }
231
238
  }
232
239
 
233
240
  /** Sets the config to generate list of section in the left block overviews panel
@@ -255,29 +262,19 @@ export class BlockModel<
255
262
  return this.sections(getImmediate(arrOrCfgOrRf));
256
263
  } else if (typeof arrOrCfgOrRf === 'function') {
257
264
  tryRegisterCallback('sections', () => arrOrCfgOrRf(new RenderCtx()));
258
- return new BlockModel<Args, OutputsCfg, UiState>(
259
- this._renderingMode,
260
- this._initialArgs,
261
- this._initialUiState,
262
- this._outputs,
263
- this._inputsValid,
264
- { __renderLambda: true, handle: 'sections' } as ConfigRenderLambda,
265
- this._title,
266
- this._enrichmentTargets,
267
- this._featureFlags,
268
- );
269
- } else
270
- return new BlockModel<Args, OutputsCfg, UiState>(
271
- this._renderingMode,
272
- this._initialArgs,
273
- this._initialUiState,
274
- this._outputs,
275
- this._inputsValid,
276
- arrOrCfgOrRf as TypedConfig,
277
- this._title,
278
- this._enrichmentTargets,
279
- this._featureFlags,
280
- );
265
+ return new BlockModel<Args, OutputsCfg, UiState>({
266
+ ...this.config,
267
+ sections: {
268
+ __renderLambda: true,
269
+ handle: 'sections',
270
+ },
271
+ });
272
+ } else {
273
+ return new BlockModel<Args, OutputsCfg, UiState>({
274
+ ...this.config,
275
+ sections: arrOrCfgOrRf as TypedConfig,
276
+ });
277
+ }
281
278
  }
282
279
 
283
280
  /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */
@@ -285,17 +282,39 @@ export class BlockModel<
285
282
  rf: RenderFunction<Args, UiState, string>,
286
283
  ): BlockModel<Args, OutputsCfg, UiState, Href> {
287
284
  tryRegisterCallback('title', () => rf(new RenderCtx()));
288
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
289
- this._renderingMode,
290
- this._initialArgs,
291
- this._initialUiState,
292
- this._outputs,
293
- this._inputsValid,
294
- this._sections,
295
- { __renderLambda: true, handle: 'title' } as ConfigRenderLambda,
296
- this._enrichmentTargets,
297
- this._featureFlags,
298
- );
285
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
286
+ ...this.config,
287
+ title: {
288
+ __renderLambda: true,
289
+ handle: 'title',
290
+ },
291
+ });
292
+ }
293
+
294
+ public subtitle(
295
+ rf: RenderFunction<Args, UiState, string>,
296
+ ): BlockModel<Args, OutputsCfg, UiState, Href> {
297
+ tryRegisterCallback('subtitle', () => rf(new RenderCtx()));
298
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
299
+ ...this.config,
300
+ subtitle: {
301
+ __renderLambda: true,
302
+ handle: 'subtitle',
303
+ },
304
+ });
305
+ }
306
+
307
+ public tags(
308
+ rf: RenderFunction<Args, UiState, string[]>,
309
+ ): BlockModel<Args, OutputsCfg, UiState, Href> {
310
+ tryRegisterCallback('tags', () => rf(new RenderCtx()));
311
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
312
+ ...this.config,
313
+ tags: {
314
+ __renderLambda: true,
315
+ handle: 'tags',
316
+ },
317
+ });
299
318
  }
300
319
 
301
320
  /**
@@ -303,62 +322,34 @@ export class BlockModel<
303
322
  * @deprecated use {@link withArgs}
304
323
  * */
305
324
  public initialArgs(value: Args): BlockModel<Args, OutputsCfg, UiState, Href> {
306
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
307
- this._renderingMode,
308
- value,
309
- this._initialUiState,
310
- this._outputs,
311
- this._inputsValid,
312
- this._sections,
313
- this._title,
314
- this._enrichmentTargets,
315
- this._featureFlags,
316
- );
325
+ return this.withArgs(value);
317
326
  }
318
327
 
319
328
  /** Sets initial args for the block, this value must be specified. */
320
- public withArgs<Args>(initialValue: Args): BlockModel<Args, OutputsCfg, UiState, Href> {
321
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
322
- this._renderingMode,
323
- initialValue,
324
- this._initialUiState,
325
- this._outputs,
326
- this._inputsValid,
327
- this._sections,
328
- this._title,
329
- this._enrichmentTargets,
330
- this._featureFlags,
331
- );
329
+ public withArgs<Args>(initialArgs: Args): BlockModel<Args, OutputsCfg, UiState, Href> {
330
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
331
+ ...this.config,
332
+ initialArgs,
333
+ });
332
334
  }
333
335
 
334
336
  /** Defines type and sets initial value for block UiState. */
335
- public withUiState<UiState>(initialValue: UiState): BlockModel<Args, OutputsCfg, UiState, Href> {
336
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
337
- this._renderingMode,
338
- this._initialArgs,
339
- initialValue,
340
- this._outputs,
341
- this._inputsValid,
342
- this._sections,
343
- this._title,
344
- this._enrichmentTargets,
345
- this._featureFlags,
346
- );
337
+ public withUiState<UiState>(initialUiState: UiState): BlockModel<Args, OutputsCfg, UiState, Href> {
338
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
339
+ ...this.config,
340
+ initialUiState,
341
+ });
347
342
  }
348
343
 
349
344
  /** Sets or overrides feature flags for the block. */
350
345
  public withFeatureFlags(flags: Partial<BlockCodeKnownFeatureFlags>): BlockModel<Args, OutputsCfg, UiState, Href> {
351
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
352
- this._renderingMode,
353
- this._initialArgs,
354
- this._initialUiState,
355
- this._outputs,
356
- this._inputsValid,
357
- this._sections,
358
- this._title,
359
- this._enrichmentTargets,
360
- { ...this._featureFlags, ...flags },
361
- );
346
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
347
+ ...this.config,
348
+ featureFlags: {
349
+ ...this.config.featureFlags,
350
+ ...flags,
351
+ },
352
+ });
362
353
  }
363
354
 
364
355
  /**
@@ -369,89 +360,96 @@ export class BlockModel<
369
360
  lambda: (args: Args) => PlRef[],
370
361
  ): BlockModel<Args, OutputsCfg, UiState, Href> {
371
362
  tryRegisterCallback('enrichmentTargets', lambda);
372
- return new BlockModel<Args, OutputsCfg, UiState, Href>(
373
- this._renderingMode,
374
- this._initialArgs,
375
- this._initialUiState,
376
- this._outputs,
377
- this._inputsValid,
378
- this._sections,
379
- this._title,
380
- { __renderLambda: true, handle: 'enrichmentTargets' } as ConfigRenderLambda,
381
- this._featureFlags,
382
- );
363
+ return new BlockModel<Args, OutputsCfg, UiState, Href>({
364
+ ...this.config,
365
+ enrichmentTargets: {
366
+ __renderLambda: true,
367
+ handle: 'enrichmentTargets',
368
+ },
369
+ });
383
370
  }
384
371
 
385
- public done(apiVersion?: 1): PlatformaV1<
372
+ public done(apiVersion?: 1): PlatformaExtended<PlatformaV1<
386
373
  Args,
387
374
  InferOutputsFromConfigs<Args, OutputsCfg, UiState>,
388
375
  UiState,
389
376
  Href
390
- >;
377
+ >>;
391
378
 
392
- public done(apiVersion: 2): PlatformaV2<
379
+ public done(apiVersion: 2): PlatformaExtended<PlatformaV2<
393
380
  Args,
394
381
  InferOutputsFromConfigs<Args, OutputsCfg, UiState>,
395
382
  UiState,
396
383
  Href
397
- >;
384
+ >>;
398
385
 
399
386
  /** Renders all provided block settings into a pre-configured platforma API
400
387
  * instance, that can be used in frontend to interact with block state, and
401
388
  * other features provided by the platforma to the block. */
402
- public done(apiVersion?: PlatformaApiVersion): Platforma<
389
+ public done(apiVersion: PlatformaApiVersion = 1): PlatformaExtended<Platforma<
403
390
  Args,
404
391
  InferOutputsFromConfigs<Args, OutputsCfg, UiState>,
405
392
  UiState,
406
393
  Href
407
- > {
408
- const requiresUIAPIVersion = apiVersion ?? 1;
394
+ >> {
409
395
  return this.withFeatureFlags({
410
- ...this._featureFlags,
411
- requiresUIAPIVersion,
412
- })._done(requiresUIAPIVersion);
396
+ ...this.config.featureFlags,
397
+ requiresUIAPIVersion: apiVersion,
398
+ }).#done();
413
399
  }
414
400
 
415
- public _done(apiVersion: PlatformaApiVersion): Platforma<
401
+ #done(): PlatformaExtended<Platforma<
416
402
  Args,
417
403
  InferOutputsFromConfigs<Args, OutputsCfg, UiState>,
418
404
  UiState,
419
405
  Href
420
- > {
421
- if (this._initialArgs === undefined) throw new Error('Initial arguments not set.');
406
+ >> {
407
+ if (this.config.initialArgs === undefined) throw new Error('Initial arguments not set.');
422
408
 
423
409
  const config: BlockConfigContainer = {
424
410
  v3: {
425
411
  sdkVersion: PlatformaSDKVersion,
426
- renderingMode: this._renderingMode,
427
- initialArgs: this._initialArgs,
428
- initialUiState: this._initialUiState,
429
- inputsValid: this._inputsValid,
430
- sections: this._sections,
431
- title: this._title,
432
- outputs: this._outputs,
433
- enrichmentTargets: this._enrichmentTargets,
434
- featureFlags: this._featureFlags,
412
+ renderingMode: this.config.renderingMode,
413
+ initialArgs: this.config.initialArgs,
414
+ initialUiState: this.config.initialUiState,
415
+ inputsValid: this.config.inputsValid,
416
+ sections: this.config.sections,
417
+ title: this.config.title,
418
+ subtitle: this.config.subtitle,
419
+ tags: this.config.tags,
420
+ outputs: this.config.outputs,
421
+ enrichmentTargets: this.config.enrichmentTargets,
422
+ featureFlags: this.config.featureFlags,
435
423
  },
436
424
 
437
425
  // fields below are added to allow previous desktop versions read generated configs
438
426
  sdkVersion: PlatformaSDKVersion,
439
- renderingMode: this._renderingMode,
440
- initialArgs: this._initialArgs,
441
- inputsValid: downgradeCfgOrLambda(this._inputsValid),
442
- sections: downgradeCfgOrLambda(this._sections),
427
+ renderingMode: this.config.renderingMode,
428
+ initialArgs: this.config.initialArgs,
429
+ inputsValid: downgradeCfgOrLambda(this.config.inputsValid),
430
+ sections: downgradeCfgOrLambda(this.config.sections),
443
431
  outputs: Object.fromEntries(
444
- Object.entries(this._outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)]),
432
+ Object.entries(this.config.outputs).map(([key, value]) => [key, downgradeCfgOrLambda(value)]),
445
433
  ),
446
434
  };
447
435
 
448
- globalThis.platformaApiVersion = apiVersion;
436
+ globalThis.platformaApiVersion = this.config.featureFlags.requiresUIAPIVersion as PlatformaApiVersion;
449
437
 
450
438
  if (!isInUI())
451
439
  // we are in the configuration rendering routine, not in actual UI
452
440
  return { config } as any;
453
441
  // normal operation inside the UI
454
- else return getPlatformaInstance({ sdkVersion: PlatformaSDKVersion, apiVersion: platformaApiVersion }) as any;
442
+ else return {
443
+ ...getPlatformaInstance({ sdkVersion: PlatformaSDKVersion, apiVersion: platformaApiVersion }),
444
+ blockModelInfo: {
445
+ outputs: Object.fromEntries(
446
+ Object.entries(this.config.outputs)
447
+ .map(([key, value]) => [key, {
448
+ withStatus: Boolean(isConfigLambda(value) && value.withStatus),
449
+ }]),
450
+ ),
451
+ },
452
+ };
455
453
  }
456
454
  }
457
455
 
@@ -466,5 +464,17 @@ type InferOutputsFromConfigs<
466
464
  OutputsCfg extends Record<string, TypedConfigOrConfigLambda>,
467
465
  UiState,
468
466
  > = {
469
- [Key in keyof OutputsCfg]: ValueOrErrors<InferOutputType<OutputsCfg[Key], Args, UiState>>;
467
+ [Key in keyof OutputsCfg]:
468
+ & OutputWithStatus<InferOutputType<OutputsCfg[Key], Args, UiState>>
469
+ & { __unwrap: (OutputsCfg[Key] extends { withStatus: true } ? false : true) };
470
+ };
471
+
472
+ export type PlatformaExtended<Pl extends Platforma = Platforma> = Pl & {
473
+ blockModelInfo: BlockModelInfo;
474
+ };
475
+
476
+ export type BlockModelInfo = {
477
+ outputs: Record<string, {
478
+ withStatus: boolean;
479
+ }>;
470
480
  };