@platforma-sdk/model 1.52.0 → 1.52.7

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 +1 @@
1
- {"version":3,"file":"block_storage.cjs","sources":["../src/block_storage.ts"],"sourcesContent":["/**\n * BlockStorage - Typed storage abstraction for block persistent data.\n *\n * This module provides:\n * - A typed structure for block storage with versioning and plugin support\n * - Utility functions for manipulating storage\n * - Handler interfaces for model-level customization\n *\n * @module block_storage\n */\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Discriminator key for BlockStorage format detection.\n * This unique hash-based key identifies data as BlockStorage vs legacy formats.\n */\nexport const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';\n\n/**\n * Current BlockStorage schema version.\n * Increment this when the storage structure itself changes (not block state migrations).\n */\nexport const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';\n\n/**\n * Type for valid schema versions\n */\nexport type BlockStorageSchemaVersion = 'v1'; // Add 'v2', 'v3', etc. as schema evolves\n\n/**\n * Plugin key type - keys starting with `@plugin/` are reserved for plugin data\n */\nexport type PluginKey = `@plugin/${string}`;\n\n/**\n * Core BlockStorage type that holds:\n * - __pl_a7f3e2b9__: Schema version (discriminator key identifies BlockStorage format)\n * - __dataVersion: Version number for block data migrations\n * - __data: The block's user-facing data (state)\n * - @plugin/*: Optional plugin-specific data\n */\nexport type BlockStorage<TState = unknown> = {\n /** Schema version - the key itself is the discriminator */\n readonly [BLOCK_STORAGE_KEY]: BlockStorageSchemaVersion;\n /** Version of the block data, used for migrations */\n __dataVersion: number;\n /** The block's user-facing data (state) */\n __data: TState;\n} & {\n /** Plugin-specific data, keyed by `@plugin/<pluginName>` */\n [K in PluginKey]?: unknown;\n};\n\n/**\n * Type guard to check if a value is a valid BlockStorage object.\n * Checks for the discriminator key and valid schema version.\n */\nexport function isBlockStorage(value: unknown): value is BlockStorage {\n if (value === null || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n const schemaVersion = obj[BLOCK_STORAGE_KEY];\n // Currently only 'v1' is valid, but this allows future versions\n return schemaVersion === 'v1'; // Add more versions as schema evolves\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates a BlockStorage with the given initial data\n *\n * @param initialData - The initial data value (defaults to empty object)\n * @param version - The initial data version (defaults to 1)\n * @returns A new BlockStorage instance with discriminator key\n */\nexport function createBlockStorage<TState = unknown>(\n initialData: TState = {} as TState,\n version: number = 1,\n): BlockStorage<TState> {\n return {\n [BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,\n __dataVersion: version,\n __data: initialData,\n };\n}\n\n/**\n * Normalizes raw storage data to BlockStorage format.\n * If the input is already a BlockStorage, returns it as-is.\n * If the input is legacy format (raw state), wraps it in BlockStorage structure.\n *\n * @param raw - Raw storage data (may be legacy format or BlockStorage)\n * @returns Normalized BlockStorage\n */\nexport function normalizeBlockStorage<TState = unknown>(raw: unknown): BlockStorage<TState> {\n if (isBlockStorage(raw)) {\n return raw as BlockStorage<TState>;\n }\n // Legacy format: raw is the state directly\n return createBlockStorage(raw as TState, 1);\n}\n\n// =============================================================================\n// Data Access & Update Functions\n// =============================================================================\n\n/**\n * Gets the data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data value\n */\nexport function getStorageData<TState>(storage: BlockStorage<TState>): TState {\n return storage.__data;\n}\n\n/**\n * Derives data from raw block storage.\n * This function is meant to be called from sdk/ui-vue to extract\n * user-facing data from the raw storage returned by the middle layer.\n *\n * The middle layer returns raw storage (opaque to it), and the UI\n * uses this function to derive the actual data value.\n *\n * @param rawStorage - Raw storage data from middle layer (may be any format)\n * @returns The extracted data value, or undefined if storage is undefined/null\n */\nexport function deriveDataFromStorage<TData = unknown>(\n rawStorage: unknown,\n): TData {\n // Normalize to BlockStorage format (handles legacy formats too)\n const storage = normalizeBlockStorage<TData>(rawStorage);\n return getStorageData(storage);\n}\n\n/** Payload for storage mutation operations. SDK defines specific operations. */\nexport type MutateStoragePayload<T = unknown> = { operation: 'update-data'; value: T };\n\n/**\n * Updates the data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param payload - The update payload with operation and value\n * @returns A new BlockStorage with updated data\n */\nexport function updateStorageData<TValue = unknown>(\n storage: BlockStorage<TValue>,\n payload: MutateStoragePayload<TValue>,\n): BlockStorage<TValue> {\n switch (payload.operation) {\n case 'update-data':\n return { ...storage, __data: payload.value };\n default:\n throw new Error(`Unknown storage operation: ${(payload as { operation: string }).operation}`);\n }\n}\n\n/**\n * Gets the data version from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data version number\n */\nexport function getStorageDataVersion(storage: BlockStorage): number {\n return storage.__dataVersion;\n}\n\n/**\n * Updates the data version in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param version - The new version number\n * @returns A new BlockStorage with updated version\n */\nexport function updateStorageDataVersion<TState>(\n storage: BlockStorage<TState>,\n version: number,\n): BlockStorage<TState> {\n return { ...storage, __dataVersion: version };\n}\n\n// =============================================================================\n// Plugin Data Functions\n// =============================================================================\n\n/**\n * Gets plugin-specific data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns The plugin data or undefined if not set\n */\nexport function getPluginData<TData = unknown>(\n storage: BlockStorage,\n pluginName: string,\n): TData | undefined {\n const key: PluginKey = `@plugin/${pluginName}`;\n return storage[key] as TData | undefined;\n}\n\n/**\n * Sets plugin-specific data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @param data - The plugin data to store\n * @returns A new BlockStorage with updated plugin data\n */\nexport function setPluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n data: unknown,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n return { ...storage, [key]: data };\n}\n\n/**\n * Removes plugin-specific data from BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns A new BlockStorage with the plugin data removed\n */\nexport function removePluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n const { [key]: _, ...rest } = storage;\n return rest as BlockStorage<TState>;\n}\n\n/**\n * Gets all plugin names that have data stored\n *\n * @param storage - The BlockStorage instance\n * @returns Array of plugin names (without `@plugin/` prefix)\n */\nexport function getPluginNames(storage: BlockStorage): string[] {\n return Object.keys(storage)\n .filter((key): key is PluginKey => key.startsWith('@plugin/'))\n .map((key) => key.slice('@plugin/'.length));\n}\n\n// =============================================================================\n// Generic Storage Access\n// =============================================================================\n\n/**\n * Gets a value from BlockStorage by key\n *\n * @param storage - The BlockStorage instance\n * @param key - The key to retrieve\n * @returns The value at the given key\n */\nexport function getFromStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(storage: BlockStorage<TState>, key: K): BlockStorage<TState>[K] {\n return storage[key];\n}\n\n/**\n * Updates a value in BlockStorage by key (immutable)\n *\n * @param storage - The current BlockStorage\n * @param key - The key to update\n * @param value - The new value\n * @returns A new BlockStorage with the updated value\n */\nexport function updateStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(\n storage: BlockStorage<TState>,\n key: K,\n value: BlockStorage<TState>[K],\n): BlockStorage<TState> {\n return { ...storage, [key]: value };\n}\n\n// =============================================================================\n// Storage Handlers (for Phase 2 - Model-Level Customization)\n// =============================================================================\n\n/**\n * Interface for model-configurable storage operations.\n * These handlers allow block models to customize how storage is managed.\n */\nexport interface BlockStorageHandlers<TState = unknown> {\n /**\n * Called when setState is invoked - transforms the new state before storing.\n * Default behavior: replaces the state directly.\n *\n * @param currentStorage - The current BlockStorage\n * @param newState - The new state being set\n * @returns The updated BlockStorage\n */\n transformStateForStorage?: (\n currentStorage: BlockStorage<TState>,\n newState: TState,\n ) => BlockStorage<TState>;\n\n /**\n * Called when reading state for args derivation.\n * Default behavior: returns the state directly.\n *\n * @param storage - The current BlockStorage\n * @returns The state to use for args derivation\n */\n deriveStateForArgs?: (storage: BlockStorage<TState>) => TState;\n\n /**\n * Called during storage schema migration.\n * Default behavior: updates stateVersion only.\n *\n * @param oldStorage - The storage before migration\n * @param fromVersion - The version migrating from\n * @param toVersion - The version migrating to\n * @returns The migrated BlockStorage\n */\n migrateStorage?: (\n oldStorage: BlockStorage<TState>,\n fromVersion: number,\n toVersion: number,\n ) => BlockStorage<TState>;\n}\n\n/**\n * Default implementations of storage handlers\n */\nexport const defaultBlockStorageHandlers: Required<BlockStorageHandlers<unknown>> = {\n transformStateForStorage: <TState>(\n storage: BlockStorage<TState>,\n newState: TState,\n ): BlockStorage<TState> => updateStorageData(storage, { operation: 'update-data', value: newState }),\n\n deriveStateForArgs: <TState>(storage: BlockStorage<TState>): TState => getStorageData(storage),\n\n migrateStorage: <TState>(\n storage: BlockStorage<TState>,\n _fromVersion: number,\n toVersion: number,\n ): BlockStorage<TState> => updateStorageDataVersion(storage, toVersion),\n};\n\n/**\n * Merges custom handlers with defaults\n *\n * @param customHandlers - Custom handlers to merge\n * @returns Complete handlers with defaults for missing functions\n */\nexport function mergeBlockStorageHandlers<TState>(\n customHandlers?: BlockStorageHandlers<TState>,\n): Required<BlockStorageHandlers<TState>> {\n return {\n ...defaultBlockStorageHandlers,\n ...customHandlers,\n } as Required<BlockStorageHandlers<TState>>;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_storage.cjs","sources":["../src/block_storage.ts"],"sourcesContent":["/**\n * BlockStorage - Typed storage abstraction for block persistent data.\n *\n * This module provides:\n * - A typed structure for block storage with versioning and plugin support\n * - Utility functions for manipulating storage\n * - Handler interfaces for model-level customization\n *\n * @module block_storage\n */\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Discriminator key for BlockStorage format detection.\n * This unique hash-based key identifies data as BlockStorage vs legacy formats.\n */\nexport const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';\n\n/**\n * Current BlockStorage schema version.\n * Increment this when the storage structure itself changes (not block state migrations).\n */\nexport const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';\n\n/**\n * Type for valid schema versions\n */\nexport type BlockStorageSchemaVersion = 'v1'; // Add 'v2', 'v3', etc. as schema evolves\n\n/**\n * Plugin key type - keys starting with `@plugin/` are reserved for plugin data\n */\nexport type PluginKey = `@plugin/${string}`;\n\n/**\n * Core BlockStorage type that holds:\n * - __pl_a7f3e2b9__: Schema version (discriminator key identifies BlockStorage format)\n * - __dataVersion: Version number for block data migrations\n * - __data: The block's user-facing data (state)\n * - @plugin/*: Optional plugin-specific data\n */\nexport type BlockStorage<TState = unknown> = {\n /** Schema version - the key itself is the discriminator */\n readonly [BLOCK_STORAGE_KEY]: BlockStorageSchemaVersion;\n /** Version of the block data, used for migrations */\n __dataVersion: number;\n /** The block's user-facing data (state) */\n __data: TState;\n} & {\n /** Plugin-specific data, keyed by `@plugin/<pluginName>` */\n [K in PluginKey]?: unknown;\n};\n\n/**\n * Type guard to check if a value is a valid BlockStorage object.\n * Checks for the discriminator key and valid schema version.\n */\nexport function isBlockStorage(value: unknown): value is BlockStorage {\n if (value === null || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n const schemaVersion = obj[BLOCK_STORAGE_KEY];\n // Currently only 'v1' is valid, but this allows future versions\n return schemaVersion === 'v1'; // Add more versions as schema evolves\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates a BlockStorage with the given initial data\n *\n * @param initialData - The initial data value (defaults to empty object)\n * @param version - The initial data version (defaults to 1)\n * @returns A new BlockStorage instance with discriminator key\n */\nexport function createBlockStorage<TState = unknown>(\n initialData: TState = {} as TState,\n version: number = 1,\n): BlockStorage<TState> {\n return {\n [BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,\n __dataVersion: version,\n __data: initialData,\n };\n}\n\n/**\n * Normalizes raw storage data to BlockStorage format.\n * If the input is already a BlockStorage, returns it as-is.\n * If the input is legacy format (raw state), wraps it in BlockStorage structure.\n *\n * @param raw - Raw storage data (may be legacy format or BlockStorage)\n * @returns Normalized BlockStorage\n */\nexport function normalizeBlockStorage<TState = unknown>(raw: unknown): BlockStorage<TState> {\n if (isBlockStorage(raw)) {\n return raw as BlockStorage<TState>;\n }\n // Legacy format: raw is the state directly\n return createBlockStorage(raw as TState, 1);\n}\n\n// =============================================================================\n// Data Access & Update Functions\n// =============================================================================\n\n/**\n * Gets the data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data value\n */\nexport function getStorageData<TState>(storage: BlockStorage<TState>): TState {\n return storage.__data;\n}\n\n/**\n * Derives data from raw block storage.\n * This function is meant to be called from sdk/ui-vue to extract\n * user-facing data from the raw storage returned by the middle layer.\n *\n * The middle layer returns raw storage (opaque to it), and the UI\n * uses this function to derive the actual data value.\n *\n * @param rawStorage - Raw storage data from middle layer (may be any format)\n * @returns The extracted data value, or undefined if storage is undefined/null\n */\nexport function deriveDataFromStorage<TData = unknown>(\n rawStorage: unknown,\n): TData {\n // Normalize to BlockStorage format (handles legacy formats too)\n const storage = normalizeBlockStorage<TData>(rawStorage);\n return getStorageData(storage);\n}\n\n/** Payload for storage mutation operations. SDK defines specific operations. */\nexport type MutateStoragePayload<T = unknown> = { operation: 'update-data'; value: T };\n\n/**\n * Updates the data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param payload - The update payload with operation and value\n * @returns A new BlockStorage with updated data\n */\nexport function updateStorageData<TValue = unknown>(\n storage: BlockStorage<TValue>,\n payload: MutateStoragePayload<TValue>,\n): BlockStorage<TValue> {\n switch (payload.operation) {\n case 'update-data':\n return { ...storage, __data: payload.value };\n default:\n throw new Error(`Unknown storage operation: ${(payload as { operation: string }).operation}`);\n }\n}\n\n/**\n * Gets the data version from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data version number\n */\nexport function getStorageDataVersion(storage: BlockStorage): number {\n return storage.__dataVersion;\n}\n\n/**\n * Updates the data version in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param version - The new version number\n * @returns A new BlockStorage with updated version\n */\nexport function updateStorageDataVersion<TState>(\n storage: BlockStorage<TState>,\n version: number,\n): BlockStorage<TState> {\n return { ...storage, __dataVersion: version };\n}\n\n/**\n * Storage debug view returned by __pl_storage_debugView callback.\n * Used by developer tools to display block storage info.\n */\nexport interface StorageDebugView {\n /** Current data version (1-based, starts at 1) */\n dataVersion: number;\n /** Raw data payload stored in BlockStorage */\n data: unknown;\n}\n\n// =============================================================================\n// Plugin Data Functions\n// =============================================================================\n\n/**\n * Gets plugin-specific data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns The plugin data or undefined if not set\n */\nexport function getPluginData<TData = unknown>(\n storage: BlockStorage,\n pluginName: string,\n): TData | undefined {\n const key: PluginKey = `@plugin/${pluginName}`;\n return storage[key] as TData | undefined;\n}\n\n/**\n * Sets plugin-specific data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @param data - The plugin data to store\n * @returns A new BlockStorage with updated plugin data\n */\nexport function setPluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n data: unknown,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n return { ...storage, [key]: data };\n}\n\n/**\n * Removes plugin-specific data from BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns A new BlockStorage with the plugin data removed\n */\nexport function removePluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n const { [key]: _, ...rest } = storage;\n return rest as BlockStorage<TState>;\n}\n\n/**\n * Gets all plugin names that have data stored\n *\n * @param storage - The BlockStorage instance\n * @returns Array of plugin names (without `@plugin/` prefix)\n */\nexport function getPluginNames(storage: BlockStorage): string[] {\n return Object.keys(storage)\n .filter((key): key is PluginKey => key.startsWith('@plugin/'))\n .map((key) => key.slice('@plugin/'.length));\n}\n\n// =============================================================================\n// Generic Storage Access\n// =============================================================================\n\n/**\n * Gets a value from BlockStorage by key\n *\n * @param storage - The BlockStorage instance\n * @param key - The key to retrieve\n * @returns The value at the given key\n */\nexport function getFromStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(storage: BlockStorage<TState>, key: K): BlockStorage<TState>[K] {\n return storage[key];\n}\n\n/**\n * Updates a value in BlockStorage by key (immutable)\n *\n * @param storage - The current BlockStorage\n * @param key - The key to update\n * @param value - The new value\n * @returns A new BlockStorage with the updated value\n */\nexport function updateStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(\n storage: BlockStorage<TState>,\n key: K,\n value: BlockStorage<TState>[K],\n): BlockStorage<TState> {\n return { ...storage, [key]: value };\n}\n\n// =============================================================================\n// Storage Handlers (for Phase 2 - Model-Level Customization)\n// =============================================================================\n\n/**\n * Interface for model-configurable storage operations.\n * These handlers allow block models to customize how storage is managed.\n */\nexport interface BlockStorageHandlers<TState = unknown> {\n /**\n * Called when setState is invoked - transforms the new state before storing.\n * Default behavior: replaces the state directly.\n *\n * @param currentStorage - The current BlockStorage\n * @param newState - The new state being set\n * @returns The updated BlockStorage\n */\n transformStateForStorage?: (\n currentStorage: BlockStorage<TState>,\n newState: TState,\n ) => BlockStorage<TState>;\n\n /**\n * Called when reading state for args derivation.\n * Default behavior: returns the state directly.\n *\n * @param storage - The current BlockStorage\n * @returns The state to use for args derivation\n */\n deriveStateForArgs?: (storage: BlockStorage<TState>) => TState;\n\n /**\n * Called during storage schema migration.\n * Default behavior: updates stateVersion only.\n *\n * @param oldStorage - The storage before migration\n * @param fromVersion - The version migrating from\n * @param toVersion - The version migrating to\n * @returns The migrated BlockStorage\n */\n migrateStorage?: (\n oldStorage: BlockStorage<TState>,\n fromVersion: number,\n toVersion: number,\n ) => BlockStorage<TState>;\n}\n\n/**\n * Default implementations of storage handlers\n */\nexport const defaultBlockStorageHandlers: Required<BlockStorageHandlers<unknown>> = {\n transformStateForStorage: <TState>(\n storage: BlockStorage<TState>,\n newState: TState,\n ): BlockStorage<TState> => updateStorageData(storage, { operation: 'update-data', value: newState }),\n\n deriveStateForArgs: <TState>(storage: BlockStorage<TState>): TState => getStorageData(storage),\n\n migrateStorage: <TState>(\n storage: BlockStorage<TState>,\n _fromVersion: number,\n toVersion: number,\n ): BlockStorage<TState> => updateStorageDataVersion(storage, toVersion),\n};\n\n/**\n * Merges custom handlers with defaults\n *\n * @param customHandlers - Custom handlers to merge\n * @returns Complete handlers with defaults for missing functions\n */\nexport function mergeBlockStorageHandlers<TState>(\n customHandlers?: BlockStorageHandlers<TState>,\n): Required<BlockStorageHandlers<TState>> {\n return {\n ...defaultBlockStorageHandlers,\n ...customHandlers,\n } as Required<BlockStorageHandlers<TState>>;\n}\n"],"names":[],"mappings":"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"}
@@ -112,6 +112,16 @@ export declare function getStorageDataVersion(storage: BlockStorage): number;
112
112
  * @returns A new BlockStorage with updated version
113
113
  */
114
114
  export declare function updateStorageDataVersion<TState>(storage: BlockStorage<TState>, version: number): BlockStorage<TState>;
115
+ /**
116
+ * Storage debug view returned by __pl_storage_debugView callback.
117
+ * Used by developer tools to display block storage info.
118
+ */
119
+ export interface StorageDebugView {
120
+ /** Current data version (1-based, starts at 1) */
121
+ dataVersion: number;
122
+ /** Raw data payload stored in BlockStorage */
123
+ data: unknown;
124
+ }
115
125
  /**
116
126
  * Gets plugin-specific data from BlockStorage
117
127
  *
@@ -1 +1 @@
1
- {"version":3,"file":"block_storage.d.ts","sourceRoot":"","sources":["../src/block_storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_storage.d.ts","sourceRoot":"","sources":["../src/block_storage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"block_storage.js","sources":["../src/block_storage.ts"],"sourcesContent":["/**\n * BlockStorage - Typed storage abstraction for block persistent data.\n *\n * This module provides:\n * - A typed structure for block storage with versioning and plugin support\n * - Utility functions for manipulating storage\n * - Handler interfaces for model-level customization\n *\n * @module block_storage\n */\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Discriminator key for BlockStorage format detection.\n * This unique hash-based key identifies data as BlockStorage vs legacy formats.\n */\nexport const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';\n\n/**\n * Current BlockStorage schema version.\n * Increment this when the storage structure itself changes (not block state migrations).\n */\nexport const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';\n\n/**\n * Type for valid schema versions\n */\nexport type BlockStorageSchemaVersion = 'v1'; // Add 'v2', 'v3', etc. as schema evolves\n\n/**\n * Plugin key type - keys starting with `@plugin/` are reserved for plugin data\n */\nexport type PluginKey = `@plugin/${string}`;\n\n/**\n * Core BlockStorage type that holds:\n * - __pl_a7f3e2b9__: Schema version (discriminator key identifies BlockStorage format)\n * - __dataVersion: Version number for block data migrations\n * - __data: The block's user-facing data (state)\n * - @plugin/*: Optional plugin-specific data\n */\nexport type BlockStorage<TState = unknown> = {\n /** Schema version - the key itself is the discriminator */\n readonly [BLOCK_STORAGE_KEY]: BlockStorageSchemaVersion;\n /** Version of the block data, used for migrations */\n __dataVersion: number;\n /** The block's user-facing data (state) */\n __data: TState;\n} & {\n /** Plugin-specific data, keyed by `@plugin/<pluginName>` */\n [K in PluginKey]?: unknown;\n};\n\n/**\n * Type guard to check if a value is a valid BlockStorage object.\n * Checks for the discriminator key and valid schema version.\n */\nexport function isBlockStorage(value: unknown): value is BlockStorage {\n if (value === null || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n const schemaVersion = obj[BLOCK_STORAGE_KEY];\n // Currently only 'v1' is valid, but this allows future versions\n return schemaVersion === 'v1'; // Add more versions as schema evolves\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates a BlockStorage with the given initial data\n *\n * @param initialData - The initial data value (defaults to empty object)\n * @param version - The initial data version (defaults to 1)\n * @returns A new BlockStorage instance with discriminator key\n */\nexport function createBlockStorage<TState = unknown>(\n initialData: TState = {} as TState,\n version: number = 1,\n): BlockStorage<TState> {\n return {\n [BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,\n __dataVersion: version,\n __data: initialData,\n };\n}\n\n/**\n * Normalizes raw storage data to BlockStorage format.\n * If the input is already a BlockStorage, returns it as-is.\n * If the input is legacy format (raw state), wraps it in BlockStorage structure.\n *\n * @param raw - Raw storage data (may be legacy format or BlockStorage)\n * @returns Normalized BlockStorage\n */\nexport function normalizeBlockStorage<TState = unknown>(raw: unknown): BlockStorage<TState> {\n if (isBlockStorage(raw)) {\n return raw as BlockStorage<TState>;\n }\n // Legacy format: raw is the state directly\n return createBlockStorage(raw as TState, 1);\n}\n\n// =============================================================================\n// Data Access & Update Functions\n// =============================================================================\n\n/**\n * Gets the data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data value\n */\nexport function getStorageData<TState>(storage: BlockStorage<TState>): TState {\n return storage.__data;\n}\n\n/**\n * Derives data from raw block storage.\n * This function is meant to be called from sdk/ui-vue to extract\n * user-facing data from the raw storage returned by the middle layer.\n *\n * The middle layer returns raw storage (opaque to it), and the UI\n * uses this function to derive the actual data value.\n *\n * @param rawStorage - Raw storage data from middle layer (may be any format)\n * @returns The extracted data value, or undefined if storage is undefined/null\n */\nexport function deriveDataFromStorage<TData = unknown>(\n rawStorage: unknown,\n): TData {\n // Normalize to BlockStorage format (handles legacy formats too)\n const storage = normalizeBlockStorage<TData>(rawStorage);\n return getStorageData(storage);\n}\n\n/** Payload for storage mutation operations. SDK defines specific operations. */\nexport type MutateStoragePayload<T = unknown> = { operation: 'update-data'; value: T };\n\n/**\n * Updates the data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param payload - The update payload with operation and value\n * @returns A new BlockStorage with updated data\n */\nexport function updateStorageData<TValue = unknown>(\n storage: BlockStorage<TValue>,\n payload: MutateStoragePayload<TValue>,\n): BlockStorage<TValue> {\n switch (payload.operation) {\n case 'update-data':\n return { ...storage, __data: payload.value };\n default:\n throw new Error(`Unknown storage operation: ${(payload as { operation: string }).operation}`);\n }\n}\n\n/**\n * Gets the data version from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data version number\n */\nexport function getStorageDataVersion(storage: BlockStorage): number {\n return storage.__dataVersion;\n}\n\n/**\n * Updates the data version in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param version - The new version number\n * @returns A new BlockStorage with updated version\n */\nexport function updateStorageDataVersion<TState>(\n storage: BlockStorage<TState>,\n version: number,\n): BlockStorage<TState> {\n return { ...storage, __dataVersion: version };\n}\n\n// =============================================================================\n// Plugin Data Functions\n// =============================================================================\n\n/**\n * Gets plugin-specific data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns The plugin data or undefined if not set\n */\nexport function getPluginData<TData = unknown>(\n storage: BlockStorage,\n pluginName: string,\n): TData | undefined {\n const key: PluginKey = `@plugin/${pluginName}`;\n return storage[key] as TData | undefined;\n}\n\n/**\n * Sets plugin-specific data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @param data - The plugin data to store\n * @returns A new BlockStorage with updated plugin data\n */\nexport function setPluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n data: unknown,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n return { ...storage, [key]: data };\n}\n\n/**\n * Removes plugin-specific data from BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns A new BlockStorage with the plugin data removed\n */\nexport function removePluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n const { [key]: _, ...rest } = storage;\n return rest as BlockStorage<TState>;\n}\n\n/**\n * Gets all plugin names that have data stored\n *\n * @param storage - The BlockStorage instance\n * @returns Array of plugin names (without `@plugin/` prefix)\n */\nexport function getPluginNames(storage: BlockStorage): string[] {\n return Object.keys(storage)\n .filter((key): key is PluginKey => key.startsWith('@plugin/'))\n .map((key) => key.slice('@plugin/'.length));\n}\n\n// =============================================================================\n// Generic Storage Access\n// =============================================================================\n\n/**\n * Gets a value from BlockStorage by key\n *\n * @param storage - The BlockStorage instance\n * @param key - The key to retrieve\n * @returns The value at the given key\n */\nexport function getFromStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(storage: BlockStorage<TState>, key: K): BlockStorage<TState>[K] {\n return storage[key];\n}\n\n/**\n * Updates a value in BlockStorage by key (immutable)\n *\n * @param storage - The current BlockStorage\n * @param key - The key to update\n * @param value - The new value\n * @returns A new BlockStorage with the updated value\n */\nexport function updateStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(\n storage: BlockStorage<TState>,\n key: K,\n value: BlockStorage<TState>[K],\n): BlockStorage<TState> {\n return { ...storage, [key]: value };\n}\n\n// =============================================================================\n// Storage Handlers (for Phase 2 - Model-Level Customization)\n// =============================================================================\n\n/**\n * Interface for model-configurable storage operations.\n * These handlers allow block models to customize how storage is managed.\n */\nexport interface BlockStorageHandlers<TState = unknown> {\n /**\n * Called when setState is invoked - transforms the new state before storing.\n * Default behavior: replaces the state directly.\n *\n * @param currentStorage - The current BlockStorage\n * @param newState - The new state being set\n * @returns The updated BlockStorage\n */\n transformStateForStorage?: (\n currentStorage: BlockStorage<TState>,\n newState: TState,\n ) => BlockStorage<TState>;\n\n /**\n * Called when reading state for args derivation.\n * Default behavior: returns the state directly.\n *\n * @param storage - The current BlockStorage\n * @returns The state to use for args derivation\n */\n deriveStateForArgs?: (storage: BlockStorage<TState>) => TState;\n\n /**\n * Called during storage schema migration.\n * Default behavior: updates stateVersion only.\n *\n * @param oldStorage - The storage before migration\n * @param fromVersion - The version migrating from\n * @param toVersion - The version migrating to\n * @returns The migrated BlockStorage\n */\n migrateStorage?: (\n oldStorage: BlockStorage<TState>,\n fromVersion: number,\n toVersion: number,\n ) => BlockStorage<TState>;\n}\n\n/**\n * Default implementations of storage handlers\n */\nexport const defaultBlockStorageHandlers: Required<BlockStorageHandlers<unknown>> = {\n transformStateForStorage: <TState>(\n storage: BlockStorage<TState>,\n newState: TState,\n ): BlockStorage<TState> => updateStorageData(storage, { operation: 'update-data', value: newState }),\n\n deriveStateForArgs: <TState>(storage: BlockStorage<TState>): TState => getStorageData(storage),\n\n migrateStorage: <TState>(\n storage: BlockStorage<TState>,\n _fromVersion: number,\n toVersion: number,\n ): BlockStorage<TState> => updateStorageDataVersion(storage, toVersion),\n};\n\n/**\n * Merges custom handlers with defaults\n *\n * @param customHandlers - Custom handlers to merge\n * @returns Complete handlers with defaults for missing functions\n */\nexport function mergeBlockStorageHandlers<TState>(\n customHandlers?: BlockStorageHandlers<TState>,\n): Required<BlockStorageHandlers<TState>> {\n return {\n ...defaultBlockStorageHandlers,\n ...customHandlers,\n } as Required<BlockStorageHandlers<TState>>;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_storage.js","sources":["../src/block_storage.ts"],"sourcesContent":["/**\n * BlockStorage - Typed storage abstraction for block persistent data.\n *\n * This module provides:\n * - A typed structure for block storage with versioning and plugin support\n * - Utility functions for manipulating storage\n * - Handler interfaces for model-level customization\n *\n * @module block_storage\n */\n\n// =============================================================================\n// Core Types\n// =============================================================================\n\n/**\n * Discriminator key for BlockStorage format detection.\n * This unique hash-based key identifies data as BlockStorage vs legacy formats.\n */\nexport const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';\n\n/**\n * Current BlockStorage schema version.\n * Increment this when the storage structure itself changes (not block state migrations).\n */\nexport const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';\n\n/**\n * Type for valid schema versions\n */\nexport type BlockStorageSchemaVersion = 'v1'; // Add 'v2', 'v3', etc. as schema evolves\n\n/**\n * Plugin key type - keys starting with `@plugin/` are reserved for plugin data\n */\nexport type PluginKey = `@plugin/${string}`;\n\n/**\n * Core BlockStorage type that holds:\n * - __pl_a7f3e2b9__: Schema version (discriminator key identifies BlockStorage format)\n * - __dataVersion: Version number for block data migrations\n * - __data: The block's user-facing data (state)\n * - @plugin/*: Optional plugin-specific data\n */\nexport type BlockStorage<TState = unknown> = {\n /** Schema version - the key itself is the discriminator */\n readonly [BLOCK_STORAGE_KEY]: BlockStorageSchemaVersion;\n /** Version of the block data, used for migrations */\n __dataVersion: number;\n /** The block's user-facing data (state) */\n __data: TState;\n} & {\n /** Plugin-specific data, keyed by `@plugin/<pluginName>` */\n [K in PluginKey]?: unknown;\n};\n\n/**\n * Type guard to check if a value is a valid BlockStorage object.\n * Checks for the discriminator key and valid schema version.\n */\nexport function isBlockStorage(value: unknown): value is BlockStorage {\n if (value === null || typeof value !== 'object') return false;\n const obj = value as Record<string, unknown>;\n const schemaVersion = obj[BLOCK_STORAGE_KEY];\n // Currently only 'v1' is valid, but this allows future versions\n return schemaVersion === 'v1'; // Add more versions as schema evolves\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates a BlockStorage with the given initial data\n *\n * @param initialData - The initial data value (defaults to empty object)\n * @param version - The initial data version (defaults to 1)\n * @returns A new BlockStorage instance with discriminator key\n */\nexport function createBlockStorage<TState = unknown>(\n initialData: TState = {} as TState,\n version: number = 1,\n): BlockStorage<TState> {\n return {\n [BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,\n __dataVersion: version,\n __data: initialData,\n };\n}\n\n/**\n * Normalizes raw storage data to BlockStorage format.\n * If the input is already a BlockStorage, returns it as-is.\n * If the input is legacy format (raw state), wraps it in BlockStorage structure.\n *\n * @param raw - Raw storage data (may be legacy format or BlockStorage)\n * @returns Normalized BlockStorage\n */\nexport function normalizeBlockStorage<TState = unknown>(raw: unknown): BlockStorage<TState> {\n if (isBlockStorage(raw)) {\n return raw as BlockStorage<TState>;\n }\n // Legacy format: raw is the state directly\n return createBlockStorage(raw as TState, 1);\n}\n\n// =============================================================================\n// Data Access & Update Functions\n// =============================================================================\n\n/**\n * Gets the data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data value\n */\nexport function getStorageData<TState>(storage: BlockStorage<TState>): TState {\n return storage.__data;\n}\n\n/**\n * Derives data from raw block storage.\n * This function is meant to be called from sdk/ui-vue to extract\n * user-facing data from the raw storage returned by the middle layer.\n *\n * The middle layer returns raw storage (opaque to it), and the UI\n * uses this function to derive the actual data value.\n *\n * @param rawStorage - Raw storage data from middle layer (may be any format)\n * @returns The extracted data value, or undefined if storage is undefined/null\n */\nexport function deriveDataFromStorage<TData = unknown>(\n rawStorage: unknown,\n): TData {\n // Normalize to BlockStorage format (handles legacy formats too)\n const storage = normalizeBlockStorage<TData>(rawStorage);\n return getStorageData(storage);\n}\n\n/** Payload for storage mutation operations. SDK defines specific operations. */\nexport type MutateStoragePayload<T = unknown> = { operation: 'update-data'; value: T };\n\n/**\n * Updates the data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param payload - The update payload with operation and value\n * @returns A new BlockStorage with updated data\n */\nexport function updateStorageData<TValue = unknown>(\n storage: BlockStorage<TValue>,\n payload: MutateStoragePayload<TValue>,\n): BlockStorage<TValue> {\n switch (payload.operation) {\n case 'update-data':\n return { ...storage, __data: payload.value };\n default:\n throw new Error(`Unknown storage operation: ${(payload as { operation: string }).operation}`);\n }\n}\n\n/**\n * Gets the data version from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @returns The data version number\n */\nexport function getStorageDataVersion(storage: BlockStorage): number {\n return storage.__dataVersion;\n}\n\n/**\n * Updates the data version in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param version - The new version number\n * @returns A new BlockStorage with updated version\n */\nexport function updateStorageDataVersion<TState>(\n storage: BlockStorage<TState>,\n version: number,\n): BlockStorage<TState> {\n return { ...storage, __dataVersion: version };\n}\n\n/**\n * Storage debug view returned by __pl_storage_debugView callback.\n * Used by developer tools to display block storage info.\n */\nexport interface StorageDebugView {\n /** Current data version (1-based, starts at 1) */\n dataVersion: number;\n /** Raw data payload stored in BlockStorage */\n data: unknown;\n}\n\n// =============================================================================\n// Plugin Data Functions\n// =============================================================================\n\n/**\n * Gets plugin-specific data from BlockStorage\n *\n * @param storage - The BlockStorage instance\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns The plugin data or undefined if not set\n */\nexport function getPluginData<TData = unknown>(\n storage: BlockStorage,\n pluginName: string,\n): TData | undefined {\n const key: PluginKey = `@plugin/${pluginName}`;\n return storage[key] as TData | undefined;\n}\n\n/**\n * Sets plugin-specific data in BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @param data - The plugin data to store\n * @returns A new BlockStorage with updated plugin data\n */\nexport function setPluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n data: unknown,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n return { ...storage, [key]: data };\n}\n\n/**\n * Removes plugin-specific data from BlockStorage (immutable)\n *\n * @param storage - The current BlockStorage\n * @param pluginName - The plugin name (without `@plugin/` prefix)\n * @returns A new BlockStorage with the plugin data removed\n */\nexport function removePluginData<TState>(\n storage: BlockStorage<TState>,\n pluginName: string,\n): BlockStorage<TState> {\n const key: PluginKey = `@plugin/${pluginName}`;\n const { [key]: _, ...rest } = storage;\n return rest as BlockStorage<TState>;\n}\n\n/**\n * Gets all plugin names that have data stored\n *\n * @param storage - The BlockStorage instance\n * @returns Array of plugin names (without `@plugin/` prefix)\n */\nexport function getPluginNames(storage: BlockStorage): string[] {\n return Object.keys(storage)\n .filter((key): key is PluginKey => key.startsWith('@plugin/'))\n .map((key) => key.slice('@plugin/'.length));\n}\n\n// =============================================================================\n// Generic Storage Access\n// =============================================================================\n\n/**\n * Gets a value from BlockStorage by key\n *\n * @param storage - The BlockStorage instance\n * @param key - The key to retrieve\n * @returns The value at the given key\n */\nexport function getFromStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(storage: BlockStorage<TState>, key: K): BlockStorage<TState>[K] {\n return storage[key];\n}\n\n/**\n * Updates a value in BlockStorage by key (immutable)\n *\n * @param storage - The current BlockStorage\n * @param key - The key to update\n * @param value - The new value\n * @returns A new BlockStorage with the updated value\n */\nexport function updateStorage<\n TState,\n K extends keyof BlockStorage<TState>,\n>(\n storage: BlockStorage<TState>,\n key: K,\n value: BlockStorage<TState>[K],\n): BlockStorage<TState> {\n return { ...storage, [key]: value };\n}\n\n// =============================================================================\n// Storage Handlers (for Phase 2 - Model-Level Customization)\n// =============================================================================\n\n/**\n * Interface for model-configurable storage operations.\n * These handlers allow block models to customize how storage is managed.\n */\nexport interface BlockStorageHandlers<TState = unknown> {\n /**\n * Called when setState is invoked - transforms the new state before storing.\n * Default behavior: replaces the state directly.\n *\n * @param currentStorage - The current BlockStorage\n * @param newState - The new state being set\n * @returns The updated BlockStorage\n */\n transformStateForStorage?: (\n currentStorage: BlockStorage<TState>,\n newState: TState,\n ) => BlockStorage<TState>;\n\n /**\n * Called when reading state for args derivation.\n * Default behavior: returns the state directly.\n *\n * @param storage - The current BlockStorage\n * @returns The state to use for args derivation\n */\n deriveStateForArgs?: (storage: BlockStorage<TState>) => TState;\n\n /**\n * Called during storage schema migration.\n * Default behavior: updates stateVersion only.\n *\n * @param oldStorage - The storage before migration\n * @param fromVersion - The version migrating from\n * @param toVersion - The version migrating to\n * @returns The migrated BlockStorage\n */\n migrateStorage?: (\n oldStorage: BlockStorage<TState>,\n fromVersion: number,\n toVersion: number,\n ) => BlockStorage<TState>;\n}\n\n/**\n * Default implementations of storage handlers\n */\nexport const defaultBlockStorageHandlers: Required<BlockStorageHandlers<unknown>> = {\n transformStateForStorage: <TState>(\n storage: BlockStorage<TState>,\n newState: TState,\n ): BlockStorage<TState> => updateStorageData(storage, { operation: 'update-data', value: newState }),\n\n deriveStateForArgs: <TState>(storage: BlockStorage<TState>): TState => getStorageData(storage),\n\n migrateStorage: <TState>(\n storage: BlockStorage<TState>,\n _fromVersion: number,\n toVersion: number,\n ): BlockStorage<TState> => updateStorageDataVersion(storage, toVersion),\n};\n\n/**\n * Merges custom handlers with defaults\n *\n * @param customHandlers - Custom handlers to merge\n * @returns Complete handlers with defaults for missing functions\n */\nexport function mergeBlockStorageHandlers<TState>(\n customHandlers?: BlockStorageHandlers<TState>,\n): Required<BlockStorageHandlers<TState>> {\n return {\n ...defaultBlockStorageHandlers,\n ...customHandlers,\n } as Required<BlockStorageHandlers<TState>>;\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var block_storage = require('./block_storage.cjs');
4
+ var plModelCommon = require('@milaboratories/pl-model-common');
4
5
  var internal = require('./internal.cjs');
5
6
 
6
7
  /**
@@ -11,9 +12,8 @@ var internal = require('./internal.cjs');
11
12
  * directly - they only see `state`.
12
13
  *
13
14
  * Registered callbacks (all prefixed with `__pl_` for internal SDK use):
14
- * - `__pl_storage_normalize`: (rawStorage) => { storage, data }
15
15
  * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
16
- * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
16
+ * - `__pl_storage_debugView`: (rawStorage) => JSON string with storage debug view
17
17
  * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
18
18
  * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
19
19
  * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
@@ -97,31 +97,28 @@ function isLegacyModelV1ApiFormat(data) {
97
97
  // =============================================================================
98
98
  // Auto-register internal callbacks when module is loaded in VM
99
99
  // =============================================================================
100
- // Register normalize callback
101
- internal.tryRegisterCallback('__pl_storage_normalize', (rawStorage) => {
102
- return normalizeStorage(rawStorage);
103
- });
104
100
  // Register apply update callback (requires existing storage)
105
101
  internal.tryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson, payload) => {
106
102
  return applyStorageUpdate(currentStorageJson, payload);
107
103
  });
108
104
  /**
109
- * Gets storage info from raw storage data.
110
- * Returns structured info about the storage state.
105
+ * Gets storage debug view from raw storage data.
106
+ * Returns structured debug info about the storage state.
111
107
  *
112
108
  * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
113
- * @returns JSON string with storage info
109
+ * @returns JSON string with storage debug view
114
110
  */
115
- function getStorageInfo(rawStorage) {
111
+ function getStorageDebugView(rawStorage) {
116
112
  const { storage } = normalizeStorage(rawStorage);
117
- const info = {
113
+ const debugView = {
118
114
  dataVersion: storage.__dataVersion,
115
+ data: storage.__data,
119
116
  };
120
- return JSON.stringify(info);
117
+ return plModelCommon.stringifyJson(debugView);
121
118
  }
122
- // Register get info callback
123
- internal.tryRegisterCallback('__pl_storage_getInfo', (rawStorage) => {
124
- return getStorageInfo(rawStorage);
119
+ // Register debug view callback
120
+ internal.tryRegisterCallback('__pl_storage_debugView', (rawStorage) => {
121
+ return getStorageDebugView(rawStorage);
125
122
  });
126
123
  /**
127
124
  * Runs storage migration using the DataModel's upgrade callback.
@@ -1 +1 @@
1
- {"version":3,"file":"block_storage_vm.cjs","sources":["../src/block_storage_vm.ts"],"sourcesContent":["/**\n * BlockStorage VM Integration - Internal module for VM-based storage operations.\n *\n * This module auto-registers internal callbacks that the middle layer can invoke\n * to perform storage transformations. Block developers never interact with these\n * directly - they only see `state`.\n *\n * Registered callbacks (all prefixed with `__pl_` for internal SDK use):\n * - `__pl_storage_normalize`: (rawStorage) => { storage, data }\n * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson\n * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info\n * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult\n * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult\n * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult\n *\n * Callbacks registered by DataModel.registerCallbacks():\n * - `__pl_data_initial`: () => initial data\n * - `__pl_data_upgrade`: (versioned) => UpgradeResult\n * - `__pl_storage_initial`: () => initial BlockStorage as JSON string\n *\n * @module block_storage_vm\n * @internal\n */\n\nimport {\n BLOCK_STORAGE_KEY,\n BLOCK_STORAGE_SCHEMA_VERSION,\n type BlockStorage,\n type MutateStoragePayload,\n createBlockStorage,\n getStorageData,\n isBlockStorage,\n updateStorageData,\n} from './block_storage';\nimport { tryGetCfgRenderCtx, tryRegisterCallback } from './internal';\n\n/**\n * Result of storage normalization\n */\nexport interface NormalizeStorageResult {\n /** The normalized BlockStorage object */\n storage: BlockStorage;\n /** The extracted data (what developers see) */\n data: unknown;\n}\n\n/**\n * Normalizes raw storage data and extracts state.\n * Handles all formats:\n * - New BlockStorage format (has discriminator)\n * - Legacy V1/V2 format ({ args, uiState })\n * - Raw V3 state (any other format)\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns Object with normalized storage and extracted state\n */\nfunction normalizeStorage(rawStorage: unknown): NormalizeStorageResult {\n // Handle undefined/null\n if (rawStorage === undefined || rawStorage === null) {\n const storage = createBlockStorage({});\n return { storage, data: {} };\n }\n\n // Parse JSON string if needed\n let parsed = rawStorage;\n if (typeof rawStorage === 'string') {\n try {\n parsed = JSON.parse(rawStorage);\n } catch {\n // If parsing fails, treat string as the data\n const storage = createBlockStorage(rawStorage);\n return { storage, data: rawStorage };\n }\n }\n\n // Check for BlockStorage format (has discriminator)\n if (isBlockStorage(parsed)) {\n return { storage: parsed, data: getStorageData(parsed) };\n }\n\n // Check for legacy V1/V2 format: { args, uiState }\n if (isLegacyModelV1ApiFormat(parsed)) {\n // For legacy format, the whole object IS the data\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n }\n\n // Raw V3 data - wrap it\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n}\n\n/**\n * Applies a state update to existing storage.\n * Used when setData is called from the frontend.\n *\n * @param currentStorageJson - Current storage as JSON string (must be defined)\n * @param newData - New data from application\n * @returns Updated storage as JSON string\n */\nfunction applyStorageUpdate(currentStorageJson: string, payload: MutateStoragePayload): string {\n const { storage: currentStorage } = normalizeStorage(currentStorageJson);\n\n // Update data while preserving other storage fields (version, plugins)\n const updatedStorage = updateStorageData(currentStorage, payload);\n\n return JSON.stringify(updatedStorage);\n}\n\n/**\n * Checks if data is in legacy Model API v1 format.\n * Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.\n */\nfunction isLegacyModelV1ApiFormat(data: unknown): data is { args?: unknown } {\n if (data === null || typeof data !== 'object') return false;\n if (isBlockStorage(data)) return false;\n\n const obj = data as Record<string, unknown>;\n return 'args' in obj;\n}\n\n// =============================================================================\n// Auto-register internal callbacks when module is loaded in VM\n// =============================================================================\n\n// Register normalize callback\ntryRegisterCallback('__pl_storage_normalize', (rawStorage: unknown) => {\n return normalizeStorage(rawStorage);\n});\n\n// Register apply update callback (requires existing storage)\ntryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson: string, payload: MutateStoragePayload) => {\n return applyStorageUpdate(currentStorageJson, payload);\n});\n\n/**\n * Storage info result returned by __pl_storage_getInfo callback.\n */\nexport interface StorageInfo {\n /** Current data version (1-based, starts at 1) */\n dataVersion: number;\n}\n\n/**\n * Gets storage info from raw storage data.\n * Returns structured info about the storage state.\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns JSON string with storage info\n */\nfunction getStorageInfo(rawStorage: unknown): string {\n const { storage } = normalizeStorage(rawStorage);\n const info: StorageInfo = {\n dataVersion: storage.__dataVersion,\n };\n return JSON.stringify(info);\n}\n\n// Register get info callback\ntryRegisterCallback('__pl_storage_getInfo', (rawStorage: unknown) => {\n return getStorageInfo(rawStorage);\n});\n\n// =============================================================================\n// Migration Support\n// =============================================================================\n\n/**\n * Result of storage migration.\n * Returned by __pl_storage_migrate callback.\n *\n * - Error result: { error: string } - serious failure (no context, etc.)\n * - Success result: { newStorageJson: string, info: string, warn?: string } - migration succeeded or reset to initial\n */\nexport type MigrationResult =\n | { error: string }\n | { error?: undefined; newStorageJson: string; info: string; warn?: string };\n\n/** Result from Migrator.upgrade() */\ninterface UpgradeResult {\n version: number;\n data: unknown;\n warning?: string;\n}\n\n/**\n * Runs storage migration using the DataModel's upgrade callback.\n * This is the main entry point for the middle layer to trigger migrations.\n *\n * Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:\n * - Handles all migration logic internally\n * - Returns { version, data, warning? } - warning present if reset to initial data\n *\n * @param currentStorageJson - Current storage as JSON string (or undefined)\n * @returns MigrationResult\n */\nfunction migrateStorage(currentStorageJson: string | undefined): MigrationResult {\n // Get the callback registry context\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Normalize storage to get current data and version\n const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);\n const currentVersion = currentStorage.__dataVersion;\n\n // Helper to create storage with given data and version\n const createStorageJson = (data: unknown, version: number): string => {\n return JSON.stringify({\n ...currentStorage,\n __dataVersion: version,\n __data: data,\n });\n };\n\n // Get the upgrade callback (registered by DataModel.registerCallbacks())\n const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'] as ((v: { version: number; data: unknown }) => UpgradeResult) | undefined;\n if (typeof upgradeCallback !== 'function') {\n return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };\n }\n\n // Call the migrator's upgrade function\n let result: UpgradeResult;\n try {\n result = upgradeCallback({ version: currentVersion, data: currentData });\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `upgrade() threw: ${errorMsg}` };\n }\n\n // Build info message\n const info = result.version === currentVersion\n ? `No migration needed (v${currentVersion})`\n : result.warning\n ? `Reset to initial data (v${result.version})`\n : `Migrated v${currentVersion}→v${result.version}`;\n\n return {\n newStorageJson: createStorageJson(result.data, result.version),\n info,\n warn: result.warning,\n };\n}\n\n// Register migrate callback\ntryRegisterCallback('__pl_storage_migrate', (currentStorageJson: string | undefined) => {\n return migrateStorage(currentStorageJson);\n});\n\n// =============================================================================\n// Args Derivation from Storage\n// =============================================================================\n\n/**\n * Result of args derivation from storage.\n * Returned by __pl_args_derive and __pl_prerunArgs_derive callbacks.\n */\nexport type ArgsDeriveResult =\n | { error: string }\n | { error?: undefined; value: unknown };\n\n/**\n * Derives args from storage using the registered 'args' callback.\n * This extracts data from storage and passes it to the block's args() function.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived args or error\n */\nfunction deriveArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Get the args callback (registered by BlockModelV3.args())\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found' };\n }\n\n // Call the args callback with extracted data\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw: ${errorMsg}` };\n }\n}\n\n// Register args derivation callback\ntryRegisterCallback('__pl_args_derive', (storageJson: string) => {\n return deriveArgsFromStorage(storageJson);\n});\n\n/**\n * Derives prerunArgs from storage using the registered 'prerunArgs' callback.\n * Falls back to 'args' callback if 'prerunArgs' is not defined.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived prerunArgs or error\n */\nfunction derivePrerunArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Try prerunArgs callback first\n const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'] as ((data: unknown) => unknown) | undefined;\n if (typeof prerunArgsCallback === 'function') {\n try {\n const result = prerunArgsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `prerunArgs() threw: ${errorMsg}` };\n }\n }\n\n // Fall back to args callback\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found (fallback from missing prerunArgs)' };\n }\n\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw (fallback): ${errorMsg}` };\n }\n}\n\n// Register prerunArgs derivation callback\ntryRegisterCallback('__pl_prerunArgs_derive', (storageJson: string) => {\n return derivePrerunArgsFromStorage(storageJson);\n});\n\n// Export discriminator key and schema version for external checks\nexport { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION };\n"],"names":["createBlockStorage","isBlockStorage","getStorageData","updateStorageData","tryRegisterCallback","tryGetCfgRenderCtx"],"mappings":";;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AAwBH;;;;;;;;;AASG;AACH,SAAS,gBAAgB,CAAC,UAAmB,EAAA;;IAE3C,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,EAAE;AACnD,QAAA,MAAM,OAAO,GAAGA,gCAAkB,CAAC,EAAE,CAAC;AACtC,QAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;IAC9B;;IAGA,IAAI,MAAM,GAAG,UAAU;AACvB,IAAA,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;AAClC,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QACjC;AAAE,QAAA,MAAM;;AAEN,YAAA,MAAM,OAAO,GAAGA,gCAAkB,CAAC,UAAU,CAAC;AAC9C,YAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE;QACtC;IACF;;AAGA,IAAA,IAAIC,4BAAc,CAAC,MAAM,CAAC,EAAE;AAC1B,QAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAEC,4BAAc,CAAC,MAAM,CAAC,EAAE;IAC1D;;AAGA,IAAA,IAAI,wBAAwB,CAAC,MAAM,CAAC,EAAE;;AAEpC,QAAA,MAAM,OAAO,GAAGF,gCAAkB,CAAC,MAAM,CAAC;AAC1C,QAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;IAClC;;AAGA,IAAA,MAAM,OAAO,GAAGA,gCAAkB,CAAC,MAAM,CAAC;AAC1C,IAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;AAClC;AAEA;;;;;;;AAOG;AACH,SAAS,kBAAkB,CAAC,kBAA0B,EAAE,OAA6B,EAAA;IACnF,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,gBAAgB,CAAC,kBAAkB,CAAC;;IAGxE,MAAM,cAAc,GAAGG,+BAAiB,CAAC,cAAc,EAAE,OAAO,CAAC;AAEjE,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;AACvC;AAEA;;;AAGG;AACH,SAAS,wBAAwB,CAAC,IAAa,EAAA;AAC7C,IAAA,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;AAAE,QAAA,OAAO,KAAK;IAC3D,IAAIF,4BAAc,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,KAAK;IAEtC,MAAM,GAAG,GAAG,IAA+B;IAC3C,OAAO,MAAM,IAAI,GAAG;AACtB;AAEA;AACA;AACA;AAEA;AACAG,4BAAmB,CAAC,wBAAwB,EAAE,CAAC,UAAmB,KAAI;AACpE,IAAA,OAAO,gBAAgB,CAAC,UAAU,CAAC;AACrC,CAAC,CAAC;AAEF;AACAA,4BAAmB,CAAC,0BAA0B,EAAE,CAAC,kBAA0B,EAAE,OAA6B,KAAI;AAC5G,IAAA,OAAO,kBAAkB,CAAC,kBAAkB,EAAE,OAAO,CAAC;AACxD,CAAC,CAAC;AAUF;;;;;;AAMG;AACH,SAAS,cAAc,CAAC,UAAmB,EAAA;IACzC,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,UAAU,CAAC;AAChD,IAAA,MAAM,IAAI,GAAgB;QACxB,WAAW,EAAE,OAAO,CAAC,aAAa;KACnC;AACD,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AAC7B;AAEA;AACAA,4BAAmB,CAAC,sBAAsB,EAAE,CAAC,UAAmB,KAAI;AAClE,IAAA,OAAO,cAAc,CAAC,UAAU,CAAC;AACnC,CAAC,CAAC;AAwBF;;;;;;;;;;AAUG;AACH,SAAS,cAAc,CAAC,kBAAsC,EAAA;;AAE5D,IAAA,MAAM,GAAG,GAAGC,2BAAkB,EAAE;AAChC,IAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,QAAA,OAAO,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACrD;;AAGA,IAAA,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,kBAAkB,CAAC;AAC3F,IAAA,MAAM,cAAc,GAAG,cAAc,CAAC,aAAa;;AAGnD,IAAA,MAAM,iBAAiB,GAAG,CAAC,IAAa,EAAE,OAAe,KAAY;QACnE,OAAO,IAAI,CAAC,SAAS,CAAC;AACpB,YAAA,GAAG,cAAc;AACjB,YAAA,aAAa,EAAE,OAAO;AACtB,YAAA,MAAM,EAAE,IAAI;AACb,SAAA,CAAC;AACJ,IAAA,CAAC;;IAGD,MAAM,eAAe,GAAG,GAAG,CAAC,gBAAgB,CAAC,mBAAmB,CAA2E;AAC3I,IAAA,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE;AACzC,QAAA,OAAO,EAAE,KAAK,EAAE,iEAAiE,EAAE;IACrF;;AAGA,IAAA,IAAI,MAAqB;AACzB,IAAA,IAAI;AACF,QAAA,MAAM,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC1E;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;AAC3D,QAAA,OAAO,EAAE,KAAK,EAAE,oBAAoB,QAAQ,CAAA,CAAE,EAAE;IAClD;;AAGA,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,KAAK;UAC5B,CAAA,sBAAA,EAAyB,cAAc,CAAA,CAAA;UACvC,MAAM,CAAC;AACP,cAAE,CAAA,wBAAA,EAA2B,MAAM,CAAC,OAAO,CAAA,CAAA;cACzC,aAAa,cAAc,CAAA,EAAA,EAAK,MAAM,CAAC,OAAO,EAAE;IAEtD,OAAO;QACL,cAAc,EAAE,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;QAC9D,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,OAAO;KACrB;AACH;AAEA;AACAD,4BAAmB,CAAC,sBAAsB,EAAE,CAAC,kBAAsC,KAAI;AACrF,IAAA,OAAO,cAAc,CAAC,kBAAkB,CAAC;AAC3C,CAAC,CAAC;AAcF;;;;;;AAMG;AACH,SAAS,qBAAqB,CAAC,WAAmB,EAAA;AAChD,IAAA,MAAM,GAAG,GAAGC,2BAAkB,EAAE;AAChC,IAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,QAAA,OAAO,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACrD;;IAGA,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,WAAW,CAAC;;IAG9C,MAAM,YAAY,GAAG,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAA6C;AAC7F,IAAA,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE;AACtC,QAAA,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE;IAC7C;;AAGA,IAAA,IAAI;AACF,QAAA,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC;AACjC,QAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;IAC1B;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;AAC3D,QAAA,OAAO,EAAE,KAAK,EAAE,iBAAiB,QAAQ,CAAA,CAAE,EAAE;IAC/C;AACF;AAEA;AACAD,4BAAmB,CAAC,kBAAkB,EAAE,CAAC,WAAmB,KAAI;AAC9D,IAAA,OAAO,qBAAqB,CAAC,WAAW,CAAC;AAC3C,CAAC,CAAC;AAEF;;;;;;AAMG;AACH,SAAS,2BAA2B,CAAC,WAAmB,EAAA;AACtD,IAAA,MAAM,GAAG,GAAGC,2BAAkB,EAAE;AAChC,IAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,QAAA,OAAO,EAAE,KAAK,EAAE,iCAAiC,EAAE;IACrD;;IAGA,MAAM,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,WAAW,CAAC;;IAG9C,MAAM,kBAAkB,GAAG,GAAG,CAAC,gBAAgB,CAAC,YAAY,CAA6C;AACzG,IAAA,IAAI,OAAO,kBAAkB,KAAK,UAAU,EAAE;AAC5C,QAAA,IAAI;AACF,YAAA,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC;AACvC,YAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;QAC1B;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;AAC3D,YAAA,OAAO,EAAE,KAAK,EAAE,uBAAuB,QAAQ,CAAA,CAAE,EAAE;QACrD;IACF;;IAGA,MAAM,YAAY,GAAG,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAA6C;AAC7F,IAAA,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE;AACtC,QAAA,OAAO,EAAE,KAAK,EAAE,4DAA4D,EAAE;IAChF;AAEA,IAAA,IAAI;AACF,QAAA,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC;AACjC,QAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;IAC1B;IAAE,OAAO,CAAC,EAAE;AACV,QAAA,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;AAC3D,QAAA,OAAO,EAAE,KAAK,EAAE,4BAA4B,QAAQ,CAAA,CAAE,EAAE;IAC1D;AACF;AAEA;AACAD,4BAAmB,CAAC,wBAAwB,EAAE,CAAC,WAAmB,KAAI;AACpE,IAAA,OAAO,2BAA2B,CAAC,WAAW,CAAC;AACjD,CAAC,CAAC;;;;;"}
1
+ {"version":3,"file":"block_storage_vm.cjs","sources":["../src/block_storage_vm.ts"],"sourcesContent":["/**\n * BlockStorage VM Integration - Internal module for VM-based storage operations.\n *\n * This module auto-registers internal callbacks that the middle layer can invoke\n * to perform storage transformations. Block developers never interact with these\n * directly - they only see `state`.\n *\n * Registered callbacks (all prefixed with `__pl_` for internal SDK use):\n * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson\n * - `__pl_storage_debugView`: (rawStorage) => JSON string with storage debug view\n * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult\n * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult\n * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult\n *\n * Callbacks registered by DataModel.registerCallbacks():\n * - `__pl_data_initial`: () => initial data\n * - `__pl_data_upgrade`: (versioned) => UpgradeResult\n * - `__pl_storage_initial`: () => initial BlockStorage as JSON string\n *\n * @module block_storage_vm\n * @internal\n */\n\nimport {\n BLOCK_STORAGE_KEY,\n BLOCK_STORAGE_SCHEMA_VERSION,\n type BlockStorage,\n type MutateStoragePayload,\n type StorageDebugView,\n createBlockStorage,\n getStorageData,\n isBlockStorage,\n updateStorageData,\n} from './block_storage';\nimport { stringifyJson, type StringifiedJson } from '@milaboratories/pl-model-common';\nimport { tryGetCfgRenderCtx, tryRegisterCallback } from './internal';\n\n/**\n * Result of storage normalization\n */\nexport interface NormalizeStorageResult {\n /** The normalized BlockStorage object */\n storage: BlockStorage;\n /** The extracted data (what developers see) */\n data: unknown;\n}\n\n/**\n * Normalizes raw storage data and extracts state.\n * Handles all formats:\n * - New BlockStorage format (has discriminator)\n * - Legacy V1/V2 format ({ args, uiState })\n * - Raw V3 state (any other format)\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns Object with normalized storage and extracted state\n */\nfunction normalizeStorage(rawStorage: unknown): NormalizeStorageResult {\n // Handle undefined/null\n if (rawStorage === undefined || rawStorage === null) {\n const storage = createBlockStorage({});\n return { storage, data: {} };\n }\n\n // Parse JSON string if needed\n let parsed = rawStorage;\n if (typeof rawStorage === 'string') {\n try {\n parsed = JSON.parse(rawStorage);\n } catch {\n // If parsing fails, treat string as the data\n const storage = createBlockStorage(rawStorage);\n return { storage, data: rawStorage };\n }\n }\n\n // Check for BlockStorage format (has discriminator)\n if (isBlockStorage(parsed)) {\n return { storage: parsed, data: getStorageData(parsed) };\n }\n\n // Check for legacy V1/V2 format: { args, uiState }\n if (isLegacyModelV1ApiFormat(parsed)) {\n // For legacy format, the whole object IS the data\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n }\n\n // Raw V3 data - wrap it\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n}\n\n/**\n * Applies a state update to existing storage.\n * Used when setData is called from the frontend.\n *\n * @param currentStorageJson - Current storage as JSON string (must be defined)\n * @param newData - New data from application\n * @returns Updated storage as JSON string\n */\nfunction applyStorageUpdate(currentStorageJson: string, payload: MutateStoragePayload): string {\n const { storage: currentStorage } = normalizeStorage(currentStorageJson);\n\n // Update data while preserving other storage fields (version, plugins)\n const updatedStorage = updateStorageData(currentStorage, payload);\n\n return JSON.stringify(updatedStorage);\n}\n\n/**\n * Checks if data is in legacy Model API v1 format.\n * Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.\n */\nfunction isLegacyModelV1ApiFormat(data: unknown): data is { args?: unknown } {\n if (data === null || typeof data !== 'object') return false;\n if (isBlockStorage(data)) return false;\n\n const obj = data as Record<string, unknown>;\n return 'args' in obj;\n}\n\n// =============================================================================\n// Auto-register internal callbacks when module is loaded in VM\n// =============================================================================\n\n// Register apply update callback (requires existing storage)\ntryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson: string, payload: MutateStoragePayload) => {\n return applyStorageUpdate(currentStorageJson, payload);\n});\n\n/**\n * Gets storage debug view from raw storage data.\n * Returns structured debug info about the storage state.\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns JSON string with storage debug view\n */\nfunction getStorageDebugView(rawStorage: unknown): StringifiedJson<StorageDebugView> {\n const { storage } = normalizeStorage(rawStorage);\n const debugView: StorageDebugView = {\n dataVersion: storage.__dataVersion,\n data: storage.__data,\n };\n return stringifyJson(debugView);\n}\n\n// Register debug view callback\ntryRegisterCallback('__pl_storage_debugView', (rawStorage: unknown) => {\n return getStorageDebugView(rawStorage);\n});\n\n// =============================================================================\n// Migration Support\n// =============================================================================\n\n/**\n * Result of storage migration.\n * Returned by __pl_storage_migrate callback.\n *\n * - Error result: { error: string } - serious failure (no context, etc.)\n * - Success result: { newStorageJson: string, info: string, warn?: string } - migration succeeded or reset to initial\n */\nexport type MigrationResult =\n | { error: string }\n | { error?: undefined; newStorageJson: string; info: string; warn?: string };\n\n/** Result from Migrator.upgrade() */\ninterface UpgradeResult {\n version: number;\n data: unknown;\n warning?: string;\n}\n\n/**\n * Runs storage migration using the DataModel's upgrade callback.\n * This is the main entry point for the middle layer to trigger migrations.\n *\n * Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:\n * - Handles all migration logic internally\n * - Returns { version, data, warning? } - warning present if reset to initial data\n *\n * @param currentStorageJson - Current storage as JSON string (or undefined)\n * @returns MigrationResult\n */\nfunction migrateStorage(currentStorageJson: string | undefined): MigrationResult {\n // Get the callback registry context\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Normalize storage to get current data and version\n const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);\n const currentVersion = currentStorage.__dataVersion;\n\n // Helper to create storage with given data and version\n const createStorageJson = (data: unknown, version: number): string => {\n return JSON.stringify({\n ...currentStorage,\n __dataVersion: version,\n __data: data,\n });\n };\n\n // Get the upgrade callback (registered by DataModel.registerCallbacks())\n const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'] as ((v: { version: number; data: unknown }) => UpgradeResult) | undefined;\n if (typeof upgradeCallback !== 'function') {\n return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };\n }\n\n // Call the migrator's upgrade function\n let result: UpgradeResult;\n try {\n result = upgradeCallback({ version: currentVersion, data: currentData });\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `upgrade() threw: ${errorMsg}` };\n }\n\n // Build info message\n const info = result.version === currentVersion\n ? `No migration needed (v${currentVersion})`\n : result.warning\n ? `Reset to initial data (v${result.version})`\n : `Migrated v${currentVersion}→v${result.version}`;\n\n return {\n newStorageJson: createStorageJson(result.data, result.version),\n info,\n warn: result.warning,\n };\n}\n\n// Register migrate callback\ntryRegisterCallback('__pl_storage_migrate', (currentStorageJson: string | undefined) => {\n return migrateStorage(currentStorageJson);\n});\n\n// =============================================================================\n// Args Derivation from Storage\n// =============================================================================\n\n/**\n * Result of args derivation from storage.\n * Returned by __pl_args_derive and __pl_prerunArgs_derive callbacks.\n */\nexport type ArgsDeriveResult =\n | { error: string }\n | { error?: undefined; value: unknown };\n\n/**\n * Derives args from storage using the registered 'args' callback.\n * This extracts data from storage and passes it to the block's args() function.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived args or error\n */\nfunction deriveArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Get the args callback (registered by BlockModelV3.args())\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found' };\n }\n\n // Call the args callback with extracted data\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw: ${errorMsg}` };\n }\n}\n\n// Register args derivation callback\ntryRegisterCallback('__pl_args_derive', (storageJson: string) => {\n return deriveArgsFromStorage(storageJson);\n});\n\n/**\n * Derives prerunArgs from storage using the registered 'prerunArgs' callback.\n * Falls back to 'args' callback if 'prerunArgs' is not defined.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived prerunArgs or error\n */\nfunction derivePrerunArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Try prerunArgs callback first\n const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'] as ((data: unknown) => unknown) | undefined;\n if (typeof prerunArgsCallback === 'function') {\n try {\n const result = prerunArgsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `prerunArgs() threw: ${errorMsg}` };\n }\n }\n\n // Fall back to args callback\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found (fallback from missing prerunArgs)' };\n }\n\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw (fallback): ${errorMsg}` };\n }\n}\n\n// Register prerunArgs derivation callback\ntryRegisterCallback('__pl_prerunArgs_derive', (storageJson: string) => {\n return derivePrerunArgsFromStorage(storageJson);\n});\n\n// Export discriminator key and schema version for external checks\nexport { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION };\n"],"names":["createBlockStorage","isBlockStorage","getStorageData","updateStorageData","tryRegisterCallback","stringifyJson","tryGetCfgRenderCtx"],"mappings":"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"}
@@ -6,9 +6,8 @@
6
6
  * directly - they only see `state`.
7
7
  *
8
8
  * Registered callbacks (all prefixed with `__pl_` for internal SDK use):
9
- * - `__pl_storage_normalize`: (rawStorage) => { storage, data }
10
9
  * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
11
- * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
10
+ * - `__pl_storage_debugView`: (rawStorage) => JSON string with storage debug view
12
11
  * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
13
12
  * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
14
13
  * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
@@ -31,13 +30,6 @@ export interface NormalizeStorageResult {
31
30
  /** The extracted data (what developers see) */
32
31
  data: unknown;
33
32
  }
34
- /**
35
- * Storage info result returned by __pl_storage_getInfo callback.
36
- */
37
- export interface StorageInfo {
38
- /** Current data version (1-based, starts at 1) */
39
- dataVersion: number;
40
- }
41
33
  /**
42
34
  * Result of storage migration.
43
35
  * Returned by __pl_storage_migrate callback.
@@ -1 +1 @@
1
- {"version":3,"file":"block_storage_vm.d.ts","sourceRoot":"","sources":["../src/block_storage_vm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,KAAK,YAAY,EAMlB,MAAM,iBAAiB,CAAC;AAGzB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;CACf;AA2FD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;CACrB;AA0BD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA8E/E;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAwF1C,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,CAAC"}
1
+ {"version":3,"file":"block_storage_vm.d.ts","sourceRoot":"","sources":["../src/block_storage_vm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,KAAK,YAAY,EAOlB,MAAM,iBAAiB,CAAC;AAIzB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;CACf;AA+GD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA8E/E;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAwF1C,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,CAAC"}
@@ -1,5 +1,6 @@
1
- import { createBlockStorage, isBlockStorage, getStorageData, updateStorageData } from './block_storage.js';
1
+ import { updateStorageData, createBlockStorage, isBlockStorage, getStorageData } from './block_storage.js';
2
2
  export { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION } from './block_storage.js';
3
+ import { stringifyJson } from '@milaboratories/pl-model-common';
3
4
  import { tryRegisterCallback, tryGetCfgRenderCtx } from './internal.js';
4
5
 
5
6
  /**
@@ -10,9 +11,8 @@ import { tryRegisterCallback, tryGetCfgRenderCtx } from './internal.js';
10
11
  * directly - they only see `state`.
11
12
  *
12
13
  * Registered callbacks (all prefixed with `__pl_` for internal SDK use):
13
- * - `__pl_storage_normalize`: (rawStorage) => { storage, data }
14
14
  * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
15
- * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
15
+ * - `__pl_storage_debugView`: (rawStorage) => JSON string with storage debug view
16
16
  * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
17
17
  * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
18
18
  * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
@@ -96,31 +96,28 @@ function isLegacyModelV1ApiFormat(data) {
96
96
  // =============================================================================
97
97
  // Auto-register internal callbacks when module is loaded in VM
98
98
  // =============================================================================
99
- // Register normalize callback
100
- tryRegisterCallback('__pl_storage_normalize', (rawStorage) => {
101
- return normalizeStorage(rawStorage);
102
- });
103
99
  // Register apply update callback (requires existing storage)
104
100
  tryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson, payload) => {
105
101
  return applyStorageUpdate(currentStorageJson, payload);
106
102
  });
107
103
  /**
108
- * Gets storage info from raw storage data.
109
- * Returns structured info about the storage state.
104
+ * Gets storage debug view from raw storage data.
105
+ * Returns structured debug info about the storage state.
110
106
  *
111
107
  * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
112
- * @returns JSON string with storage info
108
+ * @returns JSON string with storage debug view
113
109
  */
114
- function getStorageInfo(rawStorage) {
110
+ function getStorageDebugView(rawStorage) {
115
111
  const { storage } = normalizeStorage(rawStorage);
116
- const info = {
112
+ const debugView = {
117
113
  dataVersion: storage.__dataVersion,
114
+ data: storage.__data,
118
115
  };
119
- return JSON.stringify(info);
116
+ return stringifyJson(debugView);
120
117
  }
121
- // Register get info callback
122
- tryRegisterCallback('__pl_storage_getInfo', (rawStorage) => {
123
- return getStorageInfo(rawStorage);
118
+ // Register debug view callback
119
+ tryRegisterCallback('__pl_storage_debugView', (rawStorage) => {
120
+ return getStorageDebugView(rawStorage);
124
121
  });
125
122
  /**
126
123
  * Runs storage migration using the DataModel's upgrade callback.
@@ -1 +1 @@
1
- {"version":3,"file":"block_storage_vm.js","sources":["../src/block_storage_vm.ts"],"sourcesContent":["/**\n * BlockStorage VM Integration - Internal module for VM-based storage operations.\n *\n * This module auto-registers internal callbacks that the middle layer can invoke\n * to perform storage transformations. Block developers never interact with these\n * directly - they only see `state`.\n *\n * Registered callbacks (all prefixed with `__pl_` for internal SDK use):\n * - `__pl_storage_normalize`: (rawStorage) => { storage, data }\n * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson\n * - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info\n * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult\n * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult\n * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult\n *\n * Callbacks registered by DataModel.registerCallbacks():\n * - `__pl_data_initial`: () => initial data\n * - `__pl_data_upgrade`: (versioned) => UpgradeResult\n * - `__pl_storage_initial`: () => initial BlockStorage as JSON string\n *\n * @module block_storage_vm\n * @internal\n */\n\nimport {\n BLOCK_STORAGE_KEY,\n BLOCK_STORAGE_SCHEMA_VERSION,\n type BlockStorage,\n type MutateStoragePayload,\n createBlockStorage,\n getStorageData,\n isBlockStorage,\n updateStorageData,\n} from './block_storage';\nimport { tryGetCfgRenderCtx, tryRegisterCallback } from './internal';\n\n/**\n * Result of storage normalization\n */\nexport interface NormalizeStorageResult {\n /** The normalized BlockStorage object */\n storage: BlockStorage;\n /** The extracted data (what developers see) */\n data: unknown;\n}\n\n/**\n * Normalizes raw storage data and extracts state.\n * Handles all formats:\n * - New BlockStorage format (has discriminator)\n * - Legacy V1/V2 format ({ args, uiState })\n * - Raw V3 state (any other format)\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns Object with normalized storage and extracted state\n */\nfunction normalizeStorage(rawStorage: unknown): NormalizeStorageResult {\n // Handle undefined/null\n if (rawStorage === undefined || rawStorage === null) {\n const storage = createBlockStorage({});\n return { storage, data: {} };\n }\n\n // Parse JSON string if needed\n let parsed = rawStorage;\n if (typeof rawStorage === 'string') {\n try {\n parsed = JSON.parse(rawStorage);\n } catch {\n // If parsing fails, treat string as the data\n const storage = createBlockStorage(rawStorage);\n return { storage, data: rawStorage };\n }\n }\n\n // Check for BlockStorage format (has discriminator)\n if (isBlockStorage(parsed)) {\n return { storage: parsed, data: getStorageData(parsed) };\n }\n\n // Check for legacy V1/V2 format: { args, uiState }\n if (isLegacyModelV1ApiFormat(parsed)) {\n // For legacy format, the whole object IS the data\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n }\n\n // Raw V3 data - wrap it\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n}\n\n/**\n * Applies a state update to existing storage.\n * Used when setData is called from the frontend.\n *\n * @param currentStorageJson - Current storage as JSON string (must be defined)\n * @param newData - New data from application\n * @returns Updated storage as JSON string\n */\nfunction applyStorageUpdate(currentStorageJson: string, payload: MutateStoragePayload): string {\n const { storage: currentStorage } = normalizeStorage(currentStorageJson);\n\n // Update data while preserving other storage fields (version, plugins)\n const updatedStorage = updateStorageData(currentStorage, payload);\n\n return JSON.stringify(updatedStorage);\n}\n\n/**\n * Checks if data is in legacy Model API v1 format.\n * Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.\n */\nfunction isLegacyModelV1ApiFormat(data: unknown): data is { args?: unknown } {\n if (data === null || typeof data !== 'object') return false;\n if (isBlockStorage(data)) return false;\n\n const obj = data as Record<string, unknown>;\n return 'args' in obj;\n}\n\n// =============================================================================\n// Auto-register internal callbacks when module is loaded in VM\n// =============================================================================\n\n// Register normalize callback\ntryRegisterCallback('__pl_storage_normalize', (rawStorage: unknown) => {\n return normalizeStorage(rawStorage);\n});\n\n// Register apply update callback (requires existing storage)\ntryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson: string, payload: MutateStoragePayload) => {\n return applyStorageUpdate(currentStorageJson, payload);\n});\n\n/**\n * Storage info result returned by __pl_storage_getInfo callback.\n */\nexport interface StorageInfo {\n /** Current data version (1-based, starts at 1) */\n dataVersion: number;\n}\n\n/**\n * Gets storage info from raw storage data.\n * Returns structured info about the storage state.\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns JSON string with storage info\n */\nfunction getStorageInfo(rawStorage: unknown): string {\n const { storage } = normalizeStorage(rawStorage);\n const info: StorageInfo = {\n dataVersion: storage.__dataVersion,\n };\n return JSON.stringify(info);\n}\n\n// Register get info callback\ntryRegisterCallback('__pl_storage_getInfo', (rawStorage: unknown) => {\n return getStorageInfo(rawStorage);\n});\n\n// =============================================================================\n// Migration Support\n// =============================================================================\n\n/**\n * Result of storage migration.\n * Returned by __pl_storage_migrate callback.\n *\n * - Error result: { error: string } - serious failure (no context, etc.)\n * - Success result: { newStorageJson: string, info: string, warn?: string } - migration succeeded or reset to initial\n */\nexport type MigrationResult =\n | { error: string }\n | { error?: undefined; newStorageJson: string; info: string; warn?: string };\n\n/** Result from Migrator.upgrade() */\ninterface UpgradeResult {\n version: number;\n data: unknown;\n warning?: string;\n}\n\n/**\n * Runs storage migration using the DataModel's upgrade callback.\n * This is the main entry point for the middle layer to trigger migrations.\n *\n * Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:\n * - Handles all migration logic internally\n * - Returns { version, data, warning? } - warning present if reset to initial data\n *\n * @param currentStorageJson - Current storage as JSON string (or undefined)\n * @returns MigrationResult\n */\nfunction migrateStorage(currentStorageJson: string | undefined): MigrationResult {\n // Get the callback registry context\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Normalize storage to get current data and version\n const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);\n const currentVersion = currentStorage.__dataVersion;\n\n // Helper to create storage with given data and version\n const createStorageJson = (data: unknown, version: number): string => {\n return JSON.stringify({\n ...currentStorage,\n __dataVersion: version,\n __data: data,\n });\n };\n\n // Get the upgrade callback (registered by DataModel.registerCallbacks())\n const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'] as ((v: { version: number; data: unknown }) => UpgradeResult) | undefined;\n if (typeof upgradeCallback !== 'function') {\n return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };\n }\n\n // Call the migrator's upgrade function\n let result: UpgradeResult;\n try {\n result = upgradeCallback({ version: currentVersion, data: currentData });\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `upgrade() threw: ${errorMsg}` };\n }\n\n // Build info message\n const info = result.version === currentVersion\n ? `No migration needed (v${currentVersion})`\n : result.warning\n ? `Reset to initial data (v${result.version})`\n : `Migrated v${currentVersion}→v${result.version}`;\n\n return {\n newStorageJson: createStorageJson(result.data, result.version),\n info,\n warn: result.warning,\n };\n}\n\n// Register migrate callback\ntryRegisterCallback('__pl_storage_migrate', (currentStorageJson: string | undefined) => {\n return migrateStorage(currentStorageJson);\n});\n\n// =============================================================================\n// Args Derivation from Storage\n// =============================================================================\n\n/**\n * Result of args derivation from storage.\n * Returned by __pl_args_derive and __pl_prerunArgs_derive callbacks.\n */\nexport type ArgsDeriveResult =\n | { error: string }\n | { error?: undefined; value: unknown };\n\n/**\n * Derives args from storage using the registered 'args' callback.\n * This extracts data from storage and passes it to the block's args() function.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived args or error\n */\nfunction deriveArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Get the args callback (registered by BlockModelV3.args())\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found' };\n }\n\n // Call the args callback with extracted data\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw: ${errorMsg}` };\n }\n}\n\n// Register args derivation callback\ntryRegisterCallback('__pl_args_derive', (storageJson: string) => {\n return deriveArgsFromStorage(storageJson);\n});\n\n/**\n * Derives prerunArgs from storage using the registered 'prerunArgs' callback.\n * Falls back to 'args' callback if 'prerunArgs' is not defined.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived prerunArgs or error\n */\nfunction derivePrerunArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Try prerunArgs callback first\n const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'] as ((data: unknown) => unknown) | undefined;\n if (typeof prerunArgsCallback === 'function') {\n try {\n const result = prerunArgsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `prerunArgs() threw: ${errorMsg}` };\n }\n }\n\n // Fall back to args callback\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found (fallback from missing prerunArgs)' };\n }\n\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw (fallback): ${errorMsg}` };\n }\n}\n\n// Register prerunArgs derivation callback\ntryRegisterCallback('__pl_prerunArgs_derive', (storageJson: string) => {\n return derivePrerunArgsFromStorage(storageJson);\n});\n\n// Export discriminator key and schema version for external checks\nexport { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block_storage_vm.js","sources":["../src/block_storage_vm.ts"],"sourcesContent":["/**\n * BlockStorage VM Integration - Internal module for VM-based storage operations.\n *\n * This module auto-registers internal callbacks that the middle layer can invoke\n * to perform storage transformations. Block developers never interact with these\n * directly - they only see `state`.\n *\n * Registered callbacks (all prefixed with `__pl_` for internal SDK use):\n * - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson\n * - `__pl_storage_debugView`: (rawStorage) => JSON string with storage debug view\n * - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult\n * - `__pl_args_derive`: (storageJson) => ArgsDeriveResult\n * - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult\n *\n * Callbacks registered by DataModel.registerCallbacks():\n * - `__pl_data_initial`: () => initial data\n * - `__pl_data_upgrade`: (versioned) => UpgradeResult\n * - `__pl_storage_initial`: () => initial BlockStorage as JSON string\n *\n * @module block_storage_vm\n * @internal\n */\n\nimport {\n BLOCK_STORAGE_KEY,\n BLOCK_STORAGE_SCHEMA_VERSION,\n type BlockStorage,\n type MutateStoragePayload,\n type StorageDebugView,\n createBlockStorage,\n getStorageData,\n isBlockStorage,\n updateStorageData,\n} from './block_storage';\nimport { stringifyJson, type StringifiedJson } from '@milaboratories/pl-model-common';\nimport { tryGetCfgRenderCtx, tryRegisterCallback } from './internal';\n\n/**\n * Result of storage normalization\n */\nexport interface NormalizeStorageResult {\n /** The normalized BlockStorage object */\n storage: BlockStorage;\n /** The extracted data (what developers see) */\n data: unknown;\n}\n\n/**\n * Normalizes raw storage data and extracts state.\n * Handles all formats:\n * - New BlockStorage format (has discriminator)\n * - Legacy V1/V2 format ({ args, uiState })\n * - Raw V3 state (any other format)\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns Object with normalized storage and extracted state\n */\nfunction normalizeStorage(rawStorage: unknown): NormalizeStorageResult {\n // Handle undefined/null\n if (rawStorage === undefined || rawStorage === null) {\n const storage = createBlockStorage({});\n return { storage, data: {} };\n }\n\n // Parse JSON string if needed\n let parsed = rawStorage;\n if (typeof rawStorage === 'string') {\n try {\n parsed = JSON.parse(rawStorage);\n } catch {\n // If parsing fails, treat string as the data\n const storage = createBlockStorage(rawStorage);\n return { storage, data: rawStorage };\n }\n }\n\n // Check for BlockStorage format (has discriminator)\n if (isBlockStorage(parsed)) {\n return { storage: parsed, data: getStorageData(parsed) };\n }\n\n // Check for legacy V1/V2 format: { args, uiState }\n if (isLegacyModelV1ApiFormat(parsed)) {\n // For legacy format, the whole object IS the data\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n }\n\n // Raw V3 data - wrap it\n const storage = createBlockStorage(parsed);\n return { storage, data: parsed };\n}\n\n/**\n * Applies a state update to existing storage.\n * Used when setData is called from the frontend.\n *\n * @param currentStorageJson - Current storage as JSON string (must be defined)\n * @param newData - New data from application\n * @returns Updated storage as JSON string\n */\nfunction applyStorageUpdate(currentStorageJson: string, payload: MutateStoragePayload): string {\n const { storage: currentStorage } = normalizeStorage(currentStorageJson);\n\n // Update data while preserving other storage fields (version, plugins)\n const updatedStorage = updateStorageData(currentStorage, payload);\n\n return JSON.stringify(updatedStorage);\n}\n\n/**\n * Checks if data is in legacy Model API v1 format.\n * Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.\n */\nfunction isLegacyModelV1ApiFormat(data: unknown): data is { args?: unknown } {\n if (data === null || typeof data !== 'object') return false;\n if (isBlockStorage(data)) return false;\n\n const obj = data as Record<string, unknown>;\n return 'args' in obj;\n}\n\n// =============================================================================\n// Auto-register internal callbacks when module is loaded in VM\n// =============================================================================\n\n// Register apply update callback (requires existing storage)\ntryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson: string, payload: MutateStoragePayload) => {\n return applyStorageUpdate(currentStorageJson, payload);\n});\n\n/**\n * Gets storage debug view from raw storage data.\n * Returns structured debug info about the storage state.\n *\n * @param rawStorage - Raw data from blockStorage field (may be JSON string or object)\n * @returns JSON string with storage debug view\n */\nfunction getStorageDebugView(rawStorage: unknown): StringifiedJson<StorageDebugView> {\n const { storage } = normalizeStorage(rawStorage);\n const debugView: StorageDebugView = {\n dataVersion: storage.__dataVersion,\n data: storage.__data,\n };\n return stringifyJson(debugView);\n}\n\n// Register debug view callback\ntryRegisterCallback('__pl_storage_debugView', (rawStorage: unknown) => {\n return getStorageDebugView(rawStorage);\n});\n\n// =============================================================================\n// Migration Support\n// =============================================================================\n\n/**\n * Result of storage migration.\n * Returned by __pl_storage_migrate callback.\n *\n * - Error result: { error: string } - serious failure (no context, etc.)\n * - Success result: { newStorageJson: string, info: string, warn?: string } - migration succeeded or reset to initial\n */\nexport type MigrationResult =\n | { error: string }\n | { error?: undefined; newStorageJson: string; info: string; warn?: string };\n\n/** Result from Migrator.upgrade() */\ninterface UpgradeResult {\n version: number;\n data: unknown;\n warning?: string;\n}\n\n/**\n * Runs storage migration using the DataModel's upgrade callback.\n * This is the main entry point for the middle layer to trigger migrations.\n *\n * Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:\n * - Handles all migration logic internally\n * - Returns { version, data, warning? } - warning present if reset to initial data\n *\n * @param currentStorageJson - Current storage as JSON string (or undefined)\n * @returns MigrationResult\n */\nfunction migrateStorage(currentStorageJson: string | undefined): MigrationResult {\n // Get the callback registry context\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Normalize storage to get current data and version\n const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);\n const currentVersion = currentStorage.__dataVersion;\n\n // Helper to create storage with given data and version\n const createStorageJson = (data: unknown, version: number): string => {\n return JSON.stringify({\n ...currentStorage,\n __dataVersion: version,\n __data: data,\n });\n };\n\n // Get the upgrade callback (registered by DataModel.registerCallbacks())\n const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'] as ((v: { version: number; data: unknown }) => UpgradeResult) | undefined;\n if (typeof upgradeCallback !== 'function') {\n return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };\n }\n\n // Call the migrator's upgrade function\n let result: UpgradeResult;\n try {\n result = upgradeCallback({ version: currentVersion, data: currentData });\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `upgrade() threw: ${errorMsg}` };\n }\n\n // Build info message\n const info = result.version === currentVersion\n ? `No migration needed (v${currentVersion})`\n : result.warning\n ? `Reset to initial data (v${result.version})`\n : `Migrated v${currentVersion}→v${result.version}`;\n\n return {\n newStorageJson: createStorageJson(result.data, result.version),\n info,\n warn: result.warning,\n };\n}\n\n// Register migrate callback\ntryRegisterCallback('__pl_storage_migrate', (currentStorageJson: string | undefined) => {\n return migrateStorage(currentStorageJson);\n});\n\n// =============================================================================\n// Args Derivation from Storage\n// =============================================================================\n\n/**\n * Result of args derivation from storage.\n * Returned by __pl_args_derive and __pl_prerunArgs_derive callbacks.\n */\nexport type ArgsDeriveResult =\n | { error: string }\n | { error?: undefined; value: unknown };\n\n/**\n * Derives args from storage using the registered 'args' callback.\n * This extracts data from storage and passes it to the block's args() function.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived args or error\n */\nfunction deriveArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Get the args callback (registered by BlockModelV3.args())\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found' };\n }\n\n // Call the args callback with extracted data\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw: ${errorMsg}` };\n }\n}\n\n// Register args derivation callback\ntryRegisterCallback('__pl_args_derive', (storageJson: string) => {\n return deriveArgsFromStorage(storageJson);\n});\n\n/**\n * Derives prerunArgs from storage using the registered 'prerunArgs' callback.\n * Falls back to 'args' callback if 'prerunArgs' is not defined.\n *\n * @param storageJson - Storage as JSON string\n * @returns ArgsDeriveResult with derived prerunArgs or error\n */\nfunction derivePrerunArgsFromStorage(storageJson: string): ArgsDeriveResult {\n const ctx = tryGetCfgRenderCtx();\n if (ctx === undefined) {\n return { error: 'Not in config rendering context' };\n }\n\n // Extract data from storage\n const { data } = normalizeStorage(storageJson);\n\n // Try prerunArgs callback first\n const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'] as ((data: unknown) => unknown) | undefined;\n if (typeof prerunArgsCallback === 'function') {\n try {\n const result = prerunArgsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `prerunArgs() threw: ${errorMsg}` };\n }\n }\n\n // Fall back to args callback\n const argsCallback = ctx.callbackRegistry['args'] as ((data: unknown) => unknown) | undefined;\n if (typeof argsCallback !== 'function') {\n return { error: 'args callback not found (fallback from missing prerunArgs)' };\n }\n\n try {\n const result = argsCallback(data);\n return { value: result };\n } catch (e) {\n const errorMsg = e instanceof Error ? e.message : String(e);\n return { error: `args() threw (fallback): ${errorMsg}` };\n }\n}\n\n// Register prerunArgs derivation callback\ntryRegisterCallback('__pl_prerunArgs_derive', (storageJson: string) => {\n return derivePrerunArgsFromStorage(storageJson);\n});\n\n// Export discriminator key and schema version for external checks\nexport { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION };\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PFrameForGraphs.cjs","sources":["../../src/components/PFrameForGraphs.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpecNormalized,\n CanonicalizedJson,\n PColumn,\n PColumnSpec,\n PFrameHandle,\n PObjectId,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec, LinkerMap,\n matchAxisId,\n readAnnotation,\n readAnnotationJson,\n stringifyJson,\n} from '@milaboratories/pl-model-common';\nimport type { PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, RenderCtx } from '../render';\nimport { getAllRelatedColumns, getRelatedColumns } from '../pframe_utils/columns';\n\n/** Create id for column copy with added keys in axes domains */\nconst colId = (id: PObjectId, domains: (Record<string, string> | undefined)[]) => {\n let wid = id.toString();\n domains?.forEach((domain) => {\n if (domain) {\n for (const [k, v] of Object.entries(domain)) {\n wid += k;\n wid += v;\n }\n }\n });\n return wid;\n};\n\n/** All combinations with 1 key from each list */\nfunction getKeysCombinations(idsLists: AxisId[][]) {\n if (!idsLists.length) {\n return [];\n }\n let result: AxisId[][] = [[]];\n idsLists.forEach((list) => {\n const nextResult: AxisId[][] = [];\n list.forEach((key) => {\n nextResult.push(...result.map((resultItem) => [...resultItem, key]));\n });\n result = nextResult;\n });\n return result;\n}\n\nexport function isHiddenFromGraphColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);\n}\n\nexport function isHiddenFromUIColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.HideDataFromUi);\n}\n\nexport type AxesVault = Map<CanonicalizedJson<AxisId>, AxisSpecNormalized>;\n\nexport function getAvailableWithLinkersAxes(\n linkerColumns: (PColumnEntryWithLabel | PColumnEntryUniversal)[],\n blockAxes: AxesVault,\n): AxesVault {\n const linkerMap = LinkerMap.fromColumns(linkerColumns.map(getColumnIdAndSpec));\n const availableAxes = linkerMap.getReachableByLinkersAxesFromAxesNormalized(\n [...blockAxes.values()],\n (linkerKeyId, sourceAxisId) => matchAxisId(sourceAxisId, linkerKeyId),\n );\n\n return new Map(availableAxes.map((axisSpec) => {\n const id = getAxisId(axisSpec);\n return [canonicalizeJson(id), axisSpec];\n }));\n}\n/** Add columns with fully compatible axes created from partial compatible ones */\nexport function enrichCompatible<T extends Omit<PColumn<PColumnDataUniversal>, 'data'>>(blockAxes: AxesVault, columns: T[]): T[] {\n return columns.flatMap((column) => getAdditionalColumnsForColumn(blockAxes, column));\n}\n\nfunction getAdditionalColumnsForColumn<T extends Omit<PColumn<PColumnDataUniversal>, 'data'>>(\n blockAxes: AxesVault,\n column: T,\n): T[] {\n const columnAxesIds = column.spec.axesSpec.map(getAxisId);\n\n if (columnAxesIds.every((id) => blockAxes.has(canonicalizeJson(id)))) {\n return [column]; // the column is compatible with its own domains without modifications\n }\n\n // options with different possible domains for every axis of secondary column\n const secondaryIdsOptions = columnAxesIds.map((id) => {\n const result = [];\n for (const [_, mainId] of blockAxes) {\n if (matchAxisId(mainId, id) && !matchAxisId(id, mainId)) {\n result.push(mainId);\n }\n }\n return result;\n });\n // all possible combinations of axes with added domains\n const secondaryIdsVariants = getKeysCombinations(secondaryIdsOptions);\n\n // sets of added to column domain fields\n const allAddedDomainValues = new Set<string>();\n const addedNotToAllVariantsDomainValues = new Set<string>();\n const addedByVariantsDomainValues = secondaryIdsVariants.map((idsList) => {\n const addedSet = new Set<string>();\n idsList.map((axisId, idx) => {\n const d1 = column.spec.axesSpec[idx].domain;\n const d2 = axisId.domain;\n Object.entries(d2 ?? {}).forEach(([key, value]) => {\n if (d1?.[key] === undefined) {\n const item = JSON.stringify([key, value]);\n addedSet.add(item);\n allAddedDomainValues.add(item);\n }\n });\n return ({\n ...axisId,\n annotations: column.spec.axesSpec[idx].annotations,\n });\n });\n return addedSet;\n });\n [...allAddedDomainValues].forEach((addedPart) => {\n if (addedByVariantsDomainValues.some((s) => !s.has(addedPart))) {\n addedNotToAllVariantsDomainValues.add(addedPart);\n }\n });\n\n const additionalColumns = secondaryIdsVariants.map((idsList, idx) => {\n const id = colId(column.id, idsList.map((id) => id.domain));\n\n const label = readAnnotation(column.spec, Annotation.Label) ?? '';\n const labelDomainPart = ([...addedByVariantsDomainValues[idx]])\n .filter((str) => addedNotToAllVariantsDomainValues.has(str))\n .sort()\n .map((v) => JSON.parse(v)?.[1]) // use in labels only domain values, but sort them by key to save the same order in all column variants\n .join(' / ');\n\n const annotations: Annotation = {\n ...column.spec.annotations,\n [Annotation.Graph.IsVirtual]: stringifyJson(true),\n };\n if (label || labelDomainPart) {\n annotations[Annotation.Label] = label && labelDomainPart ? label + ' / ' + labelDomainPart : label + labelDomainPart;\n }\n\n return {\n ...column,\n id: id as PObjectId,\n spec: {\n ...column.spec,\n axesSpec: idsList.map((axisId, idx) => ({\n ...axisId,\n annotations: column.spec.axesSpec[idx].annotations,\n })),\n annotations,\n },\n };\n });\n\n return [column, ...additionalColumns];\n}\n\n/**\n The aim of createPFrameForGraphs: to create pframe with block’s columns and all compatible columns from result pool\n (including linker columns and all label columns).\n Block’s columns are added to pframe as is.\n Other columns are added basing on set of axes of block’s columns, considering available with linker columns.\n Compatible columns must have at least one axis from block’s axes set. This axis of the compatible column from\n result pool must satisfy matchAxisId (it can have less domain keys than in block’s axis, but without conflicting values\n among existing ones).\n In requests to pframe (calculateTableData) columns must have strictly the same axes. For compatibility in case\n of partially matched axis we add to pframe a copy of this column with modified axis (with filled missed domains)\n and modified label (with added domain values in case if more than one copy with different domains exist).\n */\nexport function createPFrameForGraphs<A, U>(\n ctx: RenderCtx<A, U>,\n blockColumns?: PColumn<PColumnDataUniversal>[],\n): PFrameHandle | undefined {\n const suitableSpec = (spec: PColumnSpec) => !isHiddenFromUIColumn(spec) && !isHiddenFromGraphColumn(spec);\n // if current block doesn't produce own columns then use all columns from result pool\n if (!blockColumns) {\n return ctx.createPFrame(getAllRelatedColumns(ctx, suitableSpec));\n };\n\n return ctx.createPFrame(getRelatedColumns(ctx, { columns: blockColumns, predicate: suitableSpec }));\n}\n"],"names":["readAnnotationJson","Annotation","LinkerMap","getColumnIdAndSpec","matchAxisId","getAxisId","canonicalizeJson","readAnnotation","stringifyJson","getAllRelatedColumns","getRelatedColumns"],"mappings":"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"}
1
+ {"version":3,"file":"PFrameForGraphs.cjs","sources":["../../src/components/PFrameForGraphs.ts"],"sourcesContent":["import type {\n AxisId,\n AxisSpecNormalized,\n CanonicalizedJson,\n PColumn,\n PColumnSpec,\n PFrameHandle,\n PObjectId,\n} from '@milaboratories/pl-model-common';\nimport {\n Annotation,\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec, LinkerMap,\n matchAxisId,\n readAnnotation,\n readAnnotationJson,\n stringifyJson,\n} from '@milaboratories/pl-model-common';\nimport type { PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, RenderCtxBase } from '../render';\nimport { getAllRelatedColumns, getRelatedColumns } from '../pframe_utils/columns';\n\n/** Create id for column copy with added keys in axes domains */\nconst colId = (id: PObjectId, domains: (Record<string, string> | undefined)[]) => {\n let wid = id.toString();\n domains?.forEach((domain) => {\n if (domain) {\n for (const [k, v] of Object.entries(domain)) {\n wid += k;\n wid += v;\n }\n }\n });\n return wid;\n};\n\n/** All combinations with 1 key from each list */\nfunction getKeysCombinations(idsLists: AxisId[][]) {\n if (!idsLists.length) {\n return [];\n }\n let result: AxisId[][] = [[]];\n idsLists.forEach((list) => {\n const nextResult: AxisId[][] = [];\n list.forEach((key) => {\n nextResult.push(...result.map((resultItem) => [...resultItem, key]));\n });\n result = nextResult;\n });\n return result;\n}\n\nexport function isHiddenFromGraphColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);\n}\n\nexport function isHiddenFromUIColumn(column: PColumnSpec): boolean {\n return !!readAnnotationJson(column, Annotation.HideDataFromUi);\n}\n\nexport type AxesVault = Map<CanonicalizedJson<AxisId>, AxisSpecNormalized>;\n\nexport function getAvailableWithLinkersAxes(\n linkerColumns: (PColumnEntryWithLabel | PColumnEntryUniversal)[],\n blockAxes: AxesVault,\n): AxesVault {\n const linkerMap = LinkerMap.fromColumns(linkerColumns.map(getColumnIdAndSpec));\n const availableAxes = linkerMap.getReachableByLinkersAxesFromAxesNormalized(\n [...blockAxes.values()],\n (linkerKeyId, sourceAxisId) => matchAxisId(sourceAxisId, linkerKeyId),\n );\n\n return new Map(availableAxes.map((axisSpec) => {\n const id = getAxisId(axisSpec);\n return [canonicalizeJson(id), axisSpec];\n }));\n}\n/** Add columns with fully compatible axes created from partial compatible ones */\nexport function enrichCompatible<T extends Omit<PColumn<PColumnDataUniversal>, 'data'>>(blockAxes: AxesVault, columns: T[]): T[] {\n return columns.flatMap((column) => getAdditionalColumnsForColumn(blockAxes, column));\n}\n\nfunction getAdditionalColumnsForColumn<T extends Omit<PColumn<PColumnDataUniversal>, 'data'>>(\n blockAxes: AxesVault,\n column: T,\n): T[] {\n const columnAxesIds = column.spec.axesSpec.map(getAxisId);\n\n if (columnAxesIds.every((id) => blockAxes.has(canonicalizeJson(id)))) {\n return [column]; // the column is compatible with its own domains without modifications\n }\n\n // options with different possible domains for every axis of secondary column\n const secondaryIdsOptions = columnAxesIds.map((id) => {\n const result = [];\n for (const [_, mainId] of blockAxes) {\n if (matchAxisId(mainId, id) && !matchAxisId(id, mainId)) {\n result.push(mainId);\n }\n }\n return result;\n });\n // all possible combinations of axes with added domains\n const secondaryIdsVariants = getKeysCombinations(secondaryIdsOptions);\n\n // sets of added to column domain fields\n const allAddedDomainValues = new Set<string>();\n const addedNotToAllVariantsDomainValues = new Set<string>();\n const addedByVariantsDomainValues = secondaryIdsVariants.map((idsList) => {\n const addedSet = new Set<string>();\n idsList.map((axisId, idx) => {\n const d1 = column.spec.axesSpec[idx].domain;\n const d2 = axisId.domain;\n Object.entries(d2 ?? {}).forEach(([key, value]) => {\n if (d1?.[key] === undefined) {\n const item = JSON.stringify([key, value]);\n addedSet.add(item);\n allAddedDomainValues.add(item);\n }\n });\n return ({\n ...axisId,\n annotations: column.spec.axesSpec[idx].annotations,\n });\n });\n return addedSet;\n });\n [...allAddedDomainValues].forEach((addedPart) => {\n if (addedByVariantsDomainValues.some((s) => !s.has(addedPart))) {\n addedNotToAllVariantsDomainValues.add(addedPart);\n }\n });\n\n const additionalColumns = secondaryIdsVariants.map((idsList, idx) => {\n const id = colId(column.id, idsList.map((id) => id.domain));\n\n const label = readAnnotation(column.spec, Annotation.Label) ?? '';\n const labelDomainPart = ([...addedByVariantsDomainValues[idx]])\n .filter((str) => addedNotToAllVariantsDomainValues.has(str))\n .sort()\n .map((v) => JSON.parse(v)?.[1]) // use in labels only domain values, but sort them by key to save the same order in all column variants\n .join(' / ');\n\n const annotations: Annotation = {\n ...column.spec.annotations,\n [Annotation.Graph.IsVirtual]: stringifyJson(true),\n };\n if (label || labelDomainPart) {\n annotations[Annotation.Label] = label && labelDomainPart ? label + ' / ' + labelDomainPart : label + labelDomainPart;\n }\n\n return {\n ...column,\n id: id as PObjectId,\n spec: {\n ...column.spec,\n axesSpec: idsList.map((axisId, idx) => ({\n ...axisId,\n annotations: column.spec.axesSpec[idx].annotations,\n })),\n annotations,\n },\n };\n });\n\n return [column, ...additionalColumns];\n}\n\n/**\n The aim of createPFrameForGraphs: to create pframe with block’s columns and all compatible columns from result pool\n (including linker columns and all label columns).\n Block’s columns are added to pframe as is.\n Other columns are added basing on set of axes of block’s columns, considering available with linker columns.\n Compatible columns must have at least one axis from block’s axes set. This axis of the compatible column from\n result pool must satisfy matchAxisId (it can have less domain keys than in block’s axis, but without conflicting values\n among existing ones).\n In requests to pframe (calculateTableData) columns must have strictly the same axes. For compatibility in case\n of partially matched axis we add to pframe a copy of this column with modified axis (with filled missed domains)\n and modified label (with added domain values in case if more than one copy with different domains exist).\n */\nexport function createPFrameForGraphs<A, U>(\n ctx: RenderCtxBase<A, U>,\n blockColumns?: PColumn<PColumnDataUniversal>[],\n): PFrameHandle | undefined {\n const suitableSpec = (spec: PColumnSpec) => !isHiddenFromUIColumn(spec) && !isHiddenFromGraphColumn(spec);\n // if current block doesn't produce own columns then use all columns from result pool\n if (!blockColumns) {\n return ctx.createPFrame(getAllRelatedColumns(ctx, suitableSpec));\n };\n\n return ctx.createPFrame(getRelatedColumns(ctx, { columns: blockColumns, predicate: suitableSpec }));\n}\n"],"names":["readAnnotationJson","Annotation","LinkerMap","getColumnIdAndSpec","matchAxisId","getAxisId","canonicalizeJson","readAnnotation","stringifyJson","getAllRelatedColumns","getRelatedColumns"],"mappings":";;;;;AAsBA;AACA,MAAM,KAAK,GAAG,CAAC,EAAa,EAAE,OAA+C,KAAI;AAC/E,IAAA,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE;AACvB,IAAA,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,KAAI;QAC1B,IAAI,MAAM,EAAE;AACV,YAAA,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC3C,GAAG,IAAI,CAAC;gBACR,GAAG,IAAI,CAAC;YACV;QACF;AACF,IAAA,CAAC,CAAC;AACF,IAAA,OAAO,GAAG;AACZ,CAAC;AAED;AACA,SAAS,mBAAmB,CAAC,QAAoB,EAAA;AAC/C,IAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;AACpB,QAAA,OAAO,EAAE;IACX;AACA,IAAA,IAAI,MAAM,GAAe,CAAC,EAAE,CAAC;AAC7B,IAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;QACxB,MAAM,UAAU,GAAe,EAAE;AACjC,QAAA,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,KAAI;YACnB,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;AACtE,QAAA,CAAC,CAAC;QACF,MAAM,GAAG,UAAU;AACrB,IAAA,CAAC,CAAC;AACF,IAAA,OAAO,MAAM;AACf;AAEM,SAAU,uBAAuB,CAAC,MAAmB,EAAA;IACzD,OAAO,CAAC,CAACA,gCAAkB,CAAC,MAAM,EAAEC,wBAAU,CAAC,kBAAkB,CAAC;AACpE;AAEM,SAAU,oBAAoB,CAAC,MAAmB,EAAA;IACtD,OAAO,CAAC,CAACD,gCAAkB,CAAC,MAAM,EAAEC,wBAAU,CAAC,cAAc,CAAC;AAChE;AAIM,SAAU,2BAA2B,CACzC,aAAgE,EAChE,SAAoB,EAAA;AAEpB,IAAA,MAAM,SAAS,GAAGC,uBAAS,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,CAACC,gCAAkB,CAAC,CAAC;AAC9E,IAAA,MAAM,aAAa,GAAG,SAAS,CAAC,2CAA2C,CACzE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EACvB,CAAC,WAAW,EAAE,YAAY,KAAKC,yBAAW,CAAC,YAAY,EAAE,WAAW,CAAC,CACtE;IAED,OAAO,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAI;AAC5C,QAAA,MAAM,EAAE,GAAGC,uBAAS,CAAC,QAAQ,CAAC;QAC9B,OAAO,CAACC,8BAAgB,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC;IACzC,CAAC,CAAC,CAAC;AACL;AACA;AACM,SAAU,gBAAgB,CAAwD,SAAoB,EAAE,OAAY,EAAA;AACxH,IAAA,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,6BAA6B,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACtF;AAEA,SAAS,6BAA6B,CACpC,SAAoB,EACpB,MAAS,EAAA;AAET,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAACD,uBAAS,CAAC;IAEzD,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,GAAG,CAACC,8BAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACpE,QAAA,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB;;IAGA,MAAM,mBAAmB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,KAAI;QACnD,MAAM,MAAM,GAAG,EAAE;QACjB,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,SAAS,EAAE;AACnC,YAAA,IAAIF,yBAAW,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAACA,yBAAW,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE;AACvD,gBAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACrB;QACF;AACA,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,CAAC;;AAEF,IAAA,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC;;AAGrE,IAAA,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU;AAC9C,IAAA,MAAM,iCAAiC,GAAG,IAAI,GAAG,EAAU;IAC3D,MAAM,2BAA2B,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,OAAO,KAAI;AACvE,QAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU;QAClC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,KAAI;AAC1B,YAAA,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM;AAC3C,YAAA,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM;AACxB,YAAA,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;gBAChD,IAAI,EAAE,GAAG,GAAG,CAAC,KAAK,SAAS,EAAE;AAC3B,oBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzC,oBAAA,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AAClB,oBAAA,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAChC;AACF,YAAA,CAAC,CAAC;AACF,YAAA,QAAQ;AACN,gBAAA,GAAG,MAAM;gBACT,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW;AACnD,aAAA;AACH,QAAA,CAAC,CAAC;AACF,QAAA,OAAO,QAAQ;AACjB,IAAA,CAAC,CAAC;IACF,CAAC,GAAG,oBAAoB,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;AAC9C,QAAA,IAAI,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE;AAC9D,YAAA,iCAAiC,CAAC,GAAG,CAAC,SAAS,CAAC;QAClD;AACF,IAAA,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,KAAI;QAClE,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;AAE3D,QAAA,MAAM,KAAK,GAAGG,4BAAc,CAAC,MAAM,CAAC,IAAI,EAAEN,wBAAU,CAAC,KAAK,CAAC,IAAI,EAAE;QACjE,MAAM,eAAe,GAAG,CAAC,CAAC,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;AAC3D,aAAA,MAAM,CAAC,CAAC,GAAG,KAAK,iCAAiC,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1D,aAAA,IAAI;AACJ,aAAA,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;aAC9B,IAAI,CAAC,KAAK,CAAC;AAEd,QAAA,MAAM,WAAW,GAAe;AAC9B,YAAA,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW;YAC1B,CAACA,wBAAU,CAAC,KAAK,CAAC,SAAS,GAAGO,2BAAa,CAAC,IAAI,CAAC;SAClD;AACD,QAAA,IAAI,KAAK,IAAI,eAAe,EAAE;YAC5B,WAAW,CAACP,wBAAU,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,eAAe,GAAG,KAAK,GAAG,eAAe;QACtH;QAEA,OAAO;AACL,YAAA,GAAG,MAAM;AACT,YAAA,EAAE,EAAE,EAAe;AACnB,YAAA,IAAI,EAAE;gBACJ,GAAG,MAAM,CAAC,IAAI;AACd,gBAAA,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM;AACtC,oBAAA,GAAG,MAAM;oBACT,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW;AACnD,iBAAA,CAAC,CAAC;gBACH,WAAW;AACZ,aAAA;SACF;AACH,IAAA,CAAC,CAAC;AAEF,IAAA,OAAO,CAAC,MAAM,EAAE,GAAG,iBAAiB,CAAC;AACvC;AAEA;;;;;;;;;;;AAWG;AACG,SAAU,qBAAqB,CACnC,GAAwB,EACxB,YAA8C,EAAA;AAE9C,IAAA,MAAM,YAAY,GAAG,CAAC,IAAiB,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;;IAEzG,IAAI,CAAC,YAAY,EAAE;QACjB,OAAO,GAAG,CAAC,YAAY,CAACQ,4BAAoB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAClE;AAEA,IAAA,OAAO,GAAG,CAAC,YAAY,CAACC,yBAAiB,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;AACrG;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import type { AxisId, AxisSpecNormalized, CanonicalizedJson, PColumn, PColumnSpec, PFrameHandle } from '@milaboratories/pl-model-common';
2
- import type { PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, RenderCtx } from '../render';
2
+ import type { PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, RenderCtxBase } from '../render';
3
3
  export declare function isHiddenFromGraphColumn(column: PColumnSpec): boolean;
4
4
  export declare function isHiddenFromUIColumn(column: PColumnSpec): boolean;
5
5
  export type AxesVault = Map<CanonicalizedJson<AxisId>, AxisSpecNormalized>;
@@ -18,5 +18,5 @@ export declare function enrichCompatible<T extends Omit<PColumn<PColumnDataUnive
18
18
  of partially matched axis we add to pframe a copy of this column with modified axis (with filled missed domains)
19
19
  and modified label (with added domain values in case if more than one copy with different domains exist).
20
20
  */
21
- export declare function createPFrameForGraphs<A, U>(ctx: RenderCtx<A, U>, blockColumns?: PColumn<PColumnDataUniversal>[]): PFrameHandle | undefined;
21
+ export declare function createPFrameForGraphs<A, U>(ctx: RenderCtxBase<A, U>, blockColumns?: PColumn<PColumnDataUniversal>[]): PFrameHandle | undefined;
22
22
  //# sourceMappingURL=PFrameForGraphs.d.ts.map