@platforma-sdk/model 1.57.0 → 1.58.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.
- package/dist/block_model.cjs +17 -13
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +4 -4
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +17 -13
- package/dist/block_model.js.map +1 -1
- package/dist/block_model_legacy.cjs +1 -0
- package/dist/block_model_legacy.cjs.map +1 -1
- package/dist/block_model_legacy.d.ts.map +1 -1
- package/dist/block_model_legacy.js +1 -0
- package/dist/block_model_legacy.js.map +1 -1
- package/dist/block_storage.cjs +18 -14
- package/dist/block_storage.cjs.map +1 -1
- package/dist/block_storage.d.ts +14 -10
- package/dist/block_storage.d.ts.map +1 -1
- package/dist/block_storage.js +18 -14
- package/dist/block_storage.js.map +1 -1
- package/dist/block_storage_callbacks.cjs +3 -3
- package/dist/block_storage_callbacks.cjs.map +1 -1
- package/dist/block_storage_callbacks.d.ts +4 -3
- package/dist/block_storage_callbacks.d.ts.map +1 -1
- package/dist/block_storage_callbacks.js +3 -3
- package/dist/block_storage_callbacks.js.map +1 -1
- package/dist/components/PFrameForGraphs.cjs +0 -117
- package/dist/components/PFrameForGraphs.cjs.map +1 -1
- package/dist/components/PFrameForGraphs.d.ts +3 -5
- package/dist/components/PFrameForGraphs.d.ts.map +1 -1
- package/dist/components/PFrameForGraphs.js +2 -117
- package/dist/components/PFrameForGraphs.js.map +1 -1
- package/dist/components/PlDataTable/index.d.ts +1 -1
- package/dist/components/PlDataTable/index.d.ts.map +1 -1
- package/dist/components/PlDataTable/table.cjs +16 -1
- package/dist/components/PlDataTable/table.cjs.map +1 -1
- package/dist/components/PlDataTable/table.d.ts.map +1 -1
- package/dist/components/PlDataTable/table.js +16 -2
- package/dist/components/PlDataTable/table.js.map +1 -1
- package/dist/index.cjs +8 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/package.json.cjs +1 -1
- package/dist/package.json.js +1 -1
- package/dist/pframe_utils/axes.cjs +131 -0
- package/dist/pframe_utils/axes.cjs.map +1 -0
- package/dist/pframe_utils/axes.d.ts +15 -0
- package/dist/pframe_utils/axes.d.ts.map +1 -0
- package/dist/pframe_utils/axes.js +128 -0
- package/dist/pframe_utils/axes.js.map +1 -0
- package/dist/pframe_utils/columns.cjs +4 -7
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.js +1 -4
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +0 -2
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.js +0 -2
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts +12 -2
- package/dist/platforma.d.ts.map +1 -1
- package/dist/plugin_handle.cjs +29 -0
- package/dist/plugin_handle.cjs.map +1 -0
- package/dist/plugin_handle.d.ts +51 -0
- package/dist/plugin_handle.d.ts.map +1 -0
- package/dist/plugin_handle.js +25 -0
- package/dist/plugin_handle.js.map +1 -0
- package/dist/plugin_model.cjs +27 -27
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +41 -33
- package/dist/plugin_model.d.ts.map +1 -1
- package/dist/plugin_model.js +27 -27
- package/dist/plugin_model.js.map +1 -1
- package/dist/render/api.cjs +9 -5
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +11 -5
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +9 -5
- package/dist/render/api.js.map +1 -1
- package/package.json +5 -5
- package/src/block_model.ts +33 -19
- package/src/block_model_legacy.ts +1 -0
- package/src/block_storage.test.ts +3 -2
- package/src/block_storage.ts +30 -22
- package/src/block_storage_callbacks.ts +8 -7
- package/src/components/PFrameForGraphs.ts +4 -167
- package/src/components/PlDataTable/index.ts +6 -1
- package/src/components/PlDataTable/table.ts +3 -4
- package/src/index.ts +2 -1
- package/src/pframe_utils/axes.ts +175 -0
- package/src/pframe_utils/columns.ts +2 -2
- package/src/platforma.ts +17 -2
- package/src/plugin_handle.ts +85 -0
- package/src/plugin_model.ts +118 -56
- package/src/render/api.ts +21 -11
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PluginHandle — Opaque branded handle and output key utilities for plugin instances.
|
|
3
|
+
*
|
|
4
|
+
* Extracted into its own module to break circular dependencies:
|
|
5
|
+
* both block_storage.ts and plugin_model.ts can import from here
|
|
6
|
+
* without depending on each other.
|
|
7
|
+
*
|
|
8
|
+
* @module plugin_handle
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Branded } from "@milaboratories/helpers";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Phantom-only base type for constraining PluginHandle's type parameter.
|
|
15
|
+
*
|
|
16
|
+
* PluginFactory has create() → PluginModel with function properties, making it invariant
|
|
17
|
+
* under strictFunctionTypes. PluginFactoryLike exposes only the covariant `__types` phantom,
|
|
18
|
+
* avoiding the contravariance chain. Handles only need `__types` for type extraction.
|
|
19
|
+
*
|
|
20
|
+
* PluginFactory extends PluginFactoryLike, so every concrete factory satisfies this constraint.
|
|
21
|
+
*/
|
|
22
|
+
export interface PluginFactoryLike<
|
|
23
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
24
|
+
Params extends undefined | Record<string, unknown> = undefined | Record<string, unknown>,
|
|
25
|
+
Outputs extends Record<string, unknown> = Record<string, unknown>,
|
|
26
|
+
> {
|
|
27
|
+
readonly __types?: {
|
|
28
|
+
data: Data;
|
|
29
|
+
params: Params;
|
|
30
|
+
outputs: Outputs;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Extract the Data type from a PluginFactoryLike phantom. */
|
|
35
|
+
export type InferFactoryData<F extends PluginFactoryLike> = NonNullable<
|
|
36
|
+
F extends PluginFactoryLike<infer D, any, any> ? D : Record<string, unknown>
|
|
37
|
+
>;
|
|
38
|
+
|
|
39
|
+
/** Extract the Params type from a PluginFactoryLike phantom. */
|
|
40
|
+
export type InferFactoryParams<F extends PluginFactoryLike> = NonNullable<
|
|
41
|
+
F extends PluginFactoryLike<any, infer P, any> ? P : undefined
|
|
42
|
+
>;
|
|
43
|
+
|
|
44
|
+
/** Extract the Outputs type from a PluginFactoryLike phantom. */
|
|
45
|
+
export type InferFactoryOutputs<F extends PluginFactoryLike> = NonNullable<
|
|
46
|
+
F extends PluginFactoryLike<any, any, infer O> ? O : Record<string, unknown>
|
|
47
|
+
>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Derive a typed PluginHandle from a PluginFactory type.
|
|
51
|
+
* Normalizes the brand to only data/params/outputs (strips config) so handles
|
|
52
|
+
* from InferPluginHandles match handles from InferPluginHandle.
|
|
53
|
+
*/
|
|
54
|
+
export type InferPluginHandle<F extends PluginFactoryLike> = NonNullable<
|
|
55
|
+
F extends PluginFactoryLike<infer Data, infer Params, infer Outputs>
|
|
56
|
+
? PluginHandle<PluginFactoryLike<Data, Params, Outputs>>
|
|
57
|
+
: PluginHandle
|
|
58
|
+
>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Opaque handle for a plugin instance. Runtime value is the plugin instance ID string.
|
|
62
|
+
* Branded with factory phantom `F` for type-safe data/outputs extraction.
|
|
63
|
+
* Constrained with PluginFactoryLike (not PluginFactory) to avoid variance issues.
|
|
64
|
+
*/
|
|
65
|
+
export type PluginHandle<F extends PluginFactoryLike = PluginFactoryLike> = Branded<string, F>;
|
|
66
|
+
|
|
67
|
+
const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
|
|
68
|
+
|
|
69
|
+
/** Construct the output key for a plugin output in the block outputs map. */
|
|
70
|
+
export function pluginOutputKey<F extends PluginFactoryLike>(
|
|
71
|
+
handle: PluginHandle<F>,
|
|
72
|
+
outputKey: string,
|
|
73
|
+
): string {
|
|
74
|
+
return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Check whether an output key belongs to a plugin (vs block-level output). */
|
|
78
|
+
export function isPluginOutputKey(key: string): boolean {
|
|
79
|
+
return key.startsWith(PLUGIN_OUTPUT_PREFIX);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Get the prefix used for all outputs of a specific plugin instance. */
|
|
83
|
+
export function pluginOutputPrefix<F extends PluginFactoryLike>(handle: PluginHandle<F>): string {
|
|
84
|
+
return pluginOutputKey(handle, "");
|
|
85
|
+
}
|
package/src/plugin_model.ts
CHANGED
|
@@ -7,37 +7,52 @@
|
|
|
7
7
|
* @module plugin_model
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type { BlockCodeKnownFeatureFlags } from "@milaboratories/pl-model-common";
|
|
10
11
|
import type { DataModel } from "./block_migrations";
|
|
11
12
|
import type { PluginName } from "./block_storage";
|
|
13
|
+
import type { PluginFactoryLike } from "./plugin_handle";
|
|
12
14
|
import type { PluginRenderCtx } from "./render";
|
|
13
15
|
|
|
14
16
|
/** Symbol for internal builder creation method */
|
|
15
17
|
const FROM_BUILDER = Symbol("fromBuilder");
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
export type PluginData = Record<string, unknown>;
|
|
20
|
+
export type PluginParams = undefined | Record<string, unknown>;
|
|
21
|
+
export type PluginOutputs = Record<string, unknown>;
|
|
22
|
+
export type PluginConfig = undefined | Record<string, unknown>;
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Configured plugin instance returned by PluginModelFactory.create().
|
|
23
26
|
* Contains the plugin's name, data model, and output definitions.
|
|
24
27
|
*/
|
|
25
|
-
export class PluginModel<
|
|
28
|
+
export class PluginModel<
|
|
29
|
+
Data extends PluginData = PluginData,
|
|
30
|
+
Params extends PluginParams = undefined,
|
|
31
|
+
Outputs extends PluginOutputs = PluginOutputs,
|
|
32
|
+
> {
|
|
26
33
|
/** Globally unique plugin name */
|
|
27
34
|
readonly name: PluginName;
|
|
28
35
|
/** Data model instance for this plugin */
|
|
29
36
|
readonly dataModel: DataModel<Data>;
|
|
30
37
|
/** Output definitions - functions that compute outputs from plugin context */
|
|
31
|
-
readonly outputs: {
|
|
38
|
+
readonly outputs: {
|
|
39
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
40
|
+
};
|
|
41
|
+
/** Feature flags declared by this plugin */
|
|
42
|
+
readonly featureFlags?: BlockCodeKnownFeatureFlags;
|
|
32
43
|
|
|
33
|
-
private constructor(
|
|
44
|
+
private constructor(options: {
|
|
34
45
|
name: PluginName;
|
|
35
46
|
dataModel: DataModel<Data>;
|
|
36
|
-
outputs: {
|
|
47
|
+
outputs: {
|
|
48
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
49
|
+
};
|
|
50
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
37
51
|
}) {
|
|
38
|
-
this.name =
|
|
39
|
-
this.dataModel =
|
|
40
|
-
this.outputs =
|
|
52
|
+
this.name = options.name;
|
|
53
|
+
this.dataModel = options.dataModel;
|
|
54
|
+
this.outputs = options.outputs;
|
|
55
|
+
this.featureFlags = options.featureFlags;
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
/**
|
|
@@ -45,12 +60,19 @@ export class PluginModel<Data = unknown, Params = undefined, Outputs = {}> {
|
|
|
45
60
|
* Uses Symbol key to prevent external access.
|
|
46
61
|
* @internal
|
|
47
62
|
*/
|
|
48
|
-
static [FROM_BUILDER]<
|
|
63
|
+
static [FROM_BUILDER]<
|
|
64
|
+
Data extends PluginData,
|
|
65
|
+
Params extends PluginParams,
|
|
66
|
+
Outputs extends PluginOutputs,
|
|
67
|
+
>(options: {
|
|
49
68
|
name: PluginName;
|
|
50
|
-
dataModel: DataModel<
|
|
51
|
-
outputs: {
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
dataModel: DataModel<Data>;
|
|
70
|
+
outputs: {
|
|
71
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
72
|
+
};
|
|
73
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
74
|
+
}): PluginModel<Data, Params, Outputs> {
|
|
75
|
+
return new PluginModel<Data, Params, Outputs>(options);
|
|
54
76
|
}
|
|
55
77
|
|
|
56
78
|
/**
|
|
@@ -63,40 +85,66 @@ export class PluginModel<Data = unknown, Params = undefined, Outputs = {}> {
|
|
|
63
85
|
* @example
|
|
64
86
|
* const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);
|
|
65
87
|
*
|
|
66
|
-
* const myPlugin = PluginModel.define
|
|
88
|
+
* const myPlugin = PluginModel.define({
|
|
67
89
|
* name: 'myPlugin' as PluginName,
|
|
68
90
|
* data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),
|
|
69
91
|
* })
|
|
70
92
|
* .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)
|
|
71
93
|
* .build();
|
|
72
94
|
*/
|
|
73
|
-
static define<
|
|
95
|
+
static define<
|
|
96
|
+
Data extends PluginData,
|
|
97
|
+
Params extends PluginParams,
|
|
98
|
+
Config extends PluginConfig,
|
|
99
|
+
>(options: {
|
|
74
100
|
name: PluginName;
|
|
75
101
|
data: (config?: Config) => DataModel<Data>;
|
|
76
|
-
|
|
77
|
-
|
|
102
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
103
|
+
}): PluginModelBuilder<Data, Params, {}, Config> {
|
|
104
|
+
return PluginModelBuilder[FROM_BUILDER](options);
|
|
78
105
|
}
|
|
79
106
|
}
|
|
80
107
|
|
|
81
|
-
/**
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
108
|
+
/** Plugin factory returned by PluginModelBuilder.build(). */
|
|
109
|
+
export interface PluginFactory<
|
|
110
|
+
Data extends PluginData = PluginData,
|
|
111
|
+
Params extends PluginParams = undefined,
|
|
112
|
+
Outputs extends PluginOutputs = PluginOutputs,
|
|
113
|
+
Config extends PluginConfig = undefined,
|
|
114
|
+
> extends PluginFactoryLike {
|
|
115
|
+
create(config?: Config): PluginModel<Data, Params, Outputs>;
|
|
116
|
+
/**
|
|
117
|
+
* @internal Phantom field for structural type extraction.
|
|
118
|
+
* Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.
|
|
119
|
+
*/
|
|
120
|
+
readonly __types?: { data: Data; params: Params; outputs: Outputs; config: Config };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class PluginModelFactory<
|
|
124
|
+
Data extends PluginData = PluginData,
|
|
125
|
+
Params extends PluginParams = undefined,
|
|
126
|
+
Outputs extends PluginOutputs = PluginOutputs,
|
|
127
|
+
Config extends PluginConfig = undefined,
|
|
128
|
+
> implements PluginFactory<Data, Params, Outputs, Config> {
|
|
86
129
|
private readonly name: PluginName;
|
|
87
130
|
private readonly data: (config?: Config) => DataModel<Data>;
|
|
88
131
|
private readonly outputs: {
|
|
89
|
-
[K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params
|
|
132
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
90
133
|
};
|
|
134
|
+
private readonly featureFlags?: BlockCodeKnownFeatureFlags;
|
|
91
135
|
|
|
92
|
-
constructor(
|
|
136
|
+
constructor(options: {
|
|
93
137
|
name: PluginName;
|
|
94
138
|
data: (config?: Config) => DataModel<Data>;
|
|
95
|
-
outputs: {
|
|
139
|
+
outputs: {
|
|
140
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
141
|
+
};
|
|
142
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
96
143
|
}) {
|
|
97
|
-
this.name =
|
|
98
|
-
this.data =
|
|
99
|
-
this.outputs =
|
|
144
|
+
this.name = options.name;
|
|
145
|
+
this.data = options.data;
|
|
146
|
+
this.outputs = options.outputs;
|
|
147
|
+
this.featureFlags = options.featureFlags;
|
|
100
148
|
}
|
|
101
149
|
|
|
102
150
|
/** Create a configured PluginModel instance */
|
|
@@ -105,14 +153,11 @@ class PluginModelFactory<Data, Params, Config, Outputs> {
|
|
|
105
153
|
name: this.name,
|
|
106
154
|
dataModel: this.data(config),
|
|
107
155
|
outputs: this.outputs,
|
|
156
|
+
featureFlags: this.featureFlags,
|
|
108
157
|
});
|
|
109
158
|
}
|
|
110
159
|
}
|
|
111
160
|
|
|
112
|
-
// =============================================================================
|
|
113
|
-
// Plugin Model Builder
|
|
114
|
-
// =============================================================================
|
|
115
|
-
|
|
116
161
|
/**
|
|
117
162
|
* Builder for creating PluginType with type-safe output definitions.
|
|
118
163
|
*
|
|
@@ -136,27 +181,34 @@ class PluginModelFactory<Data, Params, Config, Outputs> {
|
|
|
136
181
|
* .build();
|
|
137
182
|
*/
|
|
138
183
|
class PluginModelBuilder<
|
|
139
|
-
Data,
|
|
140
|
-
Params = undefined,
|
|
141
|
-
|
|
142
|
-
|
|
184
|
+
Data extends PluginData = PluginData,
|
|
185
|
+
Params extends PluginParams = undefined,
|
|
186
|
+
Outputs extends PluginOutputs = PluginOutputs,
|
|
187
|
+
Config extends PluginConfig = undefined,
|
|
143
188
|
> {
|
|
144
189
|
private readonly name: PluginName;
|
|
145
190
|
private readonly data: (config?: Config) => DataModel<Data>;
|
|
146
191
|
private readonly outputs: {
|
|
147
|
-
[K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params
|
|
192
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
148
193
|
};
|
|
194
|
+
private readonly featureFlags?: BlockCodeKnownFeatureFlags;
|
|
149
195
|
|
|
150
|
-
private constructor(
|
|
196
|
+
private constructor(options: {
|
|
151
197
|
name: PluginName;
|
|
152
198
|
data: (config?: Config) => DataModel<Data>;
|
|
153
|
-
outputs?: {
|
|
199
|
+
outputs?: {
|
|
200
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
201
|
+
};
|
|
202
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
154
203
|
}) {
|
|
155
|
-
this.name =
|
|
156
|
-
this.data =
|
|
204
|
+
this.name = options.name;
|
|
205
|
+
this.data = options.data;
|
|
157
206
|
this.outputs =
|
|
158
|
-
|
|
159
|
-
({} as {
|
|
207
|
+
options.outputs ??
|
|
208
|
+
({} as {
|
|
209
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
210
|
+
});
|
|
211
|
+
this.featureFlags = options.featureFlags;
|
|
160
212
|
}
|
|
161
213
|
|
|
162
214
|
/**
|
|
@@ -164,12 +216,20 @@ class PluginModelBuilder<
|
|
|
164
216
|
* Uses Symbol key to prevent external access.
|
|
165
217
|
* @internal
|
|
166
218
|
*/
|
|
167
|
-
static [FROM_BUILDER]<
|
|
219
|
+
static [FROM_BUILDER]<
|
|
220
|
+
Data extends PluginData,
|
|
221
|
+
Params extends PluginParams,
|
|
222
|
+
Outputs extends PluginOutputs,
|
|
223
|
+
Config extends PluginConfig,
|
|
224
|
+
>(options: {
|
|
168
225
|
name: PluginName;
|
|
169
|
-
data: (config?:
|
|
170
|
-
outputs?: {
|
|
171
|
-
|
|
172
|
-
|
|
226
|
+
data: (config?: Config) => DataModel<Data>;
|
|
227
|
+
outputs?: {
|
|
228
|
+
[K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
|
|
229
|
+
};
|
|
230
|
+
featureFlags?: BlockCodeKnownFeatureFlags;
|
|
231
|
+
}): PluginModelBuilder<Data, Params, Outputs, Config> {
|
|
232
|
+
return new PluginModelBuilder(options);
|
|
173
233
|
}
|
|
174
234
|
|
|
175
235
|
/**
|
|
@@ -185,17 +245,18 @@ class PluginModelBuilder<
|
|
|
185
245
|
*/
|
|
186
246
|
output<const Key extends string, T>(
|
|
187
247
|
key: Key,
|
|
188
|
-
fn: (ctx: PluginRenderCtx<Data, Params
|
|
189
|
-
): PluginModelBuilder<Data, Params,
|
|
190
|
-
return new PluginModelBuilder<Data, Params,
|
|
248
|
+
fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T,
|
|
249
|
+
): PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config> {
|
|
250
|
+
return new PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config>({
|
|
191
251
|
name: this.name,
|
|
192
252
|
data: this.data,
|
|
253
|
+
featureFlags: this.featureFlags,
|
|
193
254
|
outputs: {
|
|
194
255
|
...this.outputs,
|
|
195
256
|
[key]: fn,
|
|
196
257
|
} as {
|
|
197
258
|
[K in keyof (Outputs & { [P in Key]: T })]: (
|
|
198
|
-
ctx: PluginRenderCtx<Data, Params
|
|
259
|
+
ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>,
|
|
199
260
|
) => (Outputs & { [P in Key]: T })[K];
|
|
200
261
|
},
|
|
201
262
|
});
|
|
@@ -214,11 +275,12 @@ class PluginModelBuilder<
|
|
|
214
275
|
* // Later, call create() with config to get a configured instance:
|
|
215
276
|
* const configured = myPlugin.create({ defaultValue: 'test' });
|
|
216
277
|
*/
|
|
217
|
-
build():
|
|
218
|
-
return new PluginModelFactory<Data, Params,
|
|
278
|
+
build(): PluginFactory<Data, Params, Outputs, Config> {
|
|
279
|
+
return new PluginModelFactory<Data, Params, Outputs, Config>({
|
|
219
280
|
name: this.name,
|
|
220
281
|
data: this.data,
|
|
221
282
|
outputs: this.outputs,
|
|
283
|
+
featureFlags: this.featureFlags,
|
|
222
284
|
});
|
|
223
285
|
}
|
|
224
286
|
}
|
package/src/render/api.ts
CHANGED
|
@@ -50,6 +50,12 @@ import canonicalize from "canonicalize";
|
|
|
50
50
|
import type { Optional } from "utility-types";
|
|
51
51
|
import { getCfgRenderCtx } from "../internal";
|
|
52
52
|
import { getPluginData } from "../block_storage";
|
|
53
|
+
import type {
|
|
54
|
+
PluginHandle,
|
|
55
|
+
PluginFactoryLike,
|
|
56
|
+
InferFactoryData,
|
|
57
|
+
InferFactoryParams,
|
|
58
|
+
} from "../plugin_handle";
|
|
53
59
|
import { TreeNodeAccessor, ifDef } from "./accessor";
|
|
54
60
|
import type { FutureRef } from "./future";
|
|
55
61
|
import type { AccessorHandle, GlobalCfgRenderCtx } from "./internal";
|
|
@@ -756,40 +762,44 @@ export class RenderCtxLegacy<Args = unknown, UiState = unknown> extends RenderCt
|
|
|
756
762
|
/**
|
|
757
763
|
* Render context for plugin output functions.
|
|
758
764
|
* Reads plugin data from blockStorage and derives params from pre-wrapped input callbacks.
|
|
765
|
+
*
|
|
766
|
+
* Parameterized on the factory-like phantom F so that getPluginData returns
|
|
767
|
+
* InferFactoryData<F> directly — no casts needed for the data getter.
|
|
768
|
+
*
|
|
769
|
+
* @typeParam F - PluginFactoryLike phantom carrying data/params/outputs types
|
|
759
770
|
*/
|
|
760
|
-
export class PluginRenderCtx<
|
|
771
|
+
export class PluginRenderCtx<F extends PluginFactoryLike = PluginFactoryLike> {
|
|
761
772
|
private readonly ctx: GlobalCfgRenderCtx;
|
|
762
|
-
private readonly
|
|
773
|
+
private readonly handle: PluginHandle<F>;
|
|
763
774
|
private readonly wrappedInputs: Record<string, () => unknown>;
|
|
764
775
|
|
|
765
|
-
constructor(
|
|
776
|
+
constructor(handle: PluginHandle<F>, wrappedInputs: Record<string, () => unknown>) {
|
|
766
777
|
this.ctx = getCfgRenderCtx();
|
|
767
|
-
this.
|
|
778
|
+
this.handle = handle;
|
|
768
779
|
this.wrappedInputs = wrappedInputs;
|
|
769
780
|
}
|
|
770
781
|
|
|
771
|
-
private dataCache?: { v:
|
|
782
|
+
private dataCache?: { v: InferFactoryData<F> };
|
|
772
783
|
|
|
773
784
|
/** Plugin's persistent data from blockStorage.__plugins.{pluginId}.__data */
|
|
774
|
-
public get data():
|
|
785
|
+
public get data(): InferFactoryData<F> {
|
|
775
786
|
if (this.dataCache === undefined) {
|
|
776
787
|
const raw = this.ctx.blockStorage();
|
|
777
|
-
|
|
778
|
-
this.dataCache = { v: pluginData };
|
|
788
|
+
this.dataCache = { v: getPluginData(parseJson(raw), this.handle) };
|
|
779
789
|
}
|
|
780
790
|
return this.dataCache.v;
|
|
781
791
|
}
|
|
782
792
|
|
|
783
|
-
private paramsCache?: { v:
|
|
793
|
+
private paramsCache?: { v: InferFactoryParams<F> };
|
|
784
794
|
|
|
785
795
|
/** Params derived from block context via pre-wrapped input callbacks */
|
|
786
|
-
public get params():
|
|
796
|
+
public get params(): InferFactoryParams<F> {
|
|
787
797
|
if (this.paramsCache === undefined) {
|
|
788
798
|
const result: Record<string, unknown> = {};
|
|
789
799
|
for (const [key, fn] of Object.entries(this.wrappedInputs)) {
|
|
790
800
|
result[key] = fn();
|
|
791
801
|
}
|
|
792
|
-
this.paramsCache = { v: result as
|
|
802
|
+
this.paramsCache = { v: result as InferFactoryParams<F> };
|
|
793
803
|
}
|
|
794
804
|
return this.paramsCache.v;
|
|
795
805
|
}
|