@platforma-sdk/model 1.61.1 → 1.62.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 (74) hide show
  1. package/dist/block_model.cjs +17 -10
  2. package/dist/block_model.cjs.map +1 -1
  3. package/dist/block_model.d.ts +22 -5
  4. package/dist/block_model.js +16 -10
  5. package/dist/block_model.js.map +1 -1
  6. package/dist/columns/column_collection_builder.cjs +26 -14
  7. package/dist/columns/column_collection_builder.cjs.map +1 -1
  8. package/dist/columns/column_collection_builder.d.ts +9 -8
  9. package/dist/columns/column_collection_builder.js +26 -14
  10. package/dist/columns/column_collection_builder.js.map +1 -1
  11. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  12. package/dist/columns/ctx_column_sources.d.ts +1 -1
  13. package/dist/columns/ctx_column_sources.js.map +1 -1
  14. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +93 -89
  15. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  16. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +2 -2
  17. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +93 -89
  18. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  19. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  20. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -1
  21. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  22. package/dist/index.cjs +7 -0
  23. package/dist/index.d.ts +6 -2
  24. package/dist/index.js +4 -1
  25. package/dist/package.cjs +1 -1
  26. package/dist/package.js +1 -1
  27. package/dist/platforma.d.ts +8 -4
  28. package/dist/plugin_handle.cjs.map +1 -1
  29. package/dist/plugin_handle.d.ts +13 -7
  30. package/dist/plugin_handle.js.map +1 -1
  31. package/dist/plugin_model.cjs +37 -11
  32. package/dist/plugin_model.cjs.map +1 -1
  33. package/dist/plugin_model.d.ts +80 -39
  34. package/dist/plugin_model.js +37 -11
  35. package/dist/plugin_model.js.map +1 -1
  36. package/dist/render/api.cjs +13 -24
  37. package/dist/render/api.cjs.map +1 -1
  38. package/dist/render/api.d.ts +11 -14
  39. package/dist/render/api.js +13 -24
  40. package/dist/render/api.js.map +1 -1
  41. package/dist/render/internal.cjs.map +1 -1
  42. package/dist/render/internal.d.ts +3 -14
  43. package/dist/render/internal.js.map +1 -1
  44. package/dist/services/block_services.cjs +18 -0
  45. package/dist/services/block_services.cjs.map +1 -0
  46. package/dist/services/block_services.d.ts +18 -0
  47. package/dist/services/block_services.js +16 -0
  48. package/dist/services/block_services.js.map +1 -0
  49. package/dist/services/index.cjs +2 -0
  50. package/dist/services/index.d.ts +3 -0
  51. package/dist/services/index.js +2 -0
  52. package/dist/services/service_bridge.cjs +35 -0
  53. package/dist/services/service_bridge.cjs.map +1 -0
  54. package/dist/services/service_bridge.d.ts +18 -0
  55. package/dist/services/service_bridge.js +33 -0
  56. package/dist/services/service_bridge.js.map +1 -0
  57. package/dist/services/service_resolve.d.ts +13 -0
  58. package/package.json +9 -9
  59. package/src/block_model.ts +47 -14
  60. package/src/columns/column_collection_builder.test.ts +23 -2
  61. package/src/columns/column_collection_builder.ts +38 -30
  62. package/src/columns/ctx_column_sources.ts +2 -2
  63. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +159 -153
  64. package/src/components/PlDataTable/createPlDataTable/index.ts +5 -4
  65. package/src/index.ts +1 -0
  66. package/src/platforma.ts +14 -2
  67. package/src/plugin_handle.ts +24 -6
  68. package/src/plugin_model.ts +252 -84
  69. package/src/render/api.ts +50 -51
  70. package/src/render/internal.ts +3 -38
  71. package/src/services/block_services.ts +17 -0
  72. package/src/services/index.ts +3 -0
  73. package/src/services/service_bridge.ts +71 -0
  74. package/src/services/service_resolve.ts +71 -0
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import type { BlockCodeKnownFeatureFlags, OutputWithStatus } from "@milaboratories/pl-model-common";
11
+ import type { ResolveModelServices, ResolveUiServices } from "./services/service_resolve";
11
12
  import {
12
13
  type DataModel,
13
14
  DataModelBuilder,
@@ -22,6 +23,30 @@ import type { PluginRenderCtx } from "./render";
22
23
  /** Symbol for internal builder creation method */
23
24
  const FROM_BUILDER = Symbol("fromBuilder");
24
25
 
26
+ /** Output function signature for plugin render context. */
27
+ type PluginOutputFn<
28
+ Data extends PluginData,
29
+ Params extends PluginParams,
30
+ ModelServices,
31
+ UiServices,
32
+ T,
33
+ > = (
34
+ ctx: PluginRenderCtx<
35
+ PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>
36
+ >,
37
+ ) => T;
38
+
39
+ /** Mapped output functions for a plugin's outputs. */
40
+ type PluginOutputFns<
41
+ Data extends PluginData,
42
+ Params extends PluginParams,
43
+ Outputs extends PluginOutputs,
44
+ ModelServices,
45
+ UiServices,
46
+ > = {
47
+ [K in keyof Outputs]: PluginOutputFn<Data, Params, ModelServices, UiServices, Outputs[K]>;
48
+ };
49
+
25
50
  /** Symbol for internal plugin model creation — not accessible to external consumers */
26
51
  export const CREATE_PLUGIN_MODEL = Symbol("createPluginModel");
27
52
 
@@ -282,45 +307,68 @@ export class PluginInstance<
282
307
  Params extends PluginParams = undefined,
283
308
  Outputs extends PluginOutputs = PluginOutputs,
284
309
  TransferData = never,
310
+ ModelServices = unknown,
311
+ UiServices = unknown,
285
312
  > implements TransferTarget<Id, TransferData> {
286
313
  readonly id: Id;
287
314
  readonly transferVersion: string;
288
- /** @internal Phantom for type inference of Data/Params/Outputs; never set at runtime. */
289
- readonly __instanceTypes?: { data: Data; params: Params; outputs: Outputs };
290
- private readonly factory: PluginModelFactory<Data, Params, Outputs, any, any>;
291
- private readonly config: any;
315
+ /** @internal Phantom for type inference; never set at runtime. */
316
+ readonly __instanceTypes?: {
317
+ data: Data;
318
+ params: Params;
319
+ outputs: Outputs;
320
+ modelServices: ModelServices;
321
+ uiServices: UiServices;
322
+ };
323
+ /** Bound closure that creates the PluginModel. Config is captured at factory.create() time. */
324
+ private readonly createPluginModel: () => PluginModel<
325
+ Data,
326
+ Params,
327
+ Outputs,
328
+ ModelServices,
329
+ UiServices
330
+ >;
292
331
 
293
332
  private constructor(
294
333
  id: Id,
295
- factory: PluginModelFactory<Data, Params, Outputs, any, any>,
334
+ createPluginModel: () => PluginModel<Data, Params, Outputs, ModelServices, UiServices>,
296
335
  transferVersion: string,
297
- config?: any,
298
336
  ) {
299
337
  this.id = id;
300
- this.factory = factory;
338
+ this.createPluginModel = createPluginModel;
301
339
  this.transferVersion = transferVersion;
302
- this.config = config;
303
340
  }
304
341
 
305
- /** @internal */
342
+ /** @internal Accepts concrete Config — binds it into a closure, avoiding Config variance issues. */
306
343
  static [FROM_BUILDER]<
307
344
  Id extends string,
308
345
  Data extends PluginData,
309
346
  Params extends PluginParams,
310
347
  Outputs extends PluginOutputs,
311
348
  TransferData,
349
+ Config extends PluginConfig = PluginConfig,
350
+ ModelServices = unknown,
351
+ UiServices = unknown,
312
352
  >(
313
353
  id: Id,
314
- factory: PluginModelFactory<Data, Params, Outputs, any, any>,
354
+ factory: PluginModelFactory<
355
+ Data,
356
+ Params,
357
+ Outputs,
358
+ Config,
359
+ Record<string, unknown>,
360
+ ModelServices,
361
+ UiServices
362
+ >,
315
363
  transferVersion: string,
316
- config?: any,
317
- ): PluginInstance<Id, Data, Params, Outputs, TransferData> {
318
- return new PluginInstance(id, factory, transferVersion, config);
364
+ config?: Config,
365
+ ): PluginInstance<Id, Data, Params, Outputs, TransferData, ModelServices, UiServices> {
366
+ return new PluginInstance(id, () => factory[CREATE_PLUGIN_MODEL](config), transferVersion);
319
367
  }
320
368
 
321
369
  /** @internal Create a PluginModel from this instance. Used by BlockModelV3.plugin(). */
322
- [CREATE_PLUGIN_MODEL](): PluginModel<Data, Params, Outputs> {
323
- return this.factory[CREATE_PLUGIN_MODEL](this.config);
370
+ [CREATE_PLUGIN_MODEL](): PluginModel<Data, Params, Outputs, ModelServices, UiServices> {
371
+ return this.createPluginModel();
324
372
  }
325
373
  }
326
374
 
@@ -332,15 +380,15 @@ export class PluginModel<
332
380
  Data extends PluginData = PluginData,
333
381
  Params extends PluginParams = undefined,
334
382
  Outputs extends PluginOutputs = PluginOutputs,
383
+ ModelServices = {},
384
+ UiServices = {},
335
385
  > {
336
386
  /** Globally unique plugin name */
337
387
  readonly name: PluginName;
338
388
  /** Data model instance for this plugin */
339
389
  readonly dataModel: DataModel<Data>;
340
390
  /** Output definitions - functions that compute outputs from plugin context */
341
- readonly outputs: {
342
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
343
- };
391
+ readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
344
392
  /** Per-output flags (e.g. withStatus) */
345
393
  readonly outputFlags: Record<string, { withStatus: boolean }>;
346
394
  /** Feature flags declared by this plugin */
@@ -351,9 +399,7 @@ export class PluginModel<
351
399
  private constructor(options: {
352
400
  name: PluginName;
353
401
  dataModel: DataModel<Data>;
354
- outputs: {
355
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
356
- };
402
+ outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
357
403
  outputFlags: Record<string, { withStatus: boolean }>;
358
404
  featureFlags?: BlockCodeKnownFeatureFlags;
359
405
  getDefaultData: () => DataVersioned<Data>;
@@ -375,17 +421,17 @@ export class PluginModel<
375
421
  Data extends PluginData,
376
422
  Params extends PluginParams,
377
423
  Outputs extends PluginOutputs,
424
+ ModelServices = {},
425
+ UiServices = {},
378
426
  >(options: {
379
427
  name: PluginName;
380
428
  dataModel: DataModel<Data>;
381
- outputs: {
382
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
383
- };
429
+ outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
384
430
  outputFlags: Record<string, { withStatus: boolean }>;
385
431
  featureFlags?: BlockCodeKnownFeatureFlags;
386
432
  getDefaultData: () => DataVersioned<Data>;
387
- }): PluginModel<Data, Params, Outputs> {
388
- return new PluginModel<Data, Params, Outputs>(options);
433
+ }): PluginModel<Data, Params, Outputs, ModelServices, UiServices> {
434
+ return new PluginModel<Data, Params, Outputs, ModelServices, UiServices>(options);
389
435
  }
390
436
 
391
437
  /**
@@ -409,11 +455,19 @@ export class PluginModel<
409
455
  Params extends PluginParams = undefined,
410
456
  Versions extends Record<string, unknown> = {},
411
457
  Config extends PluginConfig = undefined,
458
+ Flags extends BlockCodeKnownFeatureFlags = {},
412
459
  >(options: {
413
460
  name: PluginName;
414
461
  data: PluginDataModel<Data, Versions, Config>;
415
- featureFlags?: BlockCodeKnownFeatureFlags;
416
- }): PluginModelBuilder<Data, Params, {}, Config, Versions>;
462
+ featureFlags?: Flags;
463
+ }): PluginModelInitialBuilder<
464
+ Data,
465
+ Params,
466
+ Config,
467
+ Versions,
468
+ ResolveModelServices<Flags>,
469
+ ResolveUiServices<Flags>
470
+ >;
417
471
  /**
418
472
  * Creates a new PluginModelBuilder with a data model factory function (backward compatible).
419
473
  *
@@ -427,26 +481,34 @@ export class PluginModel<
427
481
  Data extends PluginData,
428
482
  Params extends PluginParams = undefined,
429
483
  Config extends PluginConfig = undefined,
484
+ Flags extends BlockCodeKnownFeatureFlags = {},
430
485
  >(options: {
431
486
  name: PluginName;
432
487
  data: (config?: Config) => DataModel<Data>;
433
- featureFlags?: BlockCodeKnownFeatureFlags;
434
- }): PluginModelBuilder<Data, Params, {}, Config, {}>;
488
+ featureFlags?: Flags;
489
+ }): PluginModelInitialBuilder<
490
+ Data,
491
+ Params,
492
+ Config,
493
+ {},
494
+ ResolveModelServices<Flags>,
495
+ ResolveUiServices<Flags>
496
+ >;
435
497
  static define(options: {
436
498
  name: PluginName;
437
499
  data: PluginDataModel<any, any, any> | ((config?: any) => DataModel<any>);
438
500
  featureFlags?: BlockCodeKnownFeatureFlags;
439
- }): PluginModelBuilder {
501
+ }): PluginModelInitialBuilder {
440
502
  if (options.data instanceof PluginDataModel) {
441
503
  const pdm = options.data;
442
- return PluginModelBuilder[FROM_BUILDER]({
504
+ return PluginModelInitialBuilder.create({
443
505
  name: options.name,
444
506
  dataFn: () => pdm.dataModel,
445
507
  getDefaultDataFn: (config: any) => pdm.getDefaultData(config),
446
508
  featureFlags: options.featureFlags,
447
509
  });
448
510
  }
449
- return PluginModelBuilder[FROM_BUILDER]({
511
+ return PluginModelInitialBuilder.create({
450
512
  name: options.name,
451
513
  dataFn: options.data,
452
514
  featureFlags: options.featureFlags,
@@ -461,13 +523,15 @@ export interface PluginFactory<
461
523
  Outputs extends PluginOutputs = PluginOutputs,
462
524
  Config extends PluginConfig = undefined,
463
525
  Versions extends Record<string, unknown> = {},
464
- > extends PluginFactoryLike<Data, Params, Outputs> {
526
+ ModelServices = {},
527
+ UiServices = {},
528
+ > extends PluginFactoryLike<Data, Params, Outputs, ModelServices, UiServices> {
465
529
  /** Create a named plugin instance, optionally with transfer at a specific version. */
466
530
  create<const Id extends string, const V extends string & keyof Versions = never>(options: {
467
531
  pluginId: Id;
468
532
  transferAt?: V;
469
533
  config?: Config;
470
- }): PluginInstance<Id, Data, Params, Outputs, Versions[V]>;
534
+ }): PluginInstance<Id, Data, Params, Outputs, Versions[V], ModelServices, UiServices>;
471
535
 
472
536
  /**
473
537
  * @internal Phantom field for structural type extraction.
@@ -477,6 +541,8 @@ export interface PluginFactory<
477
541
  data: Data;
478
542
  params: Params;
479
543
  outputs: Outputs;
544
+ modelServices: ModelServices;
545
+ uiServices: UiServices;
480
546
  config: Config;
481
547
  versions: Versions;
482
548
  };
@@ -488,13 +554,13 @@ class PluginModelFactory<
488
554
  Outputs extends PluginOutputs = PluginOutputs,
489
555
  Config extends PluginConfig = undefined,
490
556
  Versions extends Record<string, unknown> = {},
491
- > implements PluginFactory<Data, Params, Outputs, Config, Versions> {
557
+ ModelServices = {},
558
+ UiServices = {},
559
+ > implements PluginFactory<Data, Params, Outputs, Config, Versions, ModelServices, UiServices> {
492
560
  private readonly name: PluginName;
493
561
  private readonly dataFn: (config?: Config) => DataModel<Data>;
494
562
  private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
495
- readonly outputs: {
496
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
497
- };
563
+ readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
498
564
  private readonly outputFlags: Record<string, { withStatus: boolean }>;
499
565
  private readonly featureFlags?: BlockCodeKnownFeatureFlags;
500
566
 
@@ -502,9 +568,7 @@ class PluginModelFactory<
502
568
  name: PluginName;
503
569
  dataFn: (config?: Config) => DataModel<Data>;
504
570
  getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
505
- outputs: {
506
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
507
- };
571
+ outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
508
572
  outputFlags: Record<string, { withStatus: boolean }>;
509
573
  featureFlags?: BlockCodeKnownFeatureFlags;
510
574
  }) {
@@ -523,16 +587,16 @@ class PluginModelFactory<
523
587
  Outputs extends PluginOutputs,
524
588
  Config extends PluginConfig,
525
589
  Versions extends Record<string, unknown>,
590
+ ModelServices = {},
591
+ UiServices = {},
526
592
  >(options: {
527
593
  name: PluginName;
528
594
  dataFn: (config?: Config) => DataModel<Data>;
529
595
  getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
530
- outputs: {
531
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
532
- };
596
+ outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
533
597
  outputFlags: Record<string, { withStatus: boolean }>;
534
598
  featureFlags?: BlockCodeKnownFeatureFlags;
535
- }): PluginModelFactory<Data, Params, Outputs, Config, Versions> {
599
+ }): PluginModelFactory<Data, Params, Outputs, Config, Versions, ModelServices, UiServices> {
536
600
  return new PluginModelFactory(options);
537
601
  }
538
602
 
@@ -540,21 +604,27 @@ class PluginModelFactory<
540
604
  pluginId: Id;
541
605
  transferAt?: V;
542
606
  config?: Config;
543
- }): PluginInstance<Id, Data, Params, Outputs, Versions[V]> {
607
+ }): PluginInstance<Id, Data, Params, Outputs, Versions[V], ModelServices, UiServices> {
544
608
  const transferVersion = options.transferAt ?? NO_TRANSFER_VERSION;
545
- return PluginInstance[FROM_BUILDER]<Id, Data, Params, Outputs, Versions[V]>(
546
- options.pluginId as Id,
547
- this as any,
548
- transferVersion,
549
- options.config,
550
- );
609
+ return PluginInstance[FROM_BUILDER]<
610
+ Id,
611
+ Data,
612
+ Params,
613
+ Outputs,
614
+ Versions[V],
615
+ Config,
616
+ ModelServices,
617
+ UiServices
618
+ >(options.pluginId as Id, this, transferVersion, options.config);
551
619
  }
552
620
 
553
621
  /** @internal Create a PluginModel from config. Config is captured in getDefaultData closure. */
554
- [CREATE_PLUGIN_MODEL](config?: Config): PluginModel<Data, Params, Outputs> {
622
+ [CREATE_PLUGIN_MODEL](
623
+ config?: Config,
624
+ ): PluginModel<Data, Params, Outputs, ModelServices, UiServices> {
555
625
  const dataModel = this.dataFn(config);
556
626
  const getDefaultDataFn = this.getDefaultDataFn;
557
- return PluginModel[FROM_BUILDER]<Data, Params, Outputs>({
627
+ return PluginModel[FROM_BUILDER]<Data, Params, Outputs, ModelServices, UiServices>({
558
628
  name: this.name,
559
629
  dataModel,
560
630
  outputs: this.outputs,
@@ -592,23 +662,21 @@ class PluginModelBuilder<
592
662
  Outputs extends PluginOutputs = PluginOutputs,
593
663
  Config extends PluginConfig = undefined,
594
664
  Versions extends Record<string, unknown> = {},
665
+ ModelServices = {},
666
+ UiServices = {},
595
667
  > {
596
- private readonly name: PluginName;
597
- private readonly dataFn: (config?: Config) => DataModel<Data>;
598
- private readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
599
- private readonly outputs: {
600
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
601
- };
668
+ protected readonly name: PluginName;
669
+ protected readonly dataFn: (config?: Config) => DataModel<Data>;
670
+ protected readonly getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
671
+ private readonly outputs: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
602
672
  private readonly outputFlags: Record<string, { withStatus: boolean }>;
603
- private readonly featureFlags?: BlockCodeKnownFeatureFlags;
673
+ protected readonly featureFlags?: BlockCodeKnownFeatureFlags;
604
674
 
605
- private constructor(options: {
675
+ protected constructor(options: {
606
676
  name: PluginName;
607
677
  dataFn: (config?: Config) => DataModel<Data>;
608
678
  getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
609
- outputs?: {
610
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
611
- };
679
+ outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
612
680
  outputFlags?: Record<string, { withStatus: boolean }>;
613
681
  featureFlags?: BlockCodeKnownFeatureFlags;
614
682
  }) {
@@ -616,10 +684,7 @@ class PluginModelBuilder<
616
684
  this.dataFn = options.dataFn;
617
685
  this.getDefaultDataFn = options.getDefaultDataFn;
618
686
  this.outputs =
619
- options.outputs ??
620
- ({} as {
621
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
622
- });
687
+ options.outputs ?? ({} as PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>);
623
688
  this.outputFlags = options.outputFlags ?? {};
624
689
  this.featureFlags = options.featureFlags;
625
690
  }
@@ -631,16 +696,16 @@ class PluginModelBuilder<
631
696
  Outputs extends PluginOutputs,
632
697
  Config extends PluginConfig,
633
698
  Versions extends Record<string, unknown> = {},
699
+ ModelServices = {},
700
+ UiServices = {},
634
701
  >(options: {
635
702
  name: PluginName;
636
703
  dataFn: (config?: Config) => DataModel<Data>;
637
704
  getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
638
- outputs?: {
639
- [K in keyof Outputs]: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => Outputs[K];
640
- };
705
+ outputs?: PluginOutputFns<Data, Params, Outputs, ModelServices, UiServices>;
641
706
  outputFlags?: Record<string, { withStatus: boolean }>;
642
707
  featureFlags?: BlockCodeKnownFeatureFlags;
643
- }): PluginModelBuilder<Data, Params, Outputs, Config, Versions> {
708
+ }): PluginModelBuilder<Data, Params, Outputs, Config, Versions, ModelServices, UiServices> {
644
709
  return new PluginModelBuilder(options);
645
710
  }
646
711
 
@@ -657,9 +722,29 @@ class PluginModelBuilder<
657
722
  */
658
723
  output<const Key extends string, T>(
659
724
  key: Key,
660
- fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T,
661
- ): PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config, Versions> {
662
- return new PluginModelBuilder<Data, Params, Outputs & { [K in Key]: T }, Config, Versions>({
725
+ fn: (
726
+ ctx: PluginRenderCtx<
727
+ PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>
728
+ >,
729
+ ) => T,
730
+ ): PluginModelBuilder<
731
+ Data,
732
+ Params,
733
+ Outputs & { [K in Key]: T },
734
+ Config,
735
+ Versions,
736
+ ModelServices,
737
+ UiServices
738
+ > {
739
+ return new PluginModelBuilder<
740
+ Data,
741
+ Params,
742
+ Outputs & { [K in Key]: T },
743
+ Config,
744
+ Versions,
745
+ ModelServices,
746
+ UiServices
747
+ >({
663
748
  name: this.name,
664
749
  dataFn: this.dataFn,
665
750
  getDefaultDataFn: this.getDefaultDataFn,
@@ -669,7 +754,9 @@ class PluginModelBuilder<
669
754
  [key]: fn,
670
755
  } as {
671
756
  [K in keyof (Outputs & { [P in Key]: T })]: (
672
- ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>,
757
+ ctx: PluginRenderCtx<
758
+ PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>
759
+ >,
673
760
  ) => (Outputs & { [P in Key]: T })[K];
674
761
  },
675
762
  outputFlags: { ...this.outputFlags, [key]: { withStatus: false } },
@@ -695,20 +782,28 @@ class PluginModelBuilder<
695
782
  */
696
783
  outputWithStatus<const Key extends string, T>(
697
784
  key: Key,
698
- fn: (ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>) => T,
785
+ fn: (
786
+ ctx: PluginRenderCtx<
787
+ PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>
788
+ >,
789
+ ) => T,
699
790
  ): PluginModelBuilder<
700
791
  Data,
701
792
  Params,
702
793
  Outputs & { [K in Key]: OutputWithStatus<T> },
703
794
  Config,
704
- Versions
795
+ Versions,
796
+ ModelServices,
797
+ UiServices
705
798
  > {
706
799
  return new PluginModelBuilder<
707
800
  Data,
708
801
  Params,
709
802
  Outputs & { [K in Key]: OutputWithStatus<T> },
710
803
  Config,
711
- Versions
804
+ Versions,
805
+ ModelServices,
806
+ UiServices
712
807
  >({
713
808
  name: this.name,
714
809
  dataFn: this.dataFn,
@@ -719,7 +814,9 @@ class PluginModelBuilder<
719
814
  [key]: fn,
720
815
  } as {
721
816
  [K in keyof (Outputs & { [P in Key]: OutputWithStatus<T> })]: (
722
- ctx: PluginRenderCtx<PluginFactoryLike<Data, Params>>,
817
+ ctx: PluginRenderCtx<
818
+ PluginFactoryLike<Data, Params, Record<string, unknown>, ModelServices, UiServices>
819
+ >,
723
820
  ) => (Outputs & { [P in Key]: OutputWithStatus<T> })[K];
724
821
  },
725
822
  outputFlags: { ...this.outputFlags, [key]: { withStatus: true } },
@@ -739,8 +836,16 @@ class PluginModelBuilder<
739
836
  * // Create a named instance:
740
837
  * const table = myPlugin.create({ pluginId: 'mainTable', config: { ... } });
741
838
  */
742
- build(): PluginFactory<Data, Params, Outputs, Config, Versions> {
743
- return PluginModelFactory[FROM_BUILDER]<Data, Params, Outputs, Config, Versions>({
839
+ build(): PluginFactory<Data, Params, Outputs, Config, Versions, ModelServices, UiServices> {
840
+ return PluginModelFactory[FROM_BUILDER]<
841
+ Data,
842
+ Params,
843
+ Outputs,
844
+ Config,
845
+ Versions,
846
+ ModelServices,
847
+ UiServices
848
+ >({
744
849
  name: this.name,
745
850
  dataFn: this.dataFn,
746
851
  getDefaultDataFn: this.getDefaultDataFn,
@@ -750,3 +855,66 @@ class PluginModelBuilder<
750
855
  });
751
856
  }
752
857
  }
858
+
859
+ /**
860
+ * Initial builder returned by PluginModel.define(). Extends PluginModelBuilder with .params().
861
+ * Once .params() or .output() is called, transitions to PluginModelBuilder (no second .params()).
862
+ */
863
+ class PluginModelInitialBuilder<
864
+ Data extends PluginData = PluginData,
865
+ Params extends PluginParams = undefined,
866
+ Config extends PluginConfig = undefined,
867
+ Versions extends Record<string, unknown> = {},
868
+ ModelServices = {},
869
+ UiServices = {},
870
+ > extends PluginModelBuilder<Data, Params, {}, Config, Versions, ModelServices, UiServices> {
871
+ /** @internal */
872
+ static create<
873
+ Data extends PluginData,
874
+ Config extends PluginConfig,
875
+ Versions extends Record<string, unknown> = {},
876
+ ModelServices = {},
877
+ UiServices = {},
878
+ >(options: {
879
+ name: PluginName;
880
+ dataFn: (config?: Config) => DataModel<Data>;
881
+ getDefaultDataFn?: (config?: Config) => DataVersioned<Data>;
882
+ featureFlags?: BlockCodeKnownFeatureFlags;
883
+ }): PluginModelInitialBuilder<Data, undefined, Config, Versions, ModelServices, UiServices> {
884
+ return new PluginModelInitialBuilder(options);
885
+ }
886
+
887
+ /**
888
+ * Sets the Params type for this plugin — the shape of data derived from the block's
889
+ * render context and passed into plugin output functions via `ctx.params`.
890
+ * Must be called before .output(). Available only on the initial builder.
891
+ *
892
+ * @example
893
+ * .params<{ title: string }>()
894
+ * .output('displayText', (ctx) => ctx.params.title)
895
+ */
896
+ params<P extends PluginParams>(): PluginModelBuilder<
897
+ Data,
898
+ P,
899
+ {},
900
+ Config,
901
+ Versions,
902
+ ModelServices,
903
+ UiServices
904
+ > {
905
+ return PluginModelBuilder[FROM_BUILDER]<
906
+ Data,
907
+ P,
908
+ {},
909
+ Config,
910
+ Versions,
911
+ ModelServices,
912
+ UiServices
913
+ >({
914
+ name: this.name,
915
+ dataFn: this.dataFn,
916
+ getDefaultDataFn: this.getDefaultDataFn,
917
+ featureFlags: this.featureFlags,
918
+ });
919
+ }
920
+ }