@milaboratories/pl-model-common 1.23.0 → 1.24.1

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.
@@ -31,3 +31,20 @@ export type BlockState<
31
31
 
32
32
  readonly author: AuthorMarker | undefined;
33
33
  };
34
+
35
+ export type BlockStateV3<
36
+ Outputs extends BlockOutputsBase = BlockOutputsBase,
37
+ _Data = unknown,
38
+ Href extends `/${string}` = `/${string}`,
39
+ > = {
40
+ /** Block storage persisted in the block state */
41
+ blockStorage: unknown;
42
+
43
+ /** Outputs rendered with block config */
44
+ outputs: Outputs;
45
+
46
+ /** Current navigation state */
47
+ navigationState: NavigationState<Href>;
48
+
49
+ readonly author: AuthorMarker | undefined;
50
+ };
@@ -4,6 +4,86 @@ import type { BlockCodeFeatureFlags } from '../flags';
4
4
  import type { BlockCodeWithInfo, Code } from './code';
5
5
  import type { BlockRenderingMode } from './types';
6
6
 
7
+ /**
8
+ * Descriptor for a state migration function.
9
+ * Unlike ConfigRenderLambda, migrations are not rendered reactively -
10
+ * they are one-time synchronous transformations called during block pack updates.
11
+ */
12
+ export type MigrationDescriptor = {
13
+ /** Index of this migration in the migrations callback array */
14
+ readonly index: number;
15
+ };
16
+
17
+ /**
18
+ * BroadActiveHandleDescriptor = TypedConfigOrConfigLambda,
19
+ * NarrowActiveHandleDescriptor = ConfigRenderLambda
20
+ */
21
+ export type BlockConfigV4Generic<
22
+ _Args = unknown,
23
+ _Data extends Record<string, unknown> = Record<string, unknown>,
24
+ BroadActiveHandleDescriptor = unknown,
25
+ NarrowActiveHandleDescriptor extends BroadActiveHandleDescriptor = BroadActiveHandleDescriptor,
26
+ Outputs extends Record<string, BroadActiveHandleDescriptor> = Record<string, BroadActiveHandleDescriptor>,
27
+ > = {
28
+ /** Discriminator to identify config version */
29
+ readonly configVersion: 4;
30
+
31
+ readonly modelAPIVersion: 2;
32
+
33
+ /** SDK version used by the block */
34
+ readonly sdkVersion: string;
35
+
36
+ /** Main rendering mode for the block */
37
+ readonly renderingMode: BlockRenderingMode;
38
+
39
+ /** Lambda to derive block args from state */
40
+ readonly args: NarrowActiveHandleDescriptor;
41
+
42
+ /**
43
+ * Lambda to derive prerun args from state (optional).
44
+ * If not defined, defaults to using the args() result.
45
+ * Used for staging/prerun phase.
46
+ */
47
+ readonly prerunArgs?: NarrowActiveHandleDescriptor;
48
+
49
+ /** Lambda to get initial data when block is added to the project */
50
+ readonly initialData: NarrowActiveHandleDescriptor;
51
+
52
+ /** Lambda to derive list of sections for the left overview panel */
53
+ readonly sections: NarrowActiveHandleDescriptor;
54
+
55
+ /** Lambda to derive block title */
56
+ readonly title?: NarrowActiveHandleDescriptor;
57
+
58
+ /** Lambda to derive block subtitle, shown below the title */
59
+ readonly subtitle?: NarrowActiveHandleDescriptor;
60
+
61
+ /** Lambda returning array of tags for search functionality */
62
+ readonly tags?: BroadActiveHandleDescriptor;
63
+
64
+ /**
65
+ * Lambda returning list of upstream blocks this block enriches with its exports,
66
+ * influences dependency graph construction
67
+ * */
68
+ readonly enrichmentTargets?: NarrowActiveHandleDescriptor;
69
+
70
+ /** Configuration for the output cells */
71
+ readonly outputs: Outputs;
72
+
73
+ /**
74
+ * Array of migration descriptors for state version upgrades.
75
+ * Each migration transforms state from version N to N+1.
76
+ * Migrations are NOT rendered reactively - they run synchronously during block pack updates.
77
+ */
78
+ readonly migrations?: MigrationDescriptor[];
79
+
80
+ /** Config code bundle */
81
+ readonly code?: Code;
82
+
83
+ /** Feature flags for the block Model and UI code. */
84
+ readonly featureFlags?: BlockCodeFeatureFlags;
85
+ };
86
+
7
87
  /**
8
88
  * BroadActiveHandleDescriptor = TypedConfigOrConfigLambda,
9
89
  * NarrowActiveHandleDescriptor = ConfigRenderLambda
@@ -15,6 +95,11 @@ export type BlockConfigV3Generic<
15
95
  NarrowActiveHandleDescriptor extends BroadActiveHandleDescriptor = BroadActiveHandleDescriptor,
16
96
  Outputs extends Record<string, BroadActiveHandleDescriptor> = Record<string, BroadActiveHandleDescriptor>,
17
97
  > = {
98
+ /** Discriminator to identify config version */
99
+ readonly configVersion: 3;
100
+
101
+ readonly modelAPIVersion: 1;
102
+
18
103
  /** SDK version used by the block */
