@milaboratories/milaboratories.monetization-test.model 1.0.46 → 1.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,16 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/milaboratories.monetization-test.model@1.0.46 build /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
3
+ > @milaboratories/milaboratories.monetization-test.model@1.0.48 build /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
4
4
  > ts-builder build --target block-model && block-tools build-model
5
5
 
6
6
  Building block-model project...
7
7
  ↳ rollup -c /configs/rollup.block-model.config.js
8
8
  
9
9
  ./src/index.ts → dist, dist...
10
- created dist, dist in 3.4s
10
+ created dist, dist in 2s
11
11
  
12
12
  ./src/index.ts → dist...
13
13
  (!) Circular dependency
14
14
  ../../../../sdk/model/dist/components/PFrameForGraphs.js -> ../../../../sdk/model/dist/pframe_utils/columns.js -> ../../../../sdk/model/dist/components/PFrameForGraphs.js
15
- created dist in 3.8s
15
+ created dist in 1.3s
16
16
  Build completed successfully
@@ -1,5 +1,5 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/milaboratories.monetization-test.model@1.0.46 lint /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
3
+ > @milaboratories/milaboratories.monetization-test.model@1.0.48 lint /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
4
4
  > eslint .
5
5
 
@@ -1,6 +1,6 @@
1
1
   WARN  Issue while reading "/home/runner/_work/platforma/platforma/.npmrc". Failed to replace env in config: ${NPMJS_TOKEN}
2
2
 
3
- > @milaboratories/milaboratories.monetization-test.model@1.0.46 type-check /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
3
+ > @milaboratories/milaboratories.monetization-test.model@1.0.48 type-check /home/runner/_work/platforma/platforma/etc/blocks/monetization-test/model
4
4
  > ts-builder types --target block-model
5
5
 
6
6
  ↳ tsc --noEmit --project ./tsconfig.json --customConditions ,
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @milaboratories/milaboratories.monetization-test.model
2
2
 
3
+ ## 1.0.48
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [1e4b72a]
8
+ - @platforma-sdk/model@1.52.3
9
+
10
+ ## 1.0.47
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [1694d1a]
15
+ - @platforma-sdk/model@1.52.0
16
+
3
17
  ## 1.0.46
4
18
 
5
19
  ### Patch Changes
package/dist/bundle.js CHANGED
@@ -4,6 +4,86 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["block-model"] = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
+ /**
8
+ * BlockStorage - Typed storage abstraction for block persistent data.
9
+ *
10
+ * This module provides:
11
+ * - A typed structure for block storage with versioning and plugin support
12
+ * - Utility functions for manipulating storage
13
+ * - Handler interfaces for model-level customization
14
+ *
15
+ * @module block_storage
16
+ */
17
+ // =============================================================================
18
+ // Core Types
19
+ // =============================================================================
20
+ /**
21
+ * Discriminator key for BlockStorage format detection.
22
+ * This unique hash-based key identifies data as BlockStorage vs legacy formats.
23
+ */
24
+ const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';
25
+ /**
26
+ * Current BlockStorage schema version.
27
+ * Increment this when the storage structure itself changes (not block state migrations).
28
+ */
29
+ const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';
30
+ /**
31
+ * Type guard to check if a value is a valid BlockStorage object.
32
+ * Checks for the discriminator key and valid schema version.
33
+ */
34
+ function isBlockStorage(value) {
35
+ if (value === null || typeof value !== 'object')
36
+ return false;
37
+ const obj = value;
38
+ const schemaVersion = obj[BLOCK_STORAGE_KEY];
39
+ // Currently only 'v1' is valid, but this allows future versions
40
+ return schemaVersion === 'v1'; // Add more versions as schema evolves
41
+ }
42
+ // =============================================================================
43
+ // Factory Functions
44
+ // =============================================================================
45
+ /**
46
+ * Creates a BlockStorage with the given initial data
47
+ *
48
+ * @param initialData - The initial data value (defaults to empty object)
49
+ * @param version - The initial data version (defaults to 1)
50
+ * @returns A new BlockStorage instance with discriminator key
51
+ */
52
+ function createBlockStorage(initialData = {}, version = 1) {
53
+ return {
54
+ [BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,
55
+ __dataVersion: version,
56
+ __data: initialData,
57
+ };
58
+ }
59
+ // =============================================================================
60
+ // Data Access & Update Functions
61
+ // =============================================================================
62
+ /**
63
+ * Gets the data from BlockStorage
64
+ *
65
+ * @param storage - The BlockStorage instance
66
+ * @returns The data value
67
+ */
68
+ function getStorageData(storage) {
69
+ return storage.__data;
70
+ }
71
+ /**
72
+ * Updates the data in BlockStorage (immutable)
73
+ *
74
+ * @param storage - The current BlockStorage
75
+ * @param payload - The update payload with operation and value
76
+ * @returns A new BlockStorage with updated data
77
+ */
78
+ function updateStorageData(storage, payload) {
79
+ switch (payload.operation) {
80
+ case 'update-data':
81
+ return { ...storage, __data: payload.value };
82
+ default:
83
+ throw new Error(`Unknown storage operation: ${payload.operation}`);
84
+ }
85
+ }
86
+
7
87
  //
8
88
  // Helpers
9
89
  //
@@ -7253,28 +7333,19 @@
7253
7333
  }
