@platforma-sdk/model 1.57.2 → 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.
Files changed (85) hide show
  1. package/dist/block_model.cjs +17 -13
  2. package/dist/block_model.cjs.map +1 -1
  3. package/dist/block_model.d.ts +4 -4
  4. package/dist/block_model.d.ts.map +1 -1
  5. package/dist/block_model.js +17 -13
  6. package/dist/block_model.js.map +1 -1
  7. package/dist/block_model_legacy.cjs +1 -0
  8. package/dist/block_model_legacy.cjs.map +1 -1
  9. package/dist/block_model_legacy.d.ts.map +1 -1
  10. package/dist/block_model_legacy.js +1 -0
  11. package/dist/block_model_legacy.js.map +1 -1
  12. package/dist/block_storage.cjs +18 -14
  13. package/dist/block_storage.cjs.map +1 -1
  14. package/dist/block_storage.d.ts +14 -10
  15. package/dist/block_storage.d.ts.map +1 -1
  16. package/dist/block_storage.js +18 -14
  17. package/dist/block_storage.js.map +1 -1
  18. package/dist/block_storage_callbacks.cjs +3 -3
  19. package/dist/block_storage_callbacks.cjs.map +1 -1
  20. package/dist/block_storage_callbacks.d.ts +4 -3
  21. package/dist/block_storage_callbacks.d.ts.map +1 -1
  22. package/dist/block_storage_callbacks.js +3 -3
  23. package/dist/block_storage_callbacks.js.map +1 -1
  24. package/dist/components/PFrameForGraphs.cjs +0 -117
  25. package/dist/components/PFrameForGraphs.cjs.map +1 -1
  26. package/dist/components/PFrameForGraphs.d.ts +3 -5
  27. package/dist/components/PFrameForGraphs.d.ts.map +1 -1
  28. package/dist/components/PFrameForGraphs.js +2 -117
  29. package/dist/components/PFrameForGraphs.js.map +1 -1
  30. package/dist/index.cjs +7 -2
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +3 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/package.json.cjs +1 -1
  37. package/dist/package.json.js +1 -1
  38. package/dist/pframe_utils/axes.cjs +131 -0
  39. package/dist/pframe_utils/axes.cjs.map +1 -0
  40. package/dist/pframe_utils/axes.d.ts +15 -0
  41. package/dist/pframe_utils/axes.d.ts.map +1 -0
  42. package/dist/pframe_utils/axes.js +128 -0
  43. package/dist/pframe_utils/axes.js.map +1 -0
  44. package/dist/pframe_utils/columns.cjs +4 -8
  45. package/dist/pframe_utils/columns.cjs.map +1 -1
  46. package/dist/pframe_utils/columns.js +1 -5
  47. package/dist/pframe_utils/columns.js.map +1 -1
  48. package/dist/pframe_utils/index.cjs +0 -3
  49. package/dist/pframe_utils/index.cjs.map +1 -1
  50. package/dist/pframe_utils/index.js +0 -3
  51. package/dist/pframe_utils/index.js.map +1 -1
  52. package/dist/platforma.d.ts +12 -2
  53. package/dist/platforma.d.ts.map +1 -1
  54. package/dist/plugin_handle.cjs +29 -0
  55. package/dist/plugin_handle.cjs.map +1 -0
  56. package/dist/plugin_handle.d.ts +51 -0
  57. package/dist/plugin_handle.d.ts.map +1 -0
  58. package/dist/plugin_handle.js +25 -0
  59. package/dist/plugin_handle.js.map +1 -0
  60. package/dist/plugin_model.cjs +27 -27
  61. package/dist/plugin_model.cjs.map +1 -1
  62. package/dist/plugin_model.d.ts +41 -33
  63. package/dist/plugin_model.d.ts.map +1 -1
  64. package/dist/plugin_model.js +27 -27
  65. package/dist/plugin_model.js.map +1 -1
  66. package/dist/render/api.cjs +9 -5
  67. package/dist/render/api.cjs.map +1 -1
  68. package/dist/render/api.d.ts +11 -5
  69. package/dist/render/api.d.ts.map +1 -1
  70. package/dist/render/api.js +9 -5
  71. package/dist/render/api.js.map +1 -1
  72. package/package.json +5 -5
  73. package/src/block_model.ts +33 -19
  74. package/src/block_model_legacy.ts +1 -0
  75. package/src/block_storage.test.ts +3 -2
  76. package/src/block_storage.ts +30 -22
  77. package/src/block_storage_callbacks.ts +8 -7
  78. package/src/components/PFrameForGraphs.ts +4 -167
  79. package/src/index.ts +2 -1
  80. package/src/pframe_utils/axes.ts +175 -0
  81. package/src/pframe_utils/columns.ts +2 -2
  82. package/src/platforma.ts +17 -2
  83. package/src/plugin_handle.ts +85 -0
  84. package/src/plugin_model.ts +118 -56
  85. package/src/render/api.ts +21 -11
@@ -10,9 +10,6 @@
10
10
  */
11
11
  /** Symbol for internal builder creation method */
12
12
  const FROM_BUILDER = Symbol("fromBuilder");
13
- // =============================================================================
14
- // Plugin Type
15
- // =============================================================================
16
13
  /**
17
14
  * Configured plugin instance returned by PluginModelFactory.create().
18
15
  * Contains the plugin's name, data model, and output definitions.
@@ -24,18 +21,21 @@ class PluginModel {
24
21
  dataModel;
25
22
  /** Output definitions - functions that compute outputs from plugin context */
26
23
  outputs;
