@platforma-sdk/model 1.51.9 → 1.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bconfig/lambdas.d.ts +26 -4
- package/dist/bconfig/lambdas.d.ts.map +1 -1
- package/dist/bconfig/v3.d.ts +4 -2
- package/dist/bconfig/v3.d.ts.map +1 -1
- package/dist/block_api_v3.d.ts +32 -0
- package/dist/block_api_v3.d.ts.map +1 -0
- package/dist/block_migrations.cjs +138 -0
- package/dist/block_migrations.cjs.map +1 -0
- package/dist/block_migrations.d.ts +79 -0
- package/dist/block_migrations.d.ts.map +1 -0
- package/dist/block_migrations.js +136 -0
- package/dist/block_migrations.js.map +1 -0
- package/dist/block_model.cjs +222 -0
- package/dist/block_model.cjs.map +1 -0
- package/dist/block_model.d.ts +132 -0
- package/dist/block_model.d.ts.map +1 -0
- package/dist/block_model.js +220 -0
- package/dist/block_model.js.map +1 -0
- package/dist/block_storage.cjs +244 -0
- package/dist/block_storage.cjs.map +1 -0
- package/dist/block_storage.d.ts +208 -0
- package/dist/block_storage.d.ts.map +1 -0
- package/dist/block_storage.js +225 -0
- package/dist/block_storage.js.map +1 -0
- package/dist/block_storage_vm.cjs +264 -0
- package/dist/block_storage_vm.cjs.map +1 -0
- package/dist/block_storage_vm.d.ts +67 -0
- package/dist/block_storage_vm.d.ts.map +1 -0
- package/dist/block_storage_vm.js +260 -0
- package/dist/block_storage_vm.js.map +1 -0
- package/dist/builder.cjs +9 -6
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.ts +15 -30
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +10 -7
- package/dist/builder.js.map +1 -1
- package/dist/components/PlDataTable.cjs.map +1 -1
- package/dist/components/PlDataTable.d.ts +2 -2
- package/dist/components/PlDataTable.d.ts.map +1 -1
- package/dist/components/PlDataTable.js.map +1 -1
- package/dist/index.cjs +25 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +38 -0
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.ts +21 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +36 -1
- package/dist/internal.js.map +1 -1
- package/dist/package.json.cjs +1 -1
- package/dist/package.json.js +1 -1
- package/dist/platforma.d.ts +18 -3
- package/dist/platforma.d.ts.map +1 -1
- package/dist/render/api.cjs +43 -16
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +19 -7
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +42 -17
- package/dist/render/api.js.map +1 -1
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +3 -1
- package/dist/render/internal.d.ts.map +1 -1
- package/dist/render/internal.js.map +1 -1
- package/package.json +7 -7
- package/src/bconfig/lambdas.ts +35 -4
- package/src/bconfig/v3.ts +12 -2
- package/src/block_api_v3.ts +49 -0
- package/src/block_migrations.ts +173 -0
- package/src/block_model.ts +440 -0
- package/src/block_storage.test.ts +258 -0
- package/src/block_storage.ts +365 -0
- package/src/block_storage_vm.ts +349 -0
- package/src/builder.ts +24 -59
- package/src/components/PlDataTable.ts +2 -1
- package/src/index.ts +3 -0
- package/src/internal.ts +51 -0
- package/src/platforma.ts +31 -5
- package/src/render/api.ts +52 -21
- package/src/render/internal.ts +3 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlockStorage - Typed storage abstraction for block persistent data.
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - A typed structure for block storage with versioning and plugin support
|
|
6
|
+
* - Utility functions for manipulating storage
|
|
7
|
+
* - Handler interfaces for model-level customization
|
|
8
|
+
*
|
|
9
|
+
* @module block_storage
|
|
10
|
+
*/
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Core Types
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Discriminator key for BlockStorage format detection.
|
|
16
|
+
* This unique hash-based key identifies data as BlockStorage vs legacy formats.
|
|
17
|
+
*/
|
|
18
|
+
const BLOCK_STORAGE_KEY = '__pl_a7f3e2b9__';
|
|
19
|
+
/**
|
|
20
|
+
* Current BlockStorage schema version.
|
|
21
|
+
* Increment this when the storage structure itself changes (not block state migrations).
|
|
22
|
+
*/
|
|
23
|
+
const BLOCK_STORAGE_SCHEMA_VERSION = 'v1';
|
|
24
|
+
/**
|
|
25
|
+
* Type guard to check if a value is a valid BlockStorage object.
|
|
26
|
+
* Checks for the discriminator key and valid schema version.
|
|
27
|
+
*/
|
|
28
|
+
function isBlockStorage(value) {
|
|
29
|
+
if (value === null || typeof value !== 'object')
|
|
30
|
+
return false;
|
|
31
|
+
const obj = value;
|
|
32
|
+
const schemaVersion = obj[BLOCK_STORAGE_KEY];
|
|
33
|
+
// Currently only 'v1' is valid, but this allows future versions
|
|
34
|
+
return schemaVersion === 'v1'; // Add more versions as schema evolves
|
|
35
|
+
}
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// Factory Functions
|
|
38
|
+
// =============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Creates a BlockStorage with the given initial data
|
|
41
|
+
*
|
|
42
|
+
* @param initialData - The initial data value (defaults to empty object)
|
|
43
|
+
* @param version - The initial data version (defaults to 1)
|
|
44
|
+
* @returns A new BlockStorage instance with discriminator key
|
|
45
|
+
*/
|
|
46
|
+
function createBlockStorage(initialData = {}, version = 1) {
|
|
47
|
+
return {
|
|
48
|
+
[BLOCK_STORAGE_KEY]: BLOCK_STORAGE_SCHEMA_VERSION,
|
|
49
|
+
__dataVersion: version,
|
|
50
|
+
__data: initialData,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Normalizes raw storage data to BlockStorage format.
|
|
55
|
+
* If the input is already a BlockStorage, returns it as-is.
|
|
56
|
+
* If the input is legacy format (raw state), wraps it in BlockStorage structure.
|
|
57
|
+
*
|
|
58
|
+
* @param raw - Raw storage data (may be legacy format or BlockStorage)
|
|
59
|
+
* @returns Normalized BlockStorage
|
|
60
|
+
*/
|
|
61
|
+
function normalizeBlockStorage(raw) {
|
|
62
|
+
if (isBlockStorage(raw)) {
|
|
63
|
+
return raw;
|
|
64
|
+
}
|
|
65
|
+
// Legacy format: raw is the state directly
|
|
66
|
+
return createBlockStorage(raw, 1);
|
|
67
|
+
}
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Data Access & Update Functions
|
|
70
|
+
// =============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Gets the data from BlockStorage
|
|
73
|
+
*
|
|
74
|
+
* @param storage - The BlockStorage instance
|
|
75
|
+
* @returns The data value
|
|
76
|
+
*/
|
|
77
|
+
function getStorageData(storage) {
|
|
78
|
+
return storage.__data;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Derives data from raw block storage.
|
|
82
|
+
* This function is meant to be called from sdk/ui-vue to extract
|
|
83
|
+
* user-facing data from the raw storage returned by the middle layer.
|
|
84
|
+
*
|
|
85
|
+
* The middle layer returns raw storage (opaque to it), and the UI
|
|
86
|
+
* uses this function to derive the actual data value.
|
|
87
|
+
*
|
|
88
|
+
* @param rawStorage - Raw storage data from middle layer (may be any format)
|
|
89
|
+
* @returns The extracted data value, or undefined if storage is undefined/null
|
|
90
|
+
*/
|
|
91
|
+
function deriveDataFromStorage(rawStorage) {
|
|
92
|
+
// Normalize to BlockStorage format (handles legacy formats too)
|
|
93
|
+
const storage = normalizeBlockStorage(rawStorage);
|
|
94
|
+
return getStorageData(storage);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Updates the data in BlockStorage (immutable)
|
|
98
|
+
*
|
|
99
|
+
* @param storage - The current BlockStorage
|
|
100
|
+
* @param payload - The update payload with operation and value
|
|
101
|
+
* @returns A new BlockStorage with updated data
|
|
102
|
+
*/
|
|
103
|
+
function updateStorageData(storage, payload) {
|
|
104
|
+
switch (payload.operation) {
|
|
105
|
+
case 'update-data':
|
|
106
|
+
return { ...storage, __data: payload.value };
|
|
107
|
+
default:
|
|
108
|
+
throw new Error(`Unknown storage operation: ${payload.operation}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Gets the data version from BlockStorage
|
|
113
|
+
*
|
|
114
|
+
* @param storage - The BlockStorage instance
|
|
115
|
+
* @returns The data version number
|
|
116
|
+
*/
|
|
117
|
+
function getStorageDataVersion(storage) {
|
|
118
|
+
return storage.__dataVersion;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Updates the data version in BlockStorage (immutable)
|
|
122
|
+
*
|
|
123
|
+
* @param storage - The current BlockStorage
|
|
124
|
+
* @param version - The new version number
|
|
125
|
+
* @returns A new BlockStorage with updated version
|
|
126
|
+
*/
|
|
127
|
+
function updateStorageDataVersion(storage, version) {
|
|
128
|
+
return { ...storage, __dataVersion: version };
|
|
129
|
+
}
|
|
130
|
+
// =============================================================================
|
|
131
|
+
// Plugin Data Functions
|
|
132
|
+
// =============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Gets plugin-specific data from BlockStorage
|
|
135
|
+
*
|
|
136
|
+
* @param storage - The BlockStorage instance
|
|
137
|
+
* @param pluginName - The plugin name (without `@plugin/` prefix)
|
|
138
|
+
* @returns The plugin data or undefined if not set
|
|
139
|
+
*/
|
|
140
|
+
function getPluginData(storage, pluginName) {
|
|
141
|
+
const key = `@plugin/${pluginName}`;
|
|
142
|
+
return storage[key];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Sets plugin-specific data in BlockStorage (immutable)
|
|
146
|
+
*
|
|
147
|
+
* @param storage - The current BlockStorage
|
|
148
|
+
* @param pluginName - The plugin name (without `@plugin/` prefix)
|
|
149
|
+
* @param data - The plugin data to store
|
|
150
|
+
* @returns A new BlockStorage with updated plugin data
|
|
151
|
+
*/
|
|
152
|
+
function setPluginData(storage, pluginName, data) {
|
|
153
|
+
const key = `@plugin/${pluginName}`;
|
|
154
|
+
return { ...storage, [key]: data };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Removes plugin-specific data from BlockStorage (immutable)
|
|
158
|
+
*
|
|
159
|
+
* @param storage - The current BlockStorage
|
|
160
|
+
* @param pluginName - The plugin name (without `@plugin/` prefix)
|
|
161
|
+
* @returns A new BlockStorage with the plugin data removed
|
|
162
|
+
*/
|
|
163
|
+
function removePluginData(storage, pluginName) {
|
|
164
|
+
const key = `@plugin/${pluginName}`;
|
|
165
|
+
const { [key]: _, ...rest } = storage;
|
|
166
|
+
return rest;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Gets all plugin names that have data stored
|
|
170
|
+
*
|
|
171
|
+
* @param storage - The BlockStorage instance
|
|
172
|
+
* @returns Array of plugin names (without `@plugin/` prefix)
|
|
173
|
+
*/
|
|
174
|
+
function getPluginNames(storage) {
|
|
175
|
+
return Object.keys(storage)
|
|
176
|
+
.filter((key) => key.startsWith('@plugin/'))
|
|
177
|
+
.map((key) => key.slice('@plugin/'.length));
|
|
178
|
+
}
|
|
179
|
+
// =============================================================================
|
|
180
|
+
// Generic Storage Access
|
|
181
|
+
// =============================================================================
|
|
182
|
+
/**
|
|
183
|
+
* Gets a value from BlockStorage by key
|
|
184
|
+
*
|
|
185
|
+
* @param storage - The BlockStorage instance
|
|
186
|
+
* @param key - The key to retrieve
|
|
187
|
+
* @returns The value at the given key
|
|
188
|
+
*/
|
|
189
|
+
function getFromStorage(storage, key) {
|
|
190
|
+
return storage[key];
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Updates a value in BlockStorage by key (immutable)
|
|
194
|
+
*
|
|
195
|
+
* @param storage - The current BlockStorage
|
|
196
|
+
* @param key - The key to update
|
|
197
|
+
* @param value - The new value
|
|
198
|
+
* @returns A new BlockStorage with the updated value
|
|
199
|
+
*/
|
|
200
|
+
function updateStorage(storage, key, value) {
|
|
201
|
+
return { ...storage, [key]: value };
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Default implementations of storage handlers
|
|
205
|
+
*/
|
|
206
|
+
const defaultBlockStorageHandlers = {
|
|
207
|
+
transformStateForStorage: (storage, newState) => updateStorageData(storage, { operation: 'update-data', value: newState }),
|
|
208
|
+
deriveStateForArgs: (storage) => getStorageData(storage),
|
|
209
|
+
migrateStorage: (storage, _fromVersion, toVersion) => updateStorageDataVersion(storage, toVersion),
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Merges custom handlers with defaults
|
|
213
|
+
*
|
|
214
|
+
* @param customHandlers - Custom handlers to merge
|
|
215
|
+
* @returns Complete handlers with defaults for missing functions
|
|
216
|
+
*/
|
|
217
|
+
function mergeBlockStorageHandlers(customHandlers) {
|
|
218
|
+
return {
|
|
219
|
+
...defaultBlockStorageHandlers,
|
|
220
|
+
...customHandlers,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION, createBlockStorage, defaultBlockStorageHandlers, deriveDataFromStorage, getFromStorage, getPluginData, getPluginNames, getStorageData, getStorageDataVersion, isBlockStorage, mergeBlockStorageHandlers, normalizeBlockStorage, removePluginData, setPluginData, updateStorage, updateStorageData, updateStorageDataVersion };
|
|
225
|
+
//# sourceMappingURL=block_storage.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var block_storage = require('./block_storage.cjs');
|
|
4
|
+
var internal = require('./internal.cjs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* BlockStorage VM Integration - Internal module for VM-based storage operations.
|
|
8
|
+
*
|
|
9
|
+
* This module auto-registers internal callbacks that the middle layer can invoke
|
|
10
|
+
* to perform storage transformations. Block developers never interact with these
|
|
11
|
+
* directly - they only see `state`.
|
|
12
|
+
*
|
|
13
|
+
* Registered callbacks (all prefixed with `__pl_` for internal SDK use):
|
|
14
|
+
* - `__pl_storage_normalize`: (rawStorage) => { storage, data }
|
|
15
|
+
* - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
|
|
16
|
+
* - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
|
|
17
|
+
* - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
|
|
18
|
+
* - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
|
|
19
|
+
* - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
|
|
20
|
+
*
|
|
21
|
+
* Callbacks registered by DataModel.registerCallbacks():
|
|
22
|
+
* - `__pl_data_initial`: () => initial data
|
|
23
|
+
* - `__pl_data_upgrade`: (versioned) => UpgradeResult
|
|
24
|
+
* - `__pl_storage_initial`: () => initial BlockStorage as JSON string
|
|
25
|
+
*
|
|
26
|
+
* @module block_storage_vm
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Normalizes raw storage data and extracts state.
|
|
31
|
+
* Handles all formats:
|
|
32
|
+
* - New BlockStorage format (has discriminator)
|
|
33
|
+
* - Legacy V1/V2 format ({ args, uiState })
|
|
34
|
+
* - Raw V3 state (any other format)
|
|
35
|
+
*
|
|
36
|
+
* @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
|
|
37
|
+
* @returns Object with normalized storage and extracted state
|
|
38
|
+
*/
|
|
39
|
+
function normalizeStorage(rawStorage) {
|
|
40
|
+
// Handle undefined/null
|
|
41
|
+
if (rawStorage === undefined || rawStorage === null) {
|
|
42
|
+
const storage = block_storage.createBlockStorage({});
|
|
43
|
+
return { storage, data: {} };
|
|
44
|
+
}
|
|
45
|
+
// Parse JSON string if needed
|
|
46
|
+
let parsed = rawStorage;
|
|
47
|
+
if (typeof rawStorage === 'string') {
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(rawStorage);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// If parsing fails, treat string as the data
|
|
53
|
+
const storage = block_storage.createBlockStorage(rawStorage);
|
|
54
|
+
return { storage, data: rawStorage };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Check for BlockStorage format (has discriminator)
|
|
58
|
+
if (block_storage.isBlockStorage(parsed)) {
|
|
59
|
+
return { storage: parsed, data: block_storage.getStorageData(parsed) };
|
|
60
|
+
}
|
|
61
|
+
// Check for legacy V1/V2 format: { args, uiState }
|
|
62
|
+
if (isLegacyModelV1ApiFormat(parsed)) {
|
|
63
|
+
// For legacy format, the whole object IS the data
|
|
64
|
+
const storage = block_storage.createBlockStorage(parsed);
|
|
65
|
+
return { storage, data: parsed };
|
|
66
|
+
}
|
|
67
|
+
// Raw V3 data - wrap it
|
|
68
|
+
const storage = block_storage.createBlockStorage(parsed);
|
|
69
|
+
return { storage, data: parsed };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Applies a state update to existing storage.
|
|
73
|
+
* Used when setData is called from the frontend.
|
|
74
|
+
*
|
|
75
|
+
* @param currentStorageJson - Current storage as JSON string (must be defined)
|
|
76
|
+
* @param newData - New data from application
|
|
77
|
+
* @returns Updated storage as JSON string
|
|
78
|
+
*/
|
|
79
|
+
function applyStorageUpdate(currentStorageJson, payload) {
|
|
80
|
+
const { storage: currentStorage } = normalizeStorage(currentStorageJson);
|
|
81
|
+
// Update data while preserving other storage fields (version, plugins)
|
|
82
|
+
const updatedStorage = block_storage.updateStorageData(currentStorage, payload);
|
|
83
|
+
return JSON.stringify(updatedStorage);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Checks if data is in legacy Model API v1 format.
|
|
87
|
+
* Legacy format has { args, uiState? } at top level without the BlockStorage discriminator.
|
|
88
|
+
*/
|
|
89
|
+
function isLegacyModelV1ApiFormat(data) {
|
|
90
|
+
if (data === null || typeof data !== 'object')
|
|
91
|
+
return false;
|
|
92
|
+
if (block_storage.isBlockStorage(data))
|
|
93
|
+
return false;
|
|
94
|
+
const obj = data;
|
|
95
|
+
return 'args' in obj;
|
|
96
|
+
}
|
|
97
|
+
// =============================================================================
|
|
98
|
+
// Auto-register internal callbacks when module is loaded in VM
|
|
99
|
+
// =============================================================================
|
|
100
|
+
// Register normalize callback
|
|
101
|
+
internal.tryRegisterCallback('__pl_storage_normalize', (rawStorage) => {
|
|
102
|
+
return normalizeStorage(rawStorage);
|
|
103
|
+
});
|
|
104
|
+
// Register apply update callback (requires existing storage)
|
|
105
|
+
internal.tryRegisterCallback('__pl_storage_applyUpdate', (currentStorageJson, payload) => {
|
|
106
|
+
return applyStorageUpdate(currentStorageJson, payload);
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* Gets storage info from raw storage data.
|
|
110
|
+
* Returns structured info about the storage state.
|
|
111
|
+
*
|
|
112
|
+
* @param rawStorage - Raw data from blockStorage field (may be JSON string or object)
|
|
113
|
+
* @returns JSON string with storage info
|
|
114
|
+
*/
|
|
115
|
+
function getStorageInfo(rawStorage) {
|
|
116
|
+
const { storage } = normalizeStorage(rawStorage);
|
|
117
|
+
const info = {
|
|
118
|
+
dataVersion: storage.__dataVersion,
|
|
119
|
+
};
|
|
120
|
+
return JSON.stringify(info);
|
|
121
|
+
}
|
|
122
|
+
// Register get info callback
|
|
123
|
+
internal.tryRegisterCallback('__pl_storage_getInfo', (rawStorage) => {
|
|
124
|
+
return getStorageInfo(rawStorage);
|
|
125
|
+
});
|
|
126
|
+
/**
|
|
127
|
+
* Runs storage migration using the DataModel's upgrade callback.
|
|
128
|
+
* This is the main entry point for the middle layer to trigger migrations.
|
|
129
|
+
*
|
|
130
|
+
* Uses the '__pl_data_upgrade' callback registered by DataModel.registerCallbacks() which:
|
|
131
|
+
* - Handles all migration logic internally
|
|
132
|
+
* - Returns { version, data, warning? } - warning present if reset to initial data
|
|
133
|
+
*
|
|
134
|
+
* @param currentStorageJson - Current storage as JSON string (or undefined)
|
|
135
|
+
* @returns MigrationResult
|
|
136
|
+
*/
|
|
137
|
+
function migrateStorage(currentStorageJson) {
|
|
138
|
+
// Get the callback registry context
|
|
139
|
+
const ctx = internal.tryGetCfgRenderCtx();
|
|
140
|
+
if (ctx === undefined) {
|
|
141
|
+
return { error: 'Not in config rendering context' };
|
|
142
|
+
}
|
|
143
|
+
// Normalize storage to get current data and version
|
|
144
|
+
const { storage: currentStorage, data: currentData } = normalizeStorage(currentStorageJson);
|
|
145
|
+
const currentVersion = currentStorage.__dataVersion;
|
|
146
|
+
// Helper to create storage with given data and version
|
|
147
|
+
const createStorageJson = (data, version) => {
|
|
148
|
+
return JSON.stringify({
|
|
149
|
+
...currentStorage,
|
|
150
|
+
__dataVersion: version,
|
|
151
|
+
__data: data,
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
// Get the upgrade callback (registered by DataModel.registerCallbacks())
|
|
155
|
+
const upgradeCallback = ctx.callbackRegistry['__pl_data_upgrade'];
|
|
156
|
+
if (typeof upgradeCallback !== 'function') {
|
|
157
|
+
return { error: '__pl_data_upgrade callback not found (DataModel not registered)' };
|
|
158
|
+
}
|
|
159
|
+
// Call the migrator's upgrade function
|
|
160
|
+
let result;
|
|
161
|
+
try {
|
|
162
|
+
result = upgradeCallback({ version: currentVersion, data: currentData });
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
166
|
+
return { error: `upgrade() threw: ${errorMsg}` };
|
|
167
|
+
}
|
|
168
|
+
// Build info message
|
|
169
|
+
const info = result.version === currentVersion
|
|
170
|
+
? `No migration needed (v${currentVersion})`
|
|
171
|
+
: result.warning
|
|
172
|
+
? `Reset to initial data (v${result.version})`
|
|
173
|
+
: `Migrated v${currentVersion}→v${result.version}`;
|
|
174
|
+
return {
|
|
175
|
+
newStorageJson: createStorageJson(result.data, result.version),
|
|
176
|
+
info,
|
|
177
|
+
warn: result.warning,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Register migrate callback
|
|
181
|
+
internal.tryRegisterCallback('__pl_storage_migrate', (currentStorageJson) => {
|
|
182
|
+
return migrateStorage(currentStorageJson);
|
|
183
|
+
});
|
|
184
|
+
/**
|
|
185
|
+
* Derives args from storage using the registered 'args' callback.
|
|
186
|
+
* This extracts data from storage and passes it to the block's args() function.
|
|
187
|
+
*
|
|
188
|
+
* @param storageJson - Storage as JSON string
|
|
189
|
+
* @returns ArgsDeriveResult with derived args or error
|
|
190
|
+
*/
|
|
191
|
+
function deriveArgsFromStorage(storageJson) {
|
|
192
|
+
const ctx = internal.tryGetCfgRenderCtx();
|
|
193
|
+
if (ctx === undefined) {
|
|
194
|
+
return { error: 'Not in config rendering context' };
|
|
195
|
+
}
|
|
196
|
+
// Extract data from storage
|
|
197
|
+
const { data } = normalizeStorage(storageJson);
|
|
198
|
+
// Get the args callback (registered by BlockModelV3.args())
|
|
199
|
+
const argsCallback = ctx.callbackRegistry['args'];
|
|
200
|
+
if (typeof argsCallback !== 'function') {
|
|
201
|
+
return { error: 'args callback not found' };
|
|
202
|
+
}
|
|
203
|
+
// Call the args callback with extracted data
|
|
204
|
+
try {
|
|
205
|
+
const result = argsCallback(data);
|
|
206
|
+
return { value: result };
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
210
|
+
return { error: `args() threw: ${errorMsg}` };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Register args derivation callback
|
|
214
|
+
internal.tryRegisterCallback('__pl_args_derive', (storageJson) => {
|
|
215
|
+
return deriveArgsFromStorage(storageJson);
|
|
216
|
+
});
|
|
217
|
+
/**
|
|
218
|
+
* Derives prerunArgs from storage using the registered 'prerunArgs' callback.
|
|
219
|
+
* Falls back to 'args' callback if 'prerunArgs' is not defined.
|
|
220
|
+
*
|
|
221
|
+
* @param storageJson - Storage as JSON string
|
|
222
|
+
* @returns ArgsDeriveResult with derived prerunArgs or error
|
|
223
|
+
*/
|
|
224
|
+
function derivePrerunArgsFromStorage(storageJson) {
|
|
225
|
+
const ctx = internal.tryGetCfgRenderCtx();
|
|
226
|
+
if (ctx === undefined) {
|
|
227
|
+
return { error: 'Not in config rendering context' };
|
|
228
|
+
}
|
|
229
|
+
// Extract data from storage
|
|
230
|
+
const { data } = normalizeStorage(storageJson);
|
|
231
|
+
// Try prerunArgs callback first
|
|
232
|
+
const prerunArgsCallback = ctx.callbackRegistry['prerunArgs'];
|
|
233
|
+
if (typeof prerunArgsCallback === 'function') {
|
|
234
|
+
try {
|
|
235
|
+
const result = prerunArgsCallback(data);
|
|
236
|
+
return { value: result };
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
240
|
+
return { error: `prerunArgs() threw: ${errorMsg}` };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Fall back to args callback
|
|
244
|
+
const argsCallback = ctx.callbackRegistry['args'];
|
|
245
|
+
if (typeof argsCallback !== 'function') {
|
|
246
|
+
return { error: 'args callback not found (fallback from missing prerunArgs)' };
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
const result = argsCallback(data);
|
|
250
|
+
return { value: result };
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
254
|
+
return { error: `args() threw (fallback): ${errorMsg}` };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Register prerunArgs derivation callback
|
|
258
|
+
internal.tryRegisterCallback('__pl_prerunArgs_derive', (storageJson) => {
|
|
259
|
+
return derivePrerunArgsFromStorage(storageJson);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
exports.BLOCK_STORAGE_KEY = block_storage.BLOCK_STORAGE_KEY;
|
|
263
|
+
exports.BLOCK_STORAGE_SCHEMA_VERSION = block_storage.BLOCK_STORAGE_SCHEMA_VERSION;
|
|
264
|
+
//# sourceMappingURL=block_storage_vm.cjs.map
|
|
@@ -0,0 +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":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlockStorage VM Integration - Internal module for VM-based storage operations.
|
|
3
|
+
*
|
|
4
|
+
* This module auto-registers internal callbacks that the middle layer can invoke
|
|
5
|
+
* to perform storage transformations. Block developers never interact with these
|
|
6
|
+
* directly - they only see `state`.
|
|
7
|
+
*
|
|
8
|
+
* Registered callbacks (all prefixed with `__pl_` for internal SDK use):
|
|
9
|
+
* - `__pl_storage_normalize`: (rawStorage) => { storage, data }
|
|
10
|
+
* - `__pl_storage_applyUpdate`: (currentStorageJson, payload) => updatedStorageJson
|
|
11
|
+
* - `__pl_storage_getInfo`: (rawStorage) => JSON string with storage info
|
|
12
|
+
* - `__pl_storage_migrate`: (currentStorageJson) => MigrationResult
|
|
13
|
+
* - `__pl_args_derive`: (storageJson) => ArgsDeriveResult
|
|
14
|
+
* - `__pl_prerunArgs_derive`: (storageJson) => ArgsDeriveResult
|
|
15
|
+
*
|
|
16
|
+
* Callbacks registered by DataModel.registerCallbacks():
|
|
17
|
+
* - `__pl_data_initial`: () => initial data
|
|
18
|
+
* - `__pl_data_upgrade`: (versioned) => UpgradeResult
|
|
19
|
+
* - `__pl_storage_initial`: () => initial BlockStorage as JSON string
|
|
20
|
+
*
|
|
21
|
+
* @module block_storage_vm
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
import { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION, type BlockStorage } from './block_storage';
|
|
25
|
+
/**
|
|
26
|
+
* Result of storage normalization
|
|
27
|
+
*/
|
|
28
|
+
export interface NormalizeStorageResult {
|
|
29
|
+
/** The normalized BlockStorage object */
|
|
30
|
+
storage: BlockStorage;
|
|
31
|
+
/** The extracted data (what developers see) */
|
|
32
|
+
data: unknown;
|
|
33
|
+
}
|
|
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
|
+
/**
|
|
42
|
+
* Result of storage migration.
|
|
43
|
+
* Returned by __pl_storage_migrate callback.
|
|
44
|
+
*
|
|
45
|
+
* - Error result: { error: string } - serious failure (no context, etc.)
|
|
46
|
+
* - Success result: { newStorageJson: string, info: string, warn?: string } - migration succeeded or reset to initial
|
|
47
|
+
*/
|
|
48
|
+
export type MigrationResult = {
|
|
49
|
+
error: string;
|
|
50
|
+
} | {
|
|
51
|
+
error?: undefined;
|
|
52
|
+
newStorageJson: string;
|
|
53
|
+
info: string;
|
|
54
|
+
warn?: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Result of args derivation from storage.
|
|
58
|
+
* Returned by __pl_args_derive and __pl_prerunArgs_derive callbacks.
|
|
59
|
+
*/
|
|
60
|
+
export type ArgsDeriveResult = {
|
|
61
|
+
error: string;
|
|
62
|
+
} | {
|
|
63
|
+
error?: undefined;
|
|
64
|
+
value: unknown;
|
|
65
|
+
};
|
|
66
|
+
export { BLOCK_STORAGE_KEY, BLOCK_STORAGE_SCHEMA_VERSION };
|
|
67
|
+
//# sourceMappingURL=block_storage_vm.d.ts.map
|
|
@@ -0,0 +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"}
|