7254
7334
  }
7255
7335
  /** Main entry point to the API available within model lambdas (like outputs, sections, etc..) */
7256
- class RenderCtx {
7336
+ class RenderCtxBase {
7257
7337
  ctx;
7258
7338
  constructor() {
7259
7339
  this.ctx = getCfgRenderCtx();
7260
7340
  }
7261
- _argsCache;
7262
- get args() {
7263
- if (this._argsCache === undefined) {
7264
- const raw = this.ctx.args;
7341
+ _dataCache;
7342
+ get data() {
7343
+ if (this._dataCache === undefined) {
7344
+ const raw = this.ctx.data;
7265
7345
  const value = typeof raw === 'function' ? raw() : raw;
7266
- this._argsCache = { v: JSON.parse(value) };
7346
+ this._dataCache = { v: value ? JSON.parse(value) : {} };
7267
7347
  }
7268
- return this._argsCache.v;
7269
- }
7270
- _uiStateCache;
7271
- get uiState() {
7272
- if (this._uiStateCache === undefined) {
7273
- const raw = this.ctx.uiState;
7274
- const value = typeof raw === 'function' ? raw() : raw;
7275
- this._uiStateCache = { v: value ? JSON.parse(value) : {} };
7276
- }
7277
- return this._uiStateCache.v;
7348
+ return this._dataCache.v;
7278
7349
  }
7279
7350
  // lazy rendering because this feature is rarely used
7280
7351
  _activeArgsCache;
@@ -7385,8 +7456,29 @@
7385
7456
  this.ctx.logError(msg);
7386
7457
  }
7387
7458
  }
7459
+ /** Render context for legacy v1/v2 blocks - provides backward compatibility */
7460
+ class RenderCtxLegacy extends RenderCtxBase {
7461
+ _argsCache;
7462
+ get args() {
7463
+ if (this._argsCache === undefined) {
7464
+ const raw = this.ctx.args;
7465
+ const value = typeof raw === 'function' ? raw() : raw;
7466
+ this._argsCache = { v: JSON.parse(value) };
7467
+ }
7468
+ return this._argsCache.v;
7469
+ }
7470
+ _uiStateCache;
7471
+ get uiState() {
7472
+ if (this._uiStateCache === undefined) {
7473
+ const raw = this.ctx.uiState;
7474
+ const value = typeof raw === 'function' ? raw() : raw;
7475
+ this._uiStateCache = { v: value ? JSON.parse(value) : {} };
7476
+ }
7477
+ return this._uiStateCache.v;
7478
+ }
7479
+ }
7388
7480
 
7389
- var version = "1.51.9";
7481
+ var version = "1.52.3";
7390
7482
 
7391
7483
  const PlatformaSDKVersion = version;
7392
7484
 
@@ -7430,7 +7522,7 @@
7430
7522
  output(key, cfgOrRf, flags = {}) {
7431
7523
  if (typeof cfgOrRf === 'function') {
7432
7524
  const handle = `output#${key}`;
7433
- tryRegisterCallback(handle, () => cfgOrRf(new RenderCtx()));
7525
+ tryRegisterCallback(handle, () => cfgOrRf(new RenderCtxLegacy()));
7434
7526
  return new BlockModel({
7435
7527
  ...this.config,
7436
7528
  outputs: {
@@ -7467,7 +7559,7 @@
7467
7559
  }
7468
7560
  argsValid(cfgOrRf) {
7469
7561
  if (typeof cfgOrRf === 'function') {
7470
- tryRegisterCallback('inputsValid', () => cfgOrRf(new RenderCtx()));
7562
+ tryRegisterCallback('inputsValid', () => cfgOrRf(new RenderCtxLegacy()));
7471
7563
  return new BlockModel({
7472
7564
  ...this.config,
7473
7565
  inputsValid: {
@@ -7488,7 +7580,7 @@
7488
7580
  return this.sections(getImmediate(arrOrCfgOrRf));
7489
7581
  }
7490
7582
  else if (typeof arrOrCfgOrRf === 'function') {
7491
- tryRegisterCallback('sections', () => arrOrCfgOrRf(new RenderCtx()));
7583
+ tryRegisterCallback('sections', () => arrOrCfgOrRf(new RenderCtxLegacy()));
7492
7584
  return new BlockModel({
7493
7585
  ...this.config,
7494
7586
  sections: {
@@ -7506,7 +7598,7 @@
7506
7598
  }
7507
7599
  /** Sets a rendering function to derive block title, shown for the block in the left blocks-overview panel. */
7508
7600
  title(rf) {
7509
- tryRegisterCallback('title', () => rf(new RenderCtx()));
7601
+ tryRegisterCallback('title', () => rf(new RenderCtxLegacy()));
7510
7602
  return new BlockModel({
7511
7603
  ...this.config,
7512
7604
  title: {
@@ -7516,7 +7608,7 @@
7516
7608
  });
7517
7609
  }
7518
7610
  subtitle(rf) {
7519
- tryRegisterCallback('subtitle', () => rf(new RenderCtx()));
7611
+ tryRegisterCallback('subtitle', () => rf(new RenderCtxLegacy()));
7520
7612
  return new BlockModel({
7521
7613
  ...this.config,
7522
7614
  subtitle: {
@@ -7526,7 +7618,7 @@
7526
7618
  });
7527
7619
  }
7528
7620
  tags(rf) {
7529
- tryRegisterCallback('tags', () => rf(new RenderCtx()));
7621
+ tryRegisterCallback('tags', () => rf(new RenderCtxLegacy()));
7530
7622
  return new BlockModel({
7531
7623
  ...this.config,
7532
7624
  tags: {
@@ -7593,7 +7685,10 @@
7593
7685
  if (this.config.initialArgs === undefined)
7594
7686
  throw new Error('Initial arguments not set.');
7595
7687
  const config = {
7688
+ v4: undefined,
7596
7689
  v3: {
7690
+ configVersion: 3,
7691
+ modelAPIVersion: 1,
7597
7692
  sdkVersion: PlatformaSDKVersion,
7598
7693
  renderingMode: this.config.renderingMode,
7599
7694
  initialArgs: this.config.initialArgs,
@@ -7633,6 +7728,262 @@
7633
7728
  }
7634
7729
  }
7635
7730
 
7731
+ /**
7732
+ * BlockStorage VM Integration - Internal module for VM-based storage operations.
7733
+ *
7734
+ * This module auto-registers internal callbacks that the middle layer can invoke
7735
+ * to perform storage transformations. Block developers never interact with these
7736
+ * directly - they only see `state`.
7737
+ *
7738
+ * Registered callbacks (all prefixed with `__pl_` for internal SDK use):
7739
+ * - `__pl_storage_normalize`: (rawStorage) => { storage, data }
7740
+ * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
7741
+ * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
7742
+ * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
7743
+ * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
7744
+ * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
7745
+ *
7746
+ * Callbacks registered by DataModel.registerCallbacks():
7747
+ * - `__pl_data_initial`: () => initial data
7748
+ * - `__pl_data_upgrade`: (versioned) => UpgradeResult
7749
+ * - `__pl_storage_initial`: () => initial BlockStorage as JSON string
7750
+ *
7751
+ * @module block_storage_vm
7752
+ * @internal
7753
+ */
7754
+ /**
7755
+ * Normalizes raw storage data and extracts state.
7756
+ * Handles all formats:
7757
+ * - New BlockStorage format (has discriminator)
7758
+ * - Legacy V1/V2 format ({ args, uiState })
7759
+ * - Raw V3 state (any other format)
7760
+ *
7761
+ * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
7762
+ * @returns Object with normalized storage and extracted state
7763
+ */
7764
+ function normalizeStorage(rawStorage) {
7765
+ // Handle undefined/null
7766
+ if (rawStorage === undefined || rawStorage === null) {
7767
+ const storage = createBlockStorage({});
7768
+ return { storage, data: {} };
7769
+ }
7770
+ // Parse JSON string if needed
7771
+ let parsed = rawStorage;
7772
+ if (typeof rawStorage === 'string') {
7773
+ try {
7774
+ parsed = JSON.parse(rawStorage);
7775
+ }
7776
+ catch {
7777
+ // If parsing fails, treat string as the data
7778
+ const storage = createBlockStorage(rawStorage);
7779
+ return { storage, data: rawStorage };
7780
+ }
7781
+ }
7782
+ // Check for BlockStorage format (has discriminator)
7783
+ if (isBlockStorage(parsed)) {
7784
+ return { storage: parsed, data: getStorageData(parsed) };
7785
+ }
7786
+ // Check for legacy V1/V2 format: { args, uiState }
7787
+ if (isLegacyModelV1ApiFormat(parsed)) {
7788
+ // For legacy format, the whole object IS the data
7789
+ const storage = createBlockStorage(parsed);
7790
+ return { storage, data: parsed };
7791
+ }
7792
+ // Raw V3 data - wrap it
7793
+ const storage = createBlockStorage(parsed);
7794
+ return { storage, data: parsed };
7795
+ }
7796
+ /**
7797
+ * Applies a state update to existing storage.
7798
+ * Used when setData is called from the frontend.
7799
+ *
7800
+ * @param currentStorageJson - Current storage as JSON string (must be defined)
7801
+ * @param newData - New data from application
7802
+ * @returns Updated storage as JSON string
7803
+ */
7804
+ function applyStorageUpdate(currentStorageJson, payload) {
7805
+ const { storage: currentStorage } = normalizeStorage(currentStorageJson);
7806
+ // Update data while preserving other storage fields (version, plugins)
7807
+ const updatedStorage = updateStorageData(currentStorage, payload);
7808
+ return JSON.stringify(updatedStorage);
7809
+ }
7810
+ /**
7811
+ * Checks if data is in legacy Model API v1 format.
7812
+ * Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.
7813
+ */
7814
+ function isLegacyModelV1ApiFormat(data) {
7815
+ if (data === null || typeof data !== 'object')
7816
+ return false;
7817
+ if (isBlockStorage(data))
7818
+ return false;
7819
+ const obj = data;
7820
+ return 'args' in obj;
7821
+ }
7822
+ // =============================================================================
7823
+ // Auto-register internal callbacks when module is loaded in VM
7824
+ // =============================================================================
7825
+ // Register normalize callback
7826
+ tryRegisterCallback('__pl_storage_normalize', (rawStorage) => {
7827
+ return normalizeStorage(rawStorage);
7828
+ });
7829
+ // Register apply update callback (requires existing storage)
7830
+ tryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson, payload) => {
7831
+ return applyStorageUpdate(currentStorageJson, payload);
7832
+ });
7833
+ /**
7834
+ * Gets storage info from raw storage data.
7835
+ * Returns structured info about the storage state.
7836
+ *
7837
+ * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
7838
+ * @returns JSON string with storage info
7839
+ */
7840
+ function getStorageInfo(rawStorage) {
7841
+ const { storage } = normalizeStorage(rawStorage);
7842
+ const info = {
7843
+ dataVersion: storage.__dataVersion,
7844
+ };
7845
+ return JSON.stringify(info);
7846
+ }
7847
+ // Register get info callback
7848
+ tryRegisterCallback('__pl_storage_getInfo', (rawStorage) => {
7849
+ return getStorageInfo(rawStorage);
7850
+ });
7851
+ /**
7852
+ * Runs storage migration using the DataModel's upgrade callback.
7853
+ * This is the main entry point for the middle layer to trigger migrations.
7854
+ *
7855
+ * Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:
7856
+ * - Handles all migration logic internally
7857
+ * - Returns { version, data, warning? } - warning present if reset to initial data
7858
+ *
7859
+ * @param currentStorageJson - Current storage as JSON string (or undefined)
7860
+ * @returns MigrationResult
7861
+ */
7862
+ function migrateStorage(currentStorageJson) {
7863
+ // Get the callback registry context
7864
+ const ctx = tryGetCfgRenderCtx();
7865
+ if (ctx === undefined) {
7866
+ return { error: 'Not in config rendering context' };
7867
+ }
7868
+ // Normalize storage to get current data and version
7869
+ const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);
7870
+ const currentVersion = currentStorage.__dataVersion;
7871
+ // Helper to create storage with given data and version
7872
+ const createStorageJson = (data, version) => {
7873
+ return JSON.stringify({
7874
+ ...currentStorage,
7875
+ __dataVersion: version,
7876
+ __data: data,
7877
+ });
7878
+ };
7879
+ // Get the upgrade callback (registered by DataModel.registerCallbacks())
7880
+ const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'];
7881
+ if (typeof upgradeCallback !== 'function') {
7882
+ return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };
7883
+ }
7884
+ // Call the migrator's upgrade function
7885
+ let result;
7886
+ try {
7887
+ result = upgradeCallback({ version: currentVersion, data: currentData });
7888
+ }
7889
+ catch (e) {
7890
+ const errorMsg = e instanceof Error ? e.message : String(e);
7891
+ return { error: `upgrade() threw: ${errorMsg}` };
7892
+ }
7893
+ // Build info message
7894
+ const info = result.version === currentVersion
7895
+ ? `No migration needed (v${currentVersion})`
7896
+ : result.warning
7897
+ ? `Reset to initial data (v${result.version})`
7898
+ : `Migrated v${currentVersion}→v${result.version}`;
7899
+ return {
7900
+ newStorageJson: createStorageJson(result.data, result.version),
7901
+ info,
7902
+ warn: result.warning,
7903
+ };
7904
+ }
7905
+ // Register migrate callback
7906
+ tryRegisterCallback('__pl_storage_migrate', (currentStorageJson) => {
7907
+ return migrateStorage(currentStorageJson);
7908
+ });
7909
+ /**
7910
+ * Derives args from storage using the registered 'args' callback.
7911
+ * This extracts data from storage and passes it to the block's args() function.
7912
+ *
7913
+ * @param storageJson - Storage as JSON string
7914
+ * @returns ArgsDeriveResult with derived args or error
7915
+ */
7916
+ function deriveArgsFromStorage(storageJson) {
7917
+ const ctx = tryGetCfgRenderCtx();
7918
+ if (ctx === undefined) {
7919
+ return { error: 'Not in config rendering context' };
7920
+ }
7921
+ // Extract data from storage
7922
+ const { data } = normalizeStorage(storageJson);
7923
+ // Get the args callback (registered by BlockModelV3.args())
7924
+ const argsCallback = ctx.callbackRegistry['args'];
7925
+ if (typeof argsCallback !== 'function') {
7926
+ return { error: 'args callback not found' };
7927
+ }
7928
+ // Call the args callback with extracted data
7929
+ try {
7930
+ const result = argsCallback(data);
7931
+ return { value: result };
7932
+ }
7933
+ catch (e) {
7934
+ const errorMsg = e instanceof Error ? e.message : String(e);
7935
+ return { error: `args() threw: ${errorMsg}` };
7936
+ }
7937
+ }
7938
+ // Register args derivation callback
7939
+ tryRegisterCallback('__pl_args_derive', (storageJson) => {
7940
+ return deriveArgsFromStorage(storageJson);
7941
+ });
7942
+ /**
7943
+ * Derives prerunArgs from storage using the registered 'prerunArgs' callback.
7944
+ * Falls back to 'args' callback if 'prerunArgs' is not defined.
7945
+ *
7946
+ * @param storageJson - Storage as JSON string
7947
+ * @returns ArgsDeriveResult with derived prerunArgs or error
7948
+ */
7949
+ function derivePrerunArgsFromStorage(storageJson) {
7950
+ const ctx = tryGetCfgRenderCtx();
7951
+ if (ctx === undefined) {
7952
+ return { error: 'Not in config rendering context' };
7953
+ }
7954
+ // Extract data from storage
7955
+ const { data } = normalizeStorage(storageJson);
7956
+ // Try prerunArgs callback first
7957
+ const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'];
7958
+ if (typeof prerunArgsCallback === 'function') {
7959
+ try {
7960
+ const result = prerunArgsCallback(data);
7961
+ return { value: result };
7962
+ }
7963
+ catch (e) {
7964
+ const errorMsg = e instanceof Error ? e.message : String(e);
7965
+ return { error: `prerunArgs() threw: ${errorMsg}` };
7966
+ }
7967
+ }
7968
+ // Fall back to args callback
7969
+ const argsCallback = ctx.callbackRegistry['args'];
7970
+ if (typeof argsCallback !== 'function') {
7971
+ return { error: 'args callback not found (fallback from missing prerunArgs)' };
7972
+ }
7973
+ try {
7974
+ const result = argsCallback(data);
7975
+ return { value: result };
7976
+ }
7977
+ catch (e) {
7978
+ const errorMsg = e instanceof Error ? e.message : String(e);
7979
+ return { error: `args() threw (fallback): ${errorMsg}` };
7980
+ }
7981
+ }
7982
+ // Register prerunArgs derivation callback
7983
+ tryRegisterCallback('__pl_prerunArgs_derive', (storageJson) => {
7984
+ return derivePrerunArgsFromStorage(storageJson);
7985
+ });
7986
+
7636
7987
  var stringify = {exports: {}};
7637
7988
 
7638
7989
  var hasRequiredStringify;