27
- constructor(input) {
28
- this.name = input.name;
29
- this.dataModel = input.dataModel;
30
- this.outputs = input.outputs;
24
+ /** Feature flags declared by this plugin */
25
+ featureFlags;
26
+ constructor(options) {
27
+ this.name = options.name;
28
+ this.dataModel = options.dataModel;
29
+ this.outputs = options.outputs;
30
+ this.featureFlags = options.featureFlags;
31
31
  }
32
32
  /**
33
33
  * Internal method for creating PluginModel from factory.
34
34
  * Uses Symbol key to prevent external access.
35
35
  * @internal
36
36
  */
37
- static [FROM_BUILDER](input) {
38
- return new this(input);
37
+ static [FROM_BUILDER](options) {
38
+ return new PluginModel(options);
39
39
  }
40
40
  /**
41
41
  * Creates a new PluginModelBuilder for building plugin definitions.
@@ -47,7 +47,7 @@ class PluginModel {
47
47
  * @example
48
48
  * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);
49
49
  *
50
- * const myPlugin = PluginModel.define<MyData, MyParams, MyConfig>({
50
+ * const myPlugin = PluginModel.define({
51
51
  * name: 'myPlugin' as PluginName,
52
52
  * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),
53
53
  * })
@@ -58,18 +58,16 @@ class PluginModel {
58
58
  return PluginModelBuilder[FROM_BUILDER](options);
59
59
  }
60
60
  }
61
- /**
62
- * Plugin factory returned by PluginModelBuilder.build().
63
- * Call create() with config to get a configured PluginModel instance.
64
- */
65
61
  class PluginModelFactory {
66
62
  name;
67
63
  data;
68
64
  outputs;
69
- constructor(input) {
70
- this.name = input.name;
71
- this.data = input.data;
72
- this.outputs = input.outputs;
65
+ featureFlags;
66
+ constructor(options) {
67
+ this.name = options.name;
68
+ this.data = options.data;
69
+ this.outputs = options.outputs;
70
+ this.featureFlags = options.featureFlags;
73
71
  }
74
72
  /** Create a configured PluginModel instance */
75
73
  create(config) {
@@ -77,12 +75,10 @@ class PluginModelFactory {
77
75
  name: this.name,
78
76
  dataModel: this.data(config),
79
77
  outputs: this.outputs,
78
+ featureFlags: this.featureFlags,
80
79
  });
81
80
  }
82
81
  }
83
- // =============================================================================
84
- // Plugin Model Builder
85
- // =============================================================================
86
82
  /**
87
83
  * Builder for creating PluginType with type-safe output definitions.
88
84
  *
@@ -109,20 +105,22 @@ class PluginModelBuilder {
109
105
  name;
110
106
  data;
111
107
  outputs;
112
- constructor(input) {
113
- this.name = input.name;
114
- this.data = input.data;
108
+ featureFlags;
109
+ constructor(options) {
110
+ this.name = options.name;
111
+ this.data = options.data;
115
112
  this.outputs =
116
- input.outputs ??
113
+ options.outputs ??
117
114
  {};
115
+ this.featureFlags = options.featureFlags;
118
116
  }
119
117
  /**
120
118
  * Internal method for creating PluginModelBuilder.
121
119
  * Uses Symbol key to prevent external access.
122
120
  * @internal
123
121
  */
124
- static [FROM_BUILDER](input) {
125
- return new this(input);
122
+ static [FROM_BUILDER](options) {
123
+ return new PluginModelBuilder(options);
126
124
  }
127
125
  /**
128
126
  * Adds an output to the plugin.
@@ -139,6 +137,7 @@ class PluginModelBuilder {
139
137
  return new PluginModelBuilder({
140
138
  name: this.name,
141
139
  data: this.data,
140
+ featureFlags: this.featureFlags,
142
141
  outputs: {
143
142
  ...this.outputs,
144
143
  [key]: fn,
@@ -163,6 +162,7 @@ class PluginModelBuilder {
163
162
  name: this.name,
164
163
  data: this.data,
165
164
  outputs: this.outputs,
165
+ featureFlags: this.featureFlags,
166
166
  });
167
167
  }
168
168
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.cjs","sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { DataModel } from \"./block_migrations\";\nimport type { PluginName } from \"./block_storage\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n// =============================================================================\n// Plugin Type\n// =============================================================================\n\n/**\n * Configured plugin instance returned by PluginModelFactory.create().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<Data = unknown, Params = undefined, Outputs = {}> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n\n private constructor(input: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.dataModel = input.dataModel;\n this.outputs = input.outputs;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<D, P, O>(input: {\n name: PluginName;\n dataModel: DataModel<D>;\n outputs: { [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K] };\n }): PluginModel<D, P, O> {\n return new this<D, P, O>(input);\n }\n\n /**\n * Creates a new PluginModelBuilder for building plugin definitions.\n *\n * @param options.name - Globally unique plugin name\n * @param options.data - Factory function that creates the data model from config\n * @returns PluginModelBuilder for chaining output definitions\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const myPlugin = PluginModel.define<MyData, MyParams, MyConfig>({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * })\n * .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)\n * .build();\n */\n static define<Data, Params = undefined, Config = undefined>(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n }): PluginModelBuilder<Data, Params, Config> {\n return PluginModelBuilder[FROM_BUILDER]<Data, Params, Config>(options);\n }\n}\n\n/**\n * Plugin factory returned by PluginModelBuilder.build().\n * Call create() with config to get a configured PluginModel instance.\n */\nclass PluginModelFactory<Data, Params, Config, Outputs> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];\n };\n\n constructor(input: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.data = input.data;\n this.outputs = input.outputs;\n }\n\n /** Create a configured PluginModel instance */\n create(config?: Config): PluginModel<Data, Params, Outputs> {\n return PluginModel[FROM_BUILDER]<Data, Params, Outputs>({\n name: this.name,\n dataModel: this.data(config),\n outputs: this.outputs,\n });\n }\n}\n\n// =============================================================================\n// Plugin Model Builder\n// =============================================================================\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<TableData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const dataTable = PluginModel.define<TableData, TableParams, TableConfig>({\n * name: 'dataTable' as PluginName,\n * data: (cfg) => {\n * return dataModelChain.init(() => ({ state: createInitialState(cfg.ops) }));\n * },\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data,\n Params = undefined,\n Config = undefined,\n Outputs extends Record<string, unknown> = {},\n> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];\n };\n\n private constructor(input: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.data = input.data;\n this.outputs =\n input.outputs ??\n ({} as { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] });\n }\n\n /**\n * Internal method for creating PluginModelBuilder.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<D, P, C, O extends Record<string, unknown> = {}>(input: {\n name: PluginName;\n data: (config?: C) => DataModel<D>;\n outputs?: { [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K] };\n }): PluginModelBuilder<D, P, C, O> {\n return new this<D, P, C, O>(input);\n }\n\n /**\n * Adds an output to the plugin.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns PluginModel with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('isReady', (ctx) => ctx.params.columns !== undefined)\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (ctx: PluginRenderCtx<Data, Params>) => T,\n ): PluginModelBuilder<Data, Params, Config, Outputs & { [K in Key]: T }> {\n return new PluginModelBuilder<Data, Params, Config, Outputs & { [K in Key]: T }>({\n name: this.name,\n data: this.data,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as {\n [K in keyof (Outputs & { [P in Key]: T })]: (\n ctx: PluginRenderCtx<Data, Params>,\n ) => (Outputs & { [P in Key]: T })[K];\n },\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a ConfigurablePluginModel.\n *\n * @returns Callable plugin factory that accepts config and returns PluginModel\n *\n * @example\n * const myPlugin = new PluginModelBuilder('myPlugin', () => dataModel)\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Later, call create() with config to get a configured instance:\n * const configured = myPlugin.create({ defaultValue: 'test' });\n */\n build(): PluginModelFactory<Data, Params, Config, Outputs> {\n return new PluginModelFactory<Data, Params, Config, Outputs>({\n name: this.name,\n data: this.data,\n outputs: this.outputs,\n });\n }\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;AAOG;AAMH;AACA,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;AAE1C;AACA;AACA;AAEA;;;AAGG;MACU,WAAW,CAAA;;AAEb,IAAA,IAAI;;AAEJ,IAAA,SAAS;;AAET,IAAA,OAAO;AAEhB,IAAA,WAAA,CAAoB,KAInB,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;AAChC,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO;IAC9B;AAEA;;;;AAIG;AACH,IAAA,QAAQ,YAAY,CAAC,CAAU,KAI9B,EAAA;AACC,QAAA,OAAO,IAAI,IAAI,CAAU,KAAK,CAAC;IACjC;AAEA;;;;;;;;;;;;;;;;AAgBG;IACH,OAAO,MAAM,CAA+C,OAG3D,EAAA;AACC,QAAA,OAAO,kBAAkB,CAAC,YAAY,CAAC,CAAuB,OAAO,CAAC;IACxE;AACD;AAED;;;AAGG;AACH,MAAM,kBAAkB,CAAA;AACL,IAAA,IAAI;AACJ,IAAA,IAAI;AACJ,IAAA,OAAO;AAIxB,IAAA,WAAA,CAAY,KAIX,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO;IAC9B;;AAGA,IAAA,MAAM,CAAC,MAAe,EAAA;AACpB,QAAA,OAAO,WAAW,CAAC,YAAY,CAAC,CAAwB;YACtD,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;AACtB,SAAA,CAAC;IACJ;AACD;AAED;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACH,MAAM,kBAAkB,CAAA;AAML,IAAA,IAAI;AACJ,IAAA,IAAI;AACJ,IAAA,OAAO;AAIxB,IAAA,WAAA,CAAoB,KAInB,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,OAAO;AACV,YAAA,KAAK,CAAC,OAAO;AACZ,gBAAA,EAAmF;IACxF;AAEA;;;;AAIG;AACH,IAAA,QAAQ,YAAY,CAAC,CAAkD,KAItE,EAAA;AACC,QAAA,OAAO,IAAI,IAAI,CAAa,KAAK,CAAC;IACpC;AAEA;;;;;;;;;;AAUG;IACH,MAAM,CACJ,GAAQ,EACR,EAA6C,EAAA;QAE7C,OAAO,IAAI,kBAAkB,CAAoD;YAC/E,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,OAAO,EAAE;gBACP,GAAG,IAAI,CAAC,OAAO;gBACf,CAAC,GAAG,GAAG,EAAE;AAKV,aAAA;AACF,SAAA,CAAC;IACJ;AAEA;;;;;;;;;;;;AAYG;IACH,KAAK,GAAA;QACH,OAAO,IAAI,kBAAkB,CAAgC;YAC3D,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;AACtB,SAAA,CAAC;IACJ;AACD;;;;"}
1
+ {"version":3,"file":"plugin_model.cjs","sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags } from \"@milaboratories/pl-model-common\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PluginName } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Configured plugin instance returned by PluginModelFactory.create().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModel<Data, Params, Outputs> {\n return new PluginModel<Data, Params, Outputs>(options);\n }\n\n /**\n * Creates a new PluginModelBuilder for building plugin definitions.\n *\n * @param options.name - Globally unique plugin name\n * @param options.data - Factory function that creates the data model from config\n * @returns PluginModelBuilder for chaining output definitions\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * })\n * .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)\n * .build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams,\n Config extends PluginConfig,\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelBuilder<Data, Params, {}, Config> {\n return PluginModelBuilder[FROM_BUILDER](options);\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> extends PluginFactoryLike {\n create(config?: Config): PluginModel<Data, Params, Outputs>;\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: { data: Data; params: Params; outputs: Outputs; config: Config };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> implements PluginFactory<Data, Params, Outputs, Config> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n constructor(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.data = options.data;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n }\n\n /** Create a configured PluginModel instance */\n create(config?: Config): PluginModel<Data, Params, Outputs> {\n return PluginModel[FROM_BUILDER]<Data, Params, Outputs>({\n name: this.name,\n dataModel: this.data(config),\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<TableData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const dataTable = PluginModel.define<TableData, TableParams, TableConfig>({\n * name: 'dataTable' as PluginName,\n * data: (cfg) => {\n * return dataModelChain.init(() => ({ state: createInitialState(cfg.ops) }));\n * },\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n private constructor(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.data = options.data;\n this.outputs =\n options.outputs ??\n ({} as {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n });\n this.featureFlags = options.featureFlags;\n }\n\n /**\n * Internal method for creating PluginModelBuilder.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n Config extends PluginConfig,\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelBuilder<Data, Params, Outputs, Config> {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns PluginModel with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('isReady', (ctx) => ctx.params.columns !== undefined)\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T,\n ): PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config> {\n return new PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config>({\n name: this.name,\n data: this.data,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as {\n [K in keyof (Outputs & { [P in Key]: T })]: (\n ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>,\n ) => (Outputs & { [P in Key]: T })[K];\n },\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a ConfigurablePluginModel.\n *\n * @returns Callable plugin factory that accepts config and returns PluginModel\n *\n * @example\n * const myPlugin = new PluginModelBuilder('myPlugin', () => dataModel)\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Later, call create() with config to get a configured instance:\n * const configured = myPlugin.create({ defaultValue: 'test' });\n */\n build(): PluginFactory<Data, Params, Outputs, Config> {\n return new PluginModelFactory<Data, Params, Outputs, Config>({\n name: this.name,\n data: this.data,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -6,37 +6,46 @@
6
6
  *
7
7
  * @module plugin_model
8
8
  */
9
+ import type { BlockCodeKnownFeatureFlags } from "@milaboratories/pl-model-common";
9
10
  import type { DataModel } from "./block_migrations";
10
11
  import type { PluginName } from "./block_storage";
12
+ import type { PluginFactoryLike } from "./plugin_handle";
11
13
  import type { PluginRenderCtx } from "./render";
12
14
  /** Symbol for internal builder creation method */
13
15
  declare const FROM_BUILDER: unique symbol;
16
+ export type PluginData = Record<string, unknown>;
17
+ export type PluginParams = undefined | Record<string, unknown>;
18
+ export type PluginOutputs = Record<string, unknown>;
19
+ export type PluginConfig = undefined | Record<string, unknown>;
14
20
  /**
15
21
  * Configured plugin instance returned by PluginModelFactory.create().
16
22
  * Contains the plugin's name, data model, and output definitions.
17
23
  */
18
- export declare class PluginModel<Data = unknown, Params = undefined, Outputs = {}> {
24
+ export declare class PluginModel<Data extends PluginData = PluginData, Params extends PluginParams = undefined, Outputs extends PluginOutputs = PluginOutputs> {
19
25
  /** Globally unique plugin name */
20
26
  readonly name: PluginName;
21
27
  /** Data model instance for this plugin */
22
28
  readonly dataModel: DataModel<Data>;
23
29
  /** Output definitions - functions that compute outputs from plugin context */
24
30
  readonly outputs: {
25
- [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];
31
+ [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
26
32
  };
33
+ /** Feature flags declared by this plugin */
34
+ readonly featureFlags?: BlockCodeKnownFeatureFlags;
27
35
  private constructor();
28
36
  /**
29
37
  * Internal method for creating PluginModel from factory.
30
38
  * Uses Symbol key to prevent external access.
31
39
  * @internal
32
40
  */
33
- static [FROM_BUILDER]<D, P, O>(input: {
41
+ static [FROM_BUILDER]<Data extends PluginData, Params extends PluginParams, Outputs extends PluginOutputs>(options: {
34
42
  name: PluginName;
35
- dataModel: DataModel<D>;
43
+ dataModel: DataModel<Data>;
36
44
  outputs: {
37
- [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K];
45
+ [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
38
46
  };
39
- }): PluginModel<D, P, O>;
47
+ featureFlags?: BlockCodeKnownFeatureFlags;
48
+ }): PluginModel<Data, Params, Outputs>;
40
49
  /**
41
50
  * Creates a new PluginModelBuilder for building plugin definitions.
42
51
  *
@@ -47,35 +56,32 @@ export declare class PluginModel<Data = unknown, Params = undefined, Outputs = {
47
56
  * @example
48
57
  * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);
49
58
  *
50
- * const myPlugin = PluginModel.define<MyData, MyParams, MyConfig>({
59
+ * const myPlugin = PluginModel.define({
51
60
  * name: 'myPlugin' as PluginName,
52
61
  * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),
53
62
  * })
54
63
  * .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)
55
64
  * .build();
56
65
  */
57
- static define<Data, Params = undefined, Config = undefined>(options: {
66
+ static define<Data extends PluginData, Params extends PluginParams, Config extends PluginConfig>(options: {
58
67
  name: PluginName;
59
68
  data: (config?: Config) => DataModel<Data>;
60
- }): PluginModelBuilder<Data, Params, Config>;
69
+ featureFlags?: BlockCodeKnownFeatureFlags;
70
+ }): PluginModelBuilder<Data, Params, {}, Config>;
61
71
  }
62
- /**
63
- * Plugin factory returned by PluginModelBuilder.build().
64
- * Call create() with config to get a configured PluginModel instance.
65
- */
66
- declare class PluginModelFactory<Data, Params, Config, Outputs> {
67
- private readonly name;
68
- private readonly data;
69
- private readonly outputs;
70
- constructor(input: {
71
- name: PluginName;
72
- data: (config?: Config) => DataModel<Data>;
73
- outputs: {
74
- [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];
75
- };
76
- });
77
- /** Create a configured PluginModel instance */
72
+ /** Plugin factory returned by PluginModelBuilder.build(). */
73
+ export interface PluginFactory<Data extends PluginData = PluginData, Params extends PluginParams = undefined, Outputs extends PluginOutputs = PluginOutputs, Config extends PluginConfig = undefined> extends PluginFactoryLike {
78
74
  create(config?: Config): PluginModel<Data, Params, Outputs>;
75
+ /**
76
+ * @internal Phantom field for structural type extraction.
77
+ * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.
78
+ */
79
+ readonly __types?: {
80
+ data: Data;
81
+ params: Params;
82
+ outputs: Outputs;
83
+ config: Config;
84
+ };
79
85
  }
80
86
  /**
81
87
  * Builder for creating PluginType with type-safe output definitions.
@@ -99,23 +105,25 @@ declare class PluginModelFactory<Data, Params, Config, Outputs> {
99
105
  * .output('model', (ctx) => createTableModel(ctx))
100
106
  * .build();
101
107
  */
102
- declare class PluginModelBuilder<Data, Params = undefined, Config = undefined, Outputs extends Record<string, unknown> = {}> {
108
+ declare class PluginModelBuilder<Data extends PluginData = PluginData, Params extends PluginParams = undefined, Outputs extends PluginOutputs = PluginOutputs, Config extends PluginConfig = undefined> {
103
109
  private readonly name;
104
110
  private readonly data;
105
111
  private readonly outputs;
112
+ private readonly featureFlags?;
106
113
  private constructor();
107
114
  /**
108
115
  * Internal method for creating PluginModelBuilder.
109
116
  * Uses Symbol key to prevent external access.
110
117
  * @internal
111
118
  */
112
- static [FROM_BUILDER]<D, P, C, O extends Record<string, unknown> = {}>(input: {
119
+ static [FROM_BUILDER]<Data extends PluginData, Params extends PluginParams, Outputs extends PluginOutputs, Config extends PluginConfig>(options: {
113
120
  name: PluginName;
114
- data: (config?: C) => DataModel<D>;
121
+ data: (config?: Config) => DataModel<Data>;
115
122
  outputs?: {
116
- [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K];
123
+ [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
117
124
  };
118
- }): PluginModelBuilder<D, P, C, O>;
125
+ featureFlags?: BlockCodeKnownFeatureFlags;
126
+ }): PluginModelBuilder<Data, Params, Outputs, Config>;
119
127
  /**
120
128
  * Adds an output to the plugin.
121
129
  *
@@ -127,9 +135,9 @@ declare class PluginModelBuilder<Data, Params = undefined, Config = undefined, O
127
135
  * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))
128
136
  * .output('isReady', (ctx) => ctx.params.columns !== undefined)
129
137
  */
130
- output<const Key extends string, T>(key: Key, fn: (ctx: PluginRenderCtx<Data, Params>) => T): PluginModelBuilder<Data, Params, Config, Outputs & {
138
+ output<const Key extends string, T>(key: Key, fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T): PluginModelBuilder<Data, Params, Outputs & {
131
139
  [K in Key]: T;
132
- }>;
140
+ }, Config>;
133
141
  /**
134
142
  * Finalizes the plugin definition and returns a ConfigurablePluginModel.
135
143
  *
@@ -143,7 +151,7 @@ declare class PluginModelBuilder<Data, Params = undefined, Config = undefined, O
143
151
  * // Later, call create() with config to get a configured instance:
144
152
  * const configured = myPlugin.create({ defaultValue: 'test' });
145
153
  */
146
- build(): PluginModelFactory<Data, Params, Config, Outputs>;
154
+ build(): PluginFactory<Data, Params, Outputs, Config>;
147
155
  }
148
156
  export {};
149
157
  //# sourceMappingURL=plugin_model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.d.ts","sourceRoot":"","sources":["../src/plugin_model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin_model.d.ts","sourceRoot":"","sources":["../src/plugin_model.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,6 @@
8
8
  */
9
9
  /** Symbol for internal builder creation method */
10
10
  const FROM_BUILDER = Symbol("fromBuilder");
11
- // =============================================================================
12
- // Plugin Type
13
- // =============================================================================
14
11
  /**
15
12
  * Configured plugin instance returned by PluginModelFactory.create().
16
13
  * Contains the plugin's name, data model, and output definitions.
@@ -22,18 +19,21 @@ class PluginModel {
22
19
  dataModel;
23
20
  /** Output definitions - functions that compute outputs from plugin context */
24
21
  outputs;
25
- constructor(input) {
26
- this.name = input.name;
27
- this.dataModel = input.dataModel;
28
- this.outputs = input.outputs;
22
+ /** Feature flags declared by this plugin */
23
+ featureFlags;
24
+ constructor(options) {
25
+ this.name = options.name;
26
+ this.dataModel = options.dataModel;
27
+ this.outputs = options.outputs;
28
+ this.featureFlags = options.featureFlags;
29
29
  }
30
30
  /**
31
31
  * Internal method for creating PluginModel from factory.
32
32
  * Uses Symbol key to prevent external access.
33
33
  * @internal
34
34
  */
35
- static [FROM_BUILDER](input) {
36
- return new this(input);
35
+ static [FROM_BUILDER](options) {
36
+ return new PluginModel(options);
37
37
  }
38
38
  /**
39
39
  * Creates a new PluginModelBuilder for building plugin definitions.
@@ -45,7 +45,7 @@ class PluginModel {
45
45
  * @example
46
46
  * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);
47
47
  *
48
- * const myPlugin = PluginModel.define<MyData, MyParams, MyConfig>({
48
+ * const myPlugin = PluginModel.define({
49
49
  * name: 'myPlugin' as PluginName,
50
50
  * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),
51
51
  * })
@@ -56,18 +56,16 @@ class PluginModel {
56
56
  return PluginModelBuilder[FROM_BUILDER](options);
57
57
  }
58
58
  }
59
- /**
60
- * Plugin factory returned by PluginModelBuilder.build().
61
- * Call create() with config to get a configured PluginModel instance.
62
- */
63
59
  class PluginModelFactory {
64
60
  name;
65
61
  data;
66
62
  outputs;
67
- constructor(input) {
68
- this.name = input.name;
69
- this.data = input.data;
70
- this.outputs = input.outputs;
63
+ featureFlags;
64
+ constructor(options) {
65
+ this.name = options.name;
66
+ this.data = options.data;
67
+ this.outputs = options.outputs;
68
+ this.featureFlags = options.featureFlags;
71
69
  }
72
70
  /** Create a configured PluginModel instance */
73
71
  create(config) {
@@ -75,12 +73,10 @@ class PluginModelFactory {
75
73
  name: this.name,
76
74
  dataModel: this.data(config),
77
75
  outputs: this.outputs,
76
+ featureFlags: this.featureFlags,
78
77
  });
79
78
  }
80
79
  }
81
- // =============================================================================
82
- // Plugin Model Builder
83
- // =============================================================================
84
80
  /**
85
81
  * Builder for creating PluginType with type-safe output definitions.
86
82
  *
@@ -107,20 +103,22 @@ class PluginModelBuilder {
107
103
  name;
108
104
  data;
109
105
  outputs;
110
- constructor(input) {
111
- this.name = input.name;
112
- this.data = input.data;
106
+ featureFlags;
107
+ constructor(options) {
108
+ this.name = options.name;
109
+ this.data = options.data;
113
110
  this.outputs =
114
- input.outputs ??
111
+ options.outputs ??
115
112
  {};
113
+ this.featureFlags = options.featureFlags;
116
114
  }
117
115
  /**
118
116
  * Internal method for creating PluginModelBuilder.
119
117
  * Uses Symbol key to prevent external access.
120
118
  * @internal
121
119
  */
122
- static [FROM_BUILDER](input) {
123
- return new this(input);
120
+ static [FROM_BUILDER](options) {
121
+ return new PluginModelBuilder(options);
124
122
  }
125
123
  /**
126
124
  * Adds an output to the plugin.
@@ -137,6 +135,7 @@ class PluginModelBuilder {
137
135
  return new PluginModelBuilder({
138
136
  name: this.name,
139
137
  data: this.data,
138
+ featureFlags: this.featureFlags,
140
139
  outputs: {
141
140
  ...this.outputs,
142
141
  [key]: fn,
@@ -161,6 +160,7 @@ class PluginModelBuilder {
161
160
  name: this.name,
162
161
  data: this.data,
163
162
  outputs: this.outputs,
163
+ featureFlags: this.featureFlags,
164
164
  });
165
165
  }
166
166
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin_model.js","sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { DataModel } from \"./block_migrations\";\nimport type { PluginName } from \"./block_storage\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\n// =============================================================================\n// Plugin Type\n// =============================================================================\n\n/**\n * Configured plugin instance returned by PluginModelFactory.create().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<Data = unknown, Params = undefined, Outputs = {}> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n\n private constructor(input: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.dataModel = input.dataModel;\n this.outputs = input.outputs;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<D, P, O>(input: {\n name: PluginName;\n dataModel: DataModel<D>;\n outputs: { [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K] };\n }): PluginModel<D, P, O> {\n return new this<D, P, O>(input);\n }\n\n /**\n * Creates a new PluginModelBuilder for building plugin definitions.\n *\n * @param options.name - Globally unique plugin name\n * @param options.data - Factory function that creates the data model from config\n * @returns PluginModelBuilder for chaining output definitions\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const myPlugin = PluginModel.define<MyData, MyParams, MyConfig>({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * })\n * .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)\n * .build();\n */\n static define<Data, Params = undefined, Config = undefined>(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n }): PluginModelBuilder<Data, Params, Config> {\n return PluginModelBuilder[FROM_BUILDER]<Data, Params, Config>(options);\n }\n}\n\n/**\n * Plugin factory returned by PluginModelBuilder.build().\n * Call create() with config to get a configured PluginModel instance.\n */\nclass PluginModelFactory<Data, Params, Config, Outputs> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];\n };\n\n constructor(input: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.data = input.data;\n this.outputs = input.outputs;\n }\n\n /** Create a configured PluginModel instance */\n create(config?: Config): PluginModel<Data, Params, Outputs> {\n return PluginModel[FROM_BUILDER]<Data, Params, Outputs>({\n name: this.name,\n dataModel: this.data(config),\n outputs: this.outputs,\n });\n }\n}\n\n// =============================================================================\n// Plugin Model Builder\n// =============================================================================\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<TableData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const dataTable = PluginModel.define<TableData, TableParams, TableConfig>({\n * name: 'dataTable' as PluginName,\n * data: (cfg) => {\n * return dataModelChain.init(() => ({ state: createInitialState(cfg.ops) }));\n * },\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data,\n Params = undefined,\n Config = undefined,\n Outputs extends Record<string, unknown> = {},\n> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K];\n };\n\n private constructor(input: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] };\n }) {\n this.name = input.name;\n this.data = input.data;\n this.outputs =\n input.outputs ??\n ({} as { [K in keyof Outputs]: (ctx: PluginRenderCtx<Data, Params>) => Outputs[K] });\n }\n\n /**\n * Internal method for creating PluginModelBuilder.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<D, P, C, O extends Record<string, unknown> = {}>(input: {\n name: PluginName;\n data: (config?: C) => DataModel<D>;\n outputs?: { [K in keyof O]: (ctx: PluginRenderCtx<D, P>) => O[K] };\n }): PluginModelBuilder<D, P, C, O> {\n return new this<D, P, C, O>(input);\n }\n\n /**\n * Adds an output to the plugin.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns PluginModel with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('isReady', (ctx) => ctx.params.columns !== undefined)\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (ctx: PluginRenderCtx<Data, Params>) => T,\n ): PluginModelBuilder<Data, Params, Config, Outputs & { [K in Key]: T }> {\n return new PluginModelBuilder<Data, Params, Config, Outputs & { [K in Key]: T }>({\n name: this.name,\n data: this.data,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as {\n [K in keyof (Outputs & { [P in Key]: T })]: (\n ctx: PluginRenderCtx<Data, Params>,\n ) => (Outputs & { [P in Key]: T })[K];\n },\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a ConfigurablePluginModel.\n *\n * @returns Callable plugin factory that accepts config and returns PluginModel\n *\n * @example\n * const myPlugin = new PluginModelBuilder('myPlugin', () => dataModel)\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Later, call create() with config to get a configured instance:\n * const configured = myPlugin.create({ defaultValue: 'test' });\n */\n build(): PluginModelFactory<Data, Params, Config, Outputs> {\n return new PluginModelFactory<Data, Params, Config, Outputs>({\n name: this.name,\n data: this.data,\n outputs: this.outputs,\n });\n }\n}\n"],"names":[],"mappings":"AAAA;;;;;;;AAOG;AAMH;AACA,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC;AAE1C;AACA;AACA;AAEA;;;AAGG;MACU,WAAW,CAAA;;AAEb,IAAA,IAAI;;AAEJ,IAAA,SAAS;;AAET,IAAA,OAAO;AAEhB,IAAA,WAAA,CAAoB,KAInB,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;AAChC,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO;IAC9B;AAEA;;;;AAIG;AACH,IAAA,QAAQ,YAAY,CAAC,CAAU,KAI9B,EAAA;AACC,QAAA,OAAO,IAAI,IAAI,CAAU,KAAK,CAAC;IACjC;AAEA;;;;;;;;;;;;;;;;AAgBG;IACH,OAAO,MAAM,CAA+C,OAG3D,EAAA;AACC,QAAA,OAAO,kBAAkB,CAAC,YAAY,CAAC,CAAuB,OAAO,CAAC;IACxE;AACD;AAED;;;AAGG;AACH,MAAM,kBAAkB,CAAA;AACL,IAAA,IAAI;AACJ,IAAA,IAAI;AACJ,IAAA,OAAO;AAIxB,IAAA,WAAA,CAAY,KAIX,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO;IAC9B;;AAGA,IAAA,MAAM,CAAC,MAAe,EAAA;AACpB,QAAA,OAAO,WAAW,CAAC,YAAY,CAAC,CAAwB;YACtD,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;AACtB,SAAA,CAAC;IACJ;AACD;AAED;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACH,MAAM,kBAAkB,CAAA;AAML,IAAA,IAAI;AACJ,IAAA,IAAI;AACJ,IAAA,OAAO;AAIxB,IAAA,WAAA,CAAoB,KAInB,EAAA;AACC,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AACtB,QAAA,IAAI,CAAC,OAAO;AACV,YAAA,KAAK,CAAC,OAAO;AACZ,gBAAA,EAAmF;IACxF;AAEA;;;;AAIG;AACH,IAAA,QAAQ,YAAY,CAAC,CAAkD,KAItE,EAAA;AACC,QAAA,OAAO,IAAI,IAAI,CAAa,KAAK,CAAC;IACpC;AAEA;;;;;;;;;;AAUG;IACH,MAAM,CACJ,GAAQ,EACR,EAA6C,EAAA;QAE7C,OAAO,IAAI,kBAAkB,CAAoD;YAC/E,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,OAAO,EAAE;gBACP,GAAG,IAAI,CAAC,OAAO;gBACf,CAAC,GAAG,GAAG,EAAE;AAKV,aAAA;AACF,SAAA,CAAC;IACJ;AAEA;;;;;;;;;;;;AAYG;IACH,KAAK,GAAA;QACH,OAAO,IAAI,kBAAkB,CAAgC;YAC3D,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;AACtB,SAAA,CAAC;IACJ;AACD;;;;"}
1
+ {"version":3,"file":"plugin_model.js","sources":["../src/plugin_model.ts"],"sourcesContent":["/**\n * PluginModel - Builder for creating plugin types with data model and outputs.\n *\n * Plugins are UI components with their own model logic and persistent state.\n * Block developers register plugin instances via BlockModelV3.plugin() method.\n *\n * @module plugin_model\n */\n\nimport type { BlockCodeKnownFeatureFlags } from \"@milaboratories/pl-model-common\";\nimport type { DataModel } from \"./block_migrations\";\nimport type { PluginName } from \"./block_storage\";\nimport type { PluginFactoryLike } from \"./plugin_handle\";\nimport type { PluginRenderCtx } from \"./render\";\n\n/** Symbol for internal builder creation method */\nconst FROM_BUILDER = Symbol(\"fromBuilder\");\n\nexport type PluginData = Record<string, unknown>;\nexport type PluginParams = undefined | Record<string, unknown>;\nexport type PluginOutputs = Record<string, unknown>;\nexport type PluginConfig = undefined | Record<string, unknown>;\n\n/**\n * Configured plugin instance returned by PluginModelFactory.create().\n * Contains the plugin's name, data model, and output definitions.\n */\nexport class PluginModel<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n> {\n /** Globally unique plugin name */\n readonly name: PluginName;\n /** Data model instance for this plugin */\n readonly dataModel: DataModel<Data>;\n /** Output definitions - functions that compute outputs from plugin context */\n readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n /** Feature flags declared by this plugin */\n readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n private constructor(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.dataModel = options.dataModel;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n }\n\n /**\n * Internal method for creating PluginModel from factory.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n >(options: {\n name: PluginName;\n dataModel: DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModel<Data, Params, Outputs> {\n return new PluginModel<Data, Params, Outputs>(options);\n }\n\n /**\n * Creates a new PluginModelBuilder for building plugin definitions.\n *\n * @param options.name - Globally unique plugin name\n * @param options.data - Factory function that creates the data model from config\n * @returns PluginModelBuilder for chaining output definitions\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<MyData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const myPlugin = PluginModel.define({\n * name: 'myPlugin' as PluginName,\n * data: (cfg) => dataModelChain.init(() => ({ value: cfg.defaultValue })),\n * })\n * .output('computed', (ctx) => ctx.data.value * ctx.params.multiplier)\n * .build();\n */\n static define<\n Data extends PluginData,\n Params extends PluginParams,\n Config extends PluginConfig,\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelBuilder<Data, Params, {}, Config> {\n return PluginModelBuilder[FROM_BUILDER](options);\n }\n}\n\n/** Plugin factory returned by PluginModelBuilder.build(). */\nexport interface PluginFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> extends PluginFactoryLike {\n create(config?: Config): PluginModel<Data, Params, Outputs>;\n /**\n * @internal Phantom field for structural type extraction.\n * Enables InferFactoryData/InferFactoryOutputs to work via PluginFactoryLike.\n */\n readonly __types?: { data: Data; params: Params; outputs: Outputs; config: Config };\n}\n\nclass PluginModelFactory<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> implements PluginFactory<Data, Params, Outputs, Config> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n constructor(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.data = options.data;\n this.outputs = options.outputs;\n this.featureFlags = options.featureFlags;\n }\n\n /** Create a configured PluginModel instance */\n create(config?: Config): PluginModel<Data, Params, Outputs> {\n return PluginModel[FROM_BUILDER]<Data, Params, Outputs>({\n name: this.name,\n dataModel: this.data(config),\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n });\n }\n}\n\n/**\n * Builder for creating PluginType with type-safe output definitions.\n *\n * Use `PluginModel.define()` to create a builder instance.\n *\n * @typeParam Data - Plugin's persistent data type\n * @typeParam Params - Params derived from block's RenderCtx (optional)\n * @typeParam Config - Static configuration passed to plugin factory (optional)\n * @typeParam Outputs - Accumulated output types\n *\n * @example\n * const dataModelChain = new DataModelBuilder().from<TableData>(DATA_MODEL_DEFAULT_VERSION);\n *\n * const dataTable = PluginModel.define<TableData, TableParams, TableConfig>({\n * name: 'dataTable' as PluginName,\n * data: (cfg) => {\n * return dataModelChain.init(() => ({ state: createInitialState(cfg.ops) }));\n * },\n * })\n * .output('model', (ctx) => createTableModel(ctx))\n * .build();\n */\nclass PluginModelBuilder<\n Data extends PluginData = PluginData,\n Params extends PluginParams = undefined,\n Outputs extends PluginOutputs = PluginOutputs,\n Config extends PluginConfig = undefined,\n> {\n private readonly name: PluginName;\n private readonly data: (config?: Config) => DataModel<Data>;\n private readonly outputs: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n private readonly featureFlags?: BlockCodeKnownFeatureFlags;\n\n private constructor(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }) {\n this.name = options.name;\n this.data = options.data;\n this.outputs =\n options.outputs ??\n ({} as {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n });\n this.featureFlags = options.featureFlags;\n }\n\n /**\n * Internal method for creating PluginModelBuilder.\n * Uses Symbol key to prevent external access.\n * @internal\n */\n static [FROM_BUILDER]<\n Data extends PluginData,\n Params extends PluginParams,\n Outputs extends PluginOutputs,\n Config extends PluginConfig,\n >(options: {\n name: PluginName;\n data: (config?: Config) => DataModel<Data>;\n outputs?: {\n [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];\n };\n featureFlags?: BlockCodeKnownFeatureFlags;\n }): PluginModelBuilder<Data, Params, Outputs, Config> {\n return new PluginModelBuilder(options);\n }\n\n /**\n * Adds an output to the plugin.\n *\n * @param key - Output name\n * @param fn - Function that computes the output value from plugin context\n * @returns PluginModel with the new output added\n *\n * @example\n * .output('model', (ctx) => createModel(ctx.params.columns, ctx.data.state))\n * .output('isReady', (ctx) => ctx.params.columns !== undefined)\n */\n output<const Key extends string, T>(\n key: Key,\n fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T,\n ): PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config> {\n return new PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config>({\n name: this.name,\n data: this.data,\n featureFlags: this.featureFlags,\n outputs: {\n ...this.outputs,\n [key]: fn,\n } as {\n [K in keyof (Outputs & { [P in Key]: T })]: (\n ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>,\n ) => (Outputs & { [P in Key]: T })[K];\n },\n });\n }\n\n /**\n * Finalizes the plugin definition and returns a ConfigurablePluginModel.\n *\n * @returns Callable plugin factory that accepts config and returns PluginModel\n *\n * @example\n * const myPlugin = new PluginModelBuilder('myPlugin', () => dataModel)\n * .output('value', (ctx) => ctx.data.value)\n * .build();\n *\n * // Later, call create() with config to get a configured instance:\n * const configured = myPlugin.create({ defaultValue: 'test' });\n */\n build(): PluginFactory<Data, Params, Outputs, Config> {\n return new PluginModelFactory<Data, Params, Outputs, Config>({\n name: this.name,\n data: this.data,\n outputs: this.outputs,\n featureFlags: this.featureFlags,\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -549,14 +549,19 @@ class RenderCtxLegacy extends RenderCtxBase {
549
549
  /**
550
550
  * Render context for plugin output functions.
551
551
  * Reads plugin data from blockStorage and derives params from pre-wrapped input callbacks.
552
+ *
553
+ * Parameterized on the factory-like phantom F so that getPluginData returns
554
+ * InferFactoryData<F> directly — no casts needed for the data getter.
555
+ *
556
+ * @typeParam F - PluginFactoryLike phantom carrying data/params/outputs types
552
557
  */
553
558
  class PluginRenderCtx {
554
559
  ctx;
555
- pluginId;
560
+ handle;
556
561
  wrappedInputs;
557
- constructor(pluginId, wrappedInputs) {
562
+ constructor(handle, wrappedInputs) {
558
563
  this.ctx = internal.getCfgRenderCtx();
559
- this.pluginId = pluginId;
564
+ this.handle = handle;
560
565
  this.wrappedInputs = wrappedInputs;
561
566
  }
562
567
  dataCache;
@@ -564,8 +569,7 @@ class PluginRenderCtx {
564
569
  get data() {
565
570
  if (this.dataCache === undefined) {
566
571
  const raw = this.ctx.blockStorage();
567
- const pluginData = block_storage.getPluginData(plModelCommon.parseJson(raw), this.pluginId);
568
- this.dataCache = { v: pluginData };
572
+ this.dataCache = { v: block_storage.getPluginData(plModelCommon.parseJson(raw), this.handle) };
569
573
  }
570
574
  return this.dataCache.v;
571
575
  }