19
104
  readonly sdkVersion: string;
20
105
 
@@ -63,10 +148,10 @@ export type BlockConfigV3Generic<
63
148
  readonly featureFlags?: BlockCodeFeatureFlags;
64
149
  };
65
150
 
66
- export type BlockConfigGeneric = BlockConfigV3Generic;
151
+ export type BlockConfigGeneric = BlockConfigV3Generic | BlockConfigV4Generic;
67
152
 
68
- export function extractCodeWithInfo(cfg: BlockConfigV3Generic): BlockCodeWithInfo {
69
- if (cfg.code === undefined) throw new Error('No code bundle');
153
+ export function extractCodeWithInfo(cfg: BlockConfigGeneric): BlockCodeWithInfo {
154
+ if (cfg.code === undefined) throw new Error('extractCodeWithInfo: No code bundle');
70
155
  return {
71
156
  code: cfg.code,
72
157
  sdkVersion: cfg.sdkVersion,
@@ -1,11 +1,12 @@
1
- import type { BlockConfigV3Generic } from './block_config';
1
+ import type { BlockConfigV3Generic, BlockConfigV4Generic } from './block_config';
2
2
  import type { Code } from './code';
3
3
  import type { BlockRenderingMode } from './types';
4
4
 
5
5
  /** Container simplifying maintenance of forward and backward compatibility */
6
6
  export type BlockConfigContainer = {
7
+ readonly v4?: Omit<BlockConfigV4Generic, 'code'>;
7
8
  /** Actual config */
8
- readonly v3: Omit<BlockConfigV3Generic, 'code'>;
9
+ readonly v3?: Omit<BlockConfigV3Generic, 'code'>;
9
10
 
10
11
  /** Config code bundle. Actually is required, but we keep it optional for backward compatibility */
11
12
  readonly code?: Code;
@@ -16,12 +16,32 @@ function upgradeCfgOrLambda(
16
16
  /**
17
17
  * Takes universal config, and converts it into latest config structure.
18
18
  *
19
- * **Important**: This operation is not meant to be executed recusively.
19
+ * **Important**: This operation is not meant to be executed recursively.
20
20
  * In no circumstance result of this function should be persisted!
21
21
  * */
22
22
  export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGeneric {
23
- if (cfg.v3 !== undefined) {
24
- // version 3
23
+ if (cfg.v4 !== undefined) {
24
+ // version 4 (BlockModelV3) - inputsValid is derived from args() success/failure
25
+ const { args, prerunArgs, initialData, outputs, renderingMode, sdkVersion, featureFlags, sections, title, enrichmentTargets, migrations } = cfg.v4;
26
+ const { code } = cfg;
27
+ return {
28
+ configVersion: 4,
29
+ modelAPIVersion: 2,
30
+ args,
31
+ prerunArgs,
32
+ initialData,
33
+ outputs,
34
+ renderingMode,
35
+ sdkVersion,
36
+ featureFlags,
37
+ sections,
38
+ title,
39
+ enrichmentTargets,
40
+ migrations,
41
+ code,
42
+ };
43
+ } else if (cfg.v3 !== undefined) {
44
+ // version 3 (BlockModel v1)
25
45
  const {
26
46
  initialArgs,
27
47
  initialUiState,
@@ -38,6 +58,8 @@ export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGene
38
58
  } = cfg.v3;
39
59
  const { code } = cfg;
40
60
  return {
61
+ configVersion: 3,
62
+ modelAPIVersion: 1,
41
63
  initialArgs,
42
64
  initialUiState,
43
65
  inputsValid,
@@ -53,7 +75,7 @@ export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGene
53
75
  enrichmentTargets,
54
76
  };
55
77
  } else if (cfg.inputsValid !== undefined) {
56
- // version 2
78
+ // version 2 (legacy) - normalize to v3 format
57
79
  const { sdkVersion, renderingMode, outputs, inputsValid, sections, initialArgs, code } = cfg;
58
80
  const fields = Object.keys(cfg);
59
81
  if (
@@ -68,6 +90,8 @@ export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGene
68
90
  `Malformed config v2. SDK version ${sdkVersion}; Fields = ${fields.join(', ')}`,
69
91
  );
70
92
  return {
93
+ configVersion: 3,
94
+ modelAPIVersion: 1,
71
95
  sdkVersion,
72
96
  renderingMode,
73
97
  initialArgs,
@@ -80,7 +104,7 @@ export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGene
80
104
  code,
81
105
  };
82
106
  } else if (cfg.renderingMode !== undefined) {
83
- // version 1
107
+ // version 1 (legacy) - normalize to v3 format
84
108
  const { sdkVersion, canRun, renderingMode, outputs, sections, initialArgs, code } = cfg;
85
109
  const fields = Object.keys(cfg);
86
110
  if (
@@ -94,6 +118,8 @@ export function extractConfigGeneric(cfg: BlockConfigContainer): BlockConfigGene
94
118
  `Malformed config v1. SDK version ${sdkVersion}; Fields = ${fields.join(', ')}`,
95
119
  );
96
120
  return {
121
+ configVersion: 3,
122
+ modelAPIVersion: 1,
97
123
  sdkVersion: sdkVersion ?? 'unknown',
98
124
  renderingMode,
99
125
  initialArgs,
@@ -76,11 +76,17 @@ export function readMetadataJson<M extends Metadata, T extends keyof MetadataJso
76
76
  export const Domain = {
77
77
  Alphabet: 'pl7.app/alphabet',
78
78
  BlockId: 'pl7.app/blockId',
79
+ VDJ: {
80
+ ScClonotypeChain: {
81
+ Index: 'pl7.app/vdj/scClonotypeChain/index',
82
+ },
83
+ },
79
84
  } as const;
80
85
 
81
86
  export type Domain = Metadata & Partial<{
82
- [Domain.Alphabet]: 'nucleotide' | 'aminoacid' | string;
87
+ [Domain.Alphabet]: 'nucleotide' | 'aminoacid' | (string & {});
83
88
  [Domain.BlockId]: string;
89
+ [Domain.VDJ.ScClonotypeChain.Index]: 'primary' | 'secondary' | (string & {});
84
90
  }>;
85
91
 
86
92
  export type DomainJson = MetadataJson<Domain>;
@@ -152,11 +158,14 @@ export const Annotation = {
152
158
  Visibility: 'pl7.app/table/visibility',
153
159
  },
154
160
  Trace: 'pl7.app/trace',
161
+ VDJ: {
162
+ IsAssemblingFeature: 'pl7.app/vdj/isAssemblingFeature',
163
+ },
155
164
  } as const;
156
165
 
157
166
  export type Annotation = Metadata & Partial<{
158
- [Annotation.Alphabet]: 'nucleotide' | 'aminoacid' | string;
159
- [Annotation.AxisNature]: 'homogeneous' | 'heterogeneous' | 'scaleCompatible' | string;
167
+ [Annotation.Alphabet]: 'nucleotide' | 'aminoacid' | (string & {});
168
+ [Annotation.AxisNature]: 'homogeneous' | 'heterogeneous' | 'scaleCompatible' | (string & {});
160
169
  [Annotation.Description]: string;
161
170
  [Annotation.DiscreteValues]: StringifiedJson<number[]> | StringifiedJson<string[]>;
162
171
  [Annotation.Format]: string;
@@ -169,8 +178,8 @@ export type Annotation = Metadata & Partial<{
169
178
  [Annotation.Graph.Palette]: StringifiedJson<{ mapping: Record<string, number>; name: string }>;
170
179
  [Annotation.Graph.Thresholds]: StringifiedJson<{ columnId: { valueType: ValueType; name: string }; value: number }[]>;
171
180
  [Annotation.Graph.TreatAbsentValuesAs]: StringifiedJson<number>;
172
- [Annotation.HideDataFromUi]: StringifiedJson<boolean>;
173
181
  [Annotation.HideDataFromGraphs]: StringifiedJson<boolean>;
182
+ [Annotation.HideDataFromUi]: StringifiedJson<boolean>;
174
183
  [Annotation.IsDiscreteFilter]: StringifiedJson<boolean>;
175
184
  [Annotation.IsLinkerColumn]: StringifiedJson<boolean>;
176
185
  [Annotation.IsSubset]: StringifiedJson<boolean>;
@@ -183,8 +192,9 @@ export type Annotation = Metadata & Partial<{
183
192
  [Annotation.Sequence.IsAnnotation]: StringifiedJson<boolean>;
184
193
  [Annotation.Table.FontFamily]: string;
185
194
  [Annotation.Table.OrderPriority]: StringifiedJson<number>;
186
- [Annotation.Table.Visibility]: 'hidden' | 'optional' | string;
195
+ [Annotation.Table.Visibility]: 'hidden' | 'optional' | (string & {});
187
196
  [Annotation.Trace]: StringifiedJson<Record<string, unknown>>;
197
+ [Annotation.VDJ.IsAssemblingFeature]: StringifiedJson<boolean>;
188
198
  }>;
189
199
 
190
200
  // export const AxisSpec = z.object({
@@ -236,6 +246,7 @@ export const AnnotationJson: AnnotationJson = {
236
246
  [Annotation.Sequence.IsAnnotation]: z.boolean(),
237
247
  [Annotation.Table.OrderPriority]: z.number(),
238
248
  [Annotation.Trace]: z.record(z.string(), z.unknown()),
249
+ [Annotation.VDJ.IsAssemblingFeature]: z.boolean(),
239
250
  };
240
251
 
241
252
  /// Helper function for reading plain annotation values
@@ -503,6 +514,19 @@ export const PColumnName = {
503
514
  Table: {
504
515
  RowSelection: 'pl7.app/table/row-selection',
505
516
  },
517
+ VDJ: {
518
+ Sequence: 'pl7.app/vdj/sequence',
519
+ },
520
+ } as const;
521
+
522
+ /// Well-known axis names
523
+ export const PAxisName = {
524
+ VDJ: {
525
+ Assay: {
526
+ SequenceId: 'pl7.app/vdj/assay/sequenceId',
527
+ },
528
+ ScClonotypeKey: 'pl7.app/vdj/scClonotypeKey',
529
+ },
506
530
  } as const;
507
531
 
508
532
  export function isLabelColumn(column: PColumnSpec) {