@milaboratories/pl-middle-layer 1.46.34 → 1.47.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/index.cjs +0 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/middle_layer/frontend_path.cjs +0 -1
- package/dist/middle_layer/frontend_path.cjs.map +1 -1
- package/dist/middle_layer/frontend_path.js +0 -1
- package/dist/middle_layer/frontend_path.js.map +1 -1
- package/dist/middle_layer/middle_layer.cjs +5 -1
- package/dist/middle_layer/middle_layer.cjs.map +1 -1
- package/dist/middle_layer/middle_layer.d.ts +3 -1
- package/dist/middle_layer/middle_layer.d.ts.map +1 -1
- package/dist/middle_layer/middle_layer.js +5 -1
- package/dist/middle_layer/middle_layer.js.map +1 -1
- package/dist/middle_layer/project.cjs +8 -6
- package/dist/middle_layer/project.cjs.map +1 -1
- package/dist/middle_layer/project.d.ts.map +1 -1
- package/dist/middle_layer/project.js +9 -7
- package/dist/middle_layer/project.js.map +1 -1
- package/dist/middle_layer/project_overview.cjs +2 -2
- package/dist/middle_layer/project_overview.cjs.map +1 -1
- package/dist/middle_layer/project_overview.js +3 -3
- package/dist/middle_layer/project_overview.js.map +1 -1
- package/dist/model/index.d.ts +0 -1
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/project_helper.cjs +20 -32
- package/dist/model/project_helper.cjs.map +1 -1
- package/dist/model/project_helper.d.ts +3 -4
- package/dist/model/project_helper.d.ts.map +1 -1
- package/dist/model/project_helper.js +21 -33
- package/dist/model/project_helper.js.map +1 -1
- package/dist/mutator/block-pack/frontend.cjs +0 -1
- package/dist/mutator/block-pack/frontend.cjs.map +1 -1
- package/dist/mutator/block-pack/frontend.js +0 -1
- package/dist/mutator/block-pack/frontend.js.map +1 -1
- package/dist/mutator/project.cjs +28 -35
- package/dist/mutator/project.cjs.map +1 -1
- package/dist/mutator/project.d.ts.map +1 -1
- package/dist/mutator/project.js +29 -36
- package/dist/mutator/project.js.map +1 -1
- package/package.json +13 -13
- package/src/middle_layer/middle_layer.ts +7 -2
- package/src/middle_layer/project.ts +12 -7
- package/src/middle_layer/project_overview.ts +3 -3
- package/src/model/index.ts +0 -1
- package/src/model/project_helper.ts +33 -37
- package/src/mutator/project-v3.test.ts +9 -9
- package/src/mutator/project.ts +50 -74
- package/dist/model/block_storage_helper.cjs +0 -210
- package/dist/model/block_storage_helper.cjs.map +0 -1
- package/dist/model/block_storage_helper.d.ts +0 -98
- package/dist/model/block_storage_helper.d.ts.map +0 -1
- package/dist/model/block_storage_helper.js +0 -153
- package/dist/model/block_storage_helper.js.map +0 -1
- package/src/model/block_storage_helper.ts +0 -213
|
@@ -34,7 +34,7 @@ import type {
|
|
|
34
34
|
} from "@milaboratories/pl-model-middle-layer";
|
|
35
35
|
import { activeConfigs } from "./active_cfg";
|
|
36
36
|
import { NavigationStates } from "./navigation_states";
|
|
37
|
-
import { extractConfig } from "@platforma-sdk/model";
|
|
37
|
+
import { extractConfig, BLOCK_STORAGE_FACADE_VERSION } from "@platforma-sdk/model";
|
|
38
38
|
import fs from "node:fs/promises";
|
|
39
39
|
import canonicalize from "canonicalize";
|
|
40
40
|
import type { ProjectOverviewLight } from "./project_overview_light";
|
|
@@ -187,9 +187,11 @@ export class Project {
|
|
|
187
187
|
const blockCfgContainer = await this.env.bpPreparer.getBlockConfigContainer(blockPackSpec);
|
|
188
188
|
const blockCfg = extractConfig(blockCfgContainer); // full content of this var should never be persisted
|
|
189
189
|
|
|
190
|
+
this.env.runtimeCapabilities.throwIfIncompatible(blockCfg.featureFlags);
|
|
191
|
+
|
|
190
192
|
// Build NewBlockSpec based on model API version
|
|
191
193
|
const newBlockSpec =
|
|
192
|
-
blockCfg.modelAPIVersion ===
|
|
194
|
+
blockCfg.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION
|
|
193
195
|
? { storageMode: "fromModel" as const, blockPack: preparedBp }
|
|
194
196
|
: {
|
|
195
197
|
storageMode: "legacy" as const,
|
|
@@ -276,15 +278,18 @@ export class Project {
|
|
|
276
278
|
const blockCfg = extractConfig(
|
|
277
279
|
await this.env.bpPreparer.getBlockConfigContainer(blockPackSpec),
|
|
278
280
|
);
|
|
281
|
+
|
|
282
|
+
this.env.runtimeCapabilities.throwIfIncompatible(blockCfg.featureFlags);
|
|
283
|
+
|
|
279
284
|
// resetState signals to mutator to reset storage
|
|
280
285
|
// For v2+ blocks: mutator gets initial storage directly via getInitialStorageInVM
|
|
281
286
|
// For v1 blocks: we pass the legacy state format
|
|
282
287
|
const resetState = resetArgs
|
|
283
288
|
? {
|
|
284
289
|
state:
|
|
285
|
-
blockCfg.modelAPIVersion ===
|
|
286
|
-
? {}
|
|
287
|
-
: {
|
|
290
|
+
blockCfg.modelAPIVersion === 1
|
|
291
|
+
? { args: blockCfg.initialArgs, uiState: blockCfg.initialUiState }
|
|
292
|
+
: {},
|
|
288
293
|
}
|
|
289
294
|
: undefined;
|
|
290
295
|
await withProjectAuthored(
|
|
@@ -459,7 +464,7 @@ export class Project {
|
|
|
459
464
|
/**
|
|
460
465
|
* Sets navigation state.
|
|
461
466
|
* */
|
|
462
|
-
//
|
|
467
|
+
//
|
|
463
468
|
public async setNavigationState(blockId: string, state: NavigationState): Promise<void> {
|
|
464
469
|
this.navigationStates.setState(blockId, state);
|
|
465
470
|
}
|
|
@@ -545,7 +550,7 @@ export class Project {
|
|
|
545
550
|
this.rid,
|
|
546
551
|
author,
|
|
547
552
|
(prj) => {
|
|
548
|
-
if (config.modelAPIVersion ===
|
|
553
|
+
if (config.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION) {
|
|
549
554
|
// V2+: Reset to initial storage via VM
|
|
550
555
|
prj.resetToInitialStorage(blockId);
|
|
551
556
|
} else {
|
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
} from "@milaboratories/pl-model-middle-layer";
|
|
24
24
|
import { constructBlockContext, constructBlockContextArgsOnly } from "./block_ctx";
|
|
25
25
|
import { ifNotUndef } from "../cfg_render/util";
|
|
26
|
-
import { type BlockSection } from "@platforma-sdk/model";
|
|
26
|
+
import { type BlockSection, BLOCK_STORAGE_FACADE_VERSION } from "@platforma-sdk/model";
|
|
27
27
|
import { extractCodeWithInfo, wrapCallback } from "@platforma-sdk/model";
|
|
28
28
|
import { computableFromCfgOrRF } from "./render";
|
|
29
29
|
import type { NavigationStates } from "./navigation_states";
|
|
@@ -231,7 +231,7 @@ export function projectOverview(
|
|
|
231
231
|
// inputsValid: for modelAPIVersion 2, it's true if currentArgs exists (args derivation succeeded)
|
|
232
232
|
// For older blocks, use the inputsValid callback from config
|
|
233
233
|
inputsValid:
|
|
234
|
-
cfg.modelAPIVersion ===
|
|
234
|
+
cfg.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION
|
|
235
235
|
? info.currentArguments !== undefined
|
|
236
236
|
: cfg.inputsValid
|
|
237
237
|
? (computableFromCfgOrRF(
|
|
@@ -265,7 +265,7 @@ export function projectOverview(
|
|
|
265
265
|
|
|
266
266
|
// Get block storage debug view by calling VM function (only for Model API v2 blocks)
|
|
267
267
|
const storageDebugView = ifNotUndef(bp, ({ cfg }) => {
|
|
268
|
-
if (cfg.modelAPIVersion !==
|
|
268
|
+
if (cfg.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
269
269
|
return undefined;
|
|
270
270
|
}
|
|
271
271
|
const storageNode = prj.traverse({
|
package/src/model/index.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ResultOrError,
|
|
3
3
|
BlockConfig,
|
|
4
|
+
BlockStorage,
|
|
4
5
|
PlRef,
|
|
5
|
-
ConfigRenderLambda,
|
|
6
6
|
StorageDebugView,
|
|
7
7
|
} from "@platforma-sdk/model";
|
|
8
8
|
import type { StringifiedJson } from "@milaboratories/pl-model-common";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
extractCodeWithInfo,
|
|
11
|
+
ensureError,
|
|
12
|
+
BlockStorageFacadeCallbacks,
|
|
13
|
+
BLOCK_STORAGE_FACADE_VERSION,
|
|
14
|
+
} from "@platforma-sdk/model";
|
|
10
15
|
import { LRUCache } from "lru-cache";
|
|
11
16
|
import type { QuickJSWASMModule } from "quickjs-emscripten";
|
|
12
17
|
import { executeSingleLambda } from "../js_render";
|
|
@@ -26,36 +31,11 @@ type EnrichmentTargetsValue = {
|
|
|
26
31
|
* Returned by migrateStorageInVM().
|
|
27
32
|
*
|
|
28
33
|
* - Error result: { error: string } - serious failure (no context, etc.)
|
|
29
|
-
* - Success result: { newStorageJson:
|
|
34
|
+
* - Success result: { newStorageJson: StringifiedJson<BlockStorage>, info: string } - migration succeeded
|
|
30
35
|
*/
|
|
31
36
|
export type MigrationResult =
|
|
32
37
|
| { error: string }
|
|
33
|
-
| { error?: undefined; newStorageJson:
|
|
34
|
-
|
|
35
|
-
// Internal lambda handles for storage operations (registered by SDK's block_storage_vm.ts)
|
|
36
|
-
// All callbacks are prefixed with `__pl_` to indicate internal SDK use
|
|
37
|
-
const STORAGE_APPLY_UPDATE_HANDLE: ConfigRenderLambda = {
|
|
38
|
-
__renderLambda: true,
|
|
39
|
-
handle: "__pl_storage_applyUpdate",
|
|
40
|
-
};
|
|
41
|
-
const STORAGE_DEBUG_VIEW_HANDLE: ConfigRenderLambda = {
|
|
42
|
-
__renderLambda: true,
|
|
43
|
-
handle: "__pl_storage_debugView",
|
|
44
|
-
};
|
|
45
|
-
const STORAGE_MIGRATE_HANDLE: ConfigRenderLambda = {
|
|
46
|
-
__renderLambda: true,
|
|
47
|
-
handle: "__pl_storage_migrate",
|
|
48
|
-
};
|
|
49
|
-
const ARGS_DERIVE_HANDLE: ConfigRenderLambda = { __renderLambda: true, handle: "__pl_args_derive" };
|
|
50
|
-
const PRERUN_ARGS_DERIVE_HANDLE: ConfigRenderLambda = {
|
|
51
|
-
__renderLambda: true,
|
|
52
|
-
handle: "__pl_prerunArgs_derive",
|
|
53
|
-
};
|
|
54
|
-
// Registered by DataModel.registerCallbacks()
|
|
55
|
-
const INITIAL_STORAGE_HANDLE: ConfigRenderLambda = {
|
|
56
|
-
__renderLambda: true,
|
|
57
|
-
handle: "__pl_storage_initial",
|
|
58
|
-
};
|
|
38
|
+
| { error?: undefined; newStorageJson: StringifiedJson<BlockStorage>; info: string };
|
|
59
39
|
|
|
60
40
|
/**
|
|
61
41
|
* Result of args derivation from storage.
|
|
@@ -96,7 +76,7 @@ export class ProjectHelper {
|
|
|
96
76
|
blockConfig: BlockConfig,
|
|
97
77
|
storageJson: string,
|
|
98
78
|
): ResultOrError<unknown> {
|
|
99
|
-
if (blockConfig.modelAPIVersion !==
|
|
79
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
100
80
|
return {
|
|
101
81
|
error: new Error("deriveArgsFromStorage is only supported for model API version 2"),
|
|
102
82
|
};
|
|
@@ -105,7 +85,7 @@ export class ProjectHelper {
|
|
|
105
85
|
try {
|
|
106
86
|
const result = executeSingleLambda(
|
|
107
87
|
this.quickJs,
|
|
108
|
-
|
|
88
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.ArgsDerive],
|
|
109
89
|
extractCodeWithInfo(blockConfig),
|
|
110
90
|
storageJson,
|
|
111
91
|
) as ArgsDeriveResult;
|
|
@@ -128,14 +108,14 @@ export class ProjectHelper {
|
|
|
128
108
|
* @returns The derived prerunArgs, or undefined if derivation fails
|
|
129
109
|
*/
|
|
130
110
|
public derivePrerunArgsFromStorage(blockConfig: BlockConfig, storageJson: string): unknown {
|
|
131
|
-
if (blockConfig.modelAPIVersion !==
|
|
111
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
132
112
|
throw new Error("derivePrerunArgsFromStorage is only supported for model API version 2");
|
|
133
113
|
}
|
|
134
114
|
|
|
135
115
|
try {
|
|
136
116
|
const result = executeSingleLambda(
|
|
137
117
|
this.quickJs,
|
|
138
|
-
|
|
118
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.PrerunArgsDerive],
|
|
139
119
|
extractCodeWithInfo(blockConfig),
|
|
140
120
|
storageJson,
|
|
141
121
|
) as ArgsDeriveResult;
|
|
@@ -190,10 +170,14 @@ export class ProjectHelper {
|
|
|
190
170
|
* @throws Error if storage creation fails
|
|
191
171
|
*/
|
|
192
172
|
public getInitialStorageInVM(blockConfig: BlockConfig): string {
|
|
173
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
174
|
+
throw new Error("getInitialStorageInVM is only supported for model API version 2");
|
|
175
|
+
}
|
|
176
|
+
|
|
193
177
|
try {
|
|
194
178
|
const result = executeSingleLambda(
|
|
195
179
|
this.quickJs,
|
|
196
|
-
|
|
180
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.StorageInitial],
|
|
197
181
|
extractCodeWithInfo(blockConfig),
|
|
198
182
|
) as string;
|
|
199
183
|
return result;
|
|
@@ -221,10 +205,14 @@ export class ProjectHelper {
|
|
|
221
205
|
currentStorageJson: string,
|
|
222
206
|
payload: { operation: string; value: unknown },
|
|
223
207
|
): string {
|
|
208
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
209
|
+
throw new Error("applyStorageUpdateInVM is only supported for model API version 2");
|
|
210
|
+
}
|
|
211
|
+
|
|
224
212
|
try {
|
|
225
213
|
const result = executeSingleLambda(
|
|
226
214
|
this.quickJs,
|
|
227
|
-
|
|
215
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.StorageApplyUpdate],
|
|
228
216
|
extractCodeWithInfo(blockConfig),
|
|
229
217
|
currentStorageJson,
|
|
230
218
|
payload,
|
|
@@ -248,10 +236,14 @@ export class ProjectHelper {
|
|
|
248
236
|
blockConfig: BlockConfig,
|
|
249
237
|
rawStorageJson: string | undefined,
|
|
250
238
|
): StringifiedJson<StorageDebugView> | undefined {
|
|
239
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
240
|
+
throw new Error("getStorageDebugViewInVM is only supported for model API version 2");
|
|
241
|
+
}
|
|
242
|
+
|
|
251
243
|
try {
|
|
252
244
|
const result = executeSingleLambda(
|
|
253
245
|
this.quickJs,
|
|
254
|
-
|
|
246
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.StorageDebugView],
|
|
255
247
|
extractCodeWithInfo(blockConfig),
|
|
256
248
|
rawStorageJson,
|
|
257
249
|
) as StringifiedJson<StorageDebugView>;
|
|
@@ -285,10 +277,14 @@ export class ProjectHelper {
|
|
|
285
277
|
blockConfig: BlockConfig,
|
|
286
278
|
currentStorageJson: string | undefined,
|
|
287
279
|
): MigrationResult {
|
|
280
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
281
|
+
return { error: "migrateStorageInVM is only supported for model API version 2" };
|
|
282
|
+
}
|
|
283
|
+
|
|
288
284
|
try {
|
|
289
285
|
const result = executeSingleLambda(
|
|
290
286
|
this.quickJs,
|
|
291
|
-
|
|
287
|
+
blockConfig.blockLifecycleCallbacks[BlockStorageFacadeCallbacks.StorageMigrate],
|
|
292
288
|
extractCodeWithInfo(blockConfig),
|
|
293
289
|
currentStorageJson,
|
|
294
290
|
) as MigrationResult;
|
|
@@ -50,7 +50,7 @@ test("v3 blocks: basic test with unified state", async () => {
|
|
|
50
50
|
modelAPIVersion: 2,
|
|
51
51
|
blockId: "enter1",
|
|
52
52
|
payload: {
|
|
53
|
-
operation: "update-data",
|
|
53
|
+
operation: "update-block-data",
|
|
54
54
|
value: { numbers: [1, 2, 3] },
|
|
55
55
|
},
|
|
56
56
|
},
|
|
@@ -82,7 +82,7 @@ test("v3 blocks: basic test with unified state", async () => {
|
|
|
82
82
|
modelAPIVersion: 2,
|
|
83
83
|
blockId: "enter2",
|
|
84
84
|
payload: {
|
|
85
|
-
operation: "update-data",
|
|
85
|
+
operation: "update-block-data",
|
|
86
86
|
value: { numbers: [4, 5, 6] },
|
|
87
87
|
},
|
|
88
88
|
},
|
|
@@ -108,7 +108,7 @@ test("v3 blocks: basic test with unified state", async () => {
|
|
|
108
108
|
modelAPIVersion: 2,
|
|
109
109
|
blockId: "sum1",
|
|
110
110
|
payload: {
|
|
111
|
-
operation: "update-data",
|
|
111
|
+
operation: "update-block-data",
|
|
112
112
|
value: { sources: [outputRef("enter1", "numbers"), outputRef("enter2", "numbers")] },
|
|
113
113
|
},
|
|
114
114
|
},
|
|
@@ -182,7 +182,7 @@ test("v3 blocks: prerunArgs skip test", async () => {
|
|
|
182
182
|
modelAPIVersion: 2,
|
|
183
183
|
blockId: "enter1",
|
|
184
184
|
payload: {
|
|
185
|
-
operation: "update-data",
|
|
185
|
+
operation: "update-block-data",
|
|
186
186
|
value: { numbers: [3, 1, 2] },
|
|
187
187
|
},
|
|
188
188
|
},
|
|
@@ -215,7 +215,7 @@ test("v3 blocks: prerunArgs skip test", async () => {
|
|
|
215
215
|
modelAPIVersion: 2,
|
|
216
216
|
blockId: "enter1",
|
|
217
217
|
payload: {
|
|
218
|
-
operation: "update-data",
|
|
218
|
+
operation: "update-block-data",
|
|
219
219
|
value: { numbers: [5, 1, 2] }, // Changed odd numbers only
|
|
220
220
|
},
|
|
221
221
|
},
|
|
@@ -245,7 +245,7 @@ test("v3 blocks: prerunArgs skip test", async () => {
|
|
|
245
245
|
modelAPIVersion: 2,
|
|
246
246
|
blockId: "enter1",
|
|
247
247
|
payload: {
|
|
248
|
-
operation: "update-data",
|
|
248
|
+
operation: "update-block-data",
|
|
249
249
|
value: { numbers: [5, 1, 4] }, // Changed even number from 2 to 4
|
|
250
250
|
},
|
|
251
251
|
},
|
|
@@ -309,7 +309,7 @@ test("v3 blocks: migrateBlockPack preserves state and re-derives args and prerun
|
|
|
309
309
|
{
|
|
310
310
|
modelAPIVersion: 2,
|
|
311
311
|
blockId: "enter1",
|
|
312
|
-
payload: { operation: "update-data", value: { numbers: [4, 2, 6] } },
|
|
312
|
+
payload: { operation: "update-block-data", value: { numbers: [4, 2, 6] } },
|
|
313
313
|
},
|
|
314
314
|
]);
|
|
315
315
|
mut.save();
|
|
@@ -381,7 +381,7 @@ test("v3 blocks: migrateBlockPack with storage migration re-derives args and pre
|
|
|
381
381
|
{
|
|
382
382
|
modelAPIVersion: 2,
|
|
383
383
|
blockId: "enter1",
|
|
384
|
-
payload: { operation: "update-data", value: { numbers: [1] } },
|
|
384
|
+
payload: { operation: "update-block-data", value: { numbers: [1] } },
|
|
385
385
|
},
|
|
386
386
|
]);
|
|
387
387
|
mut.save();
|
|
@@ -461,7 +461,7 @@ test("v3 blocks: migrateBlockPack assigns author marker", async () => {
|
|
|
461
461
|
{
|
|
462
462
|
modelAPIVersion: 2,
|
|
463
463
|
blockId: "enter1",
|
|
464
|
-
payload: { operation: "update-data", value: { numbers: [1, 2, 3] } },
|
|
464
|
+
payload: { operation: "update-block-data", value: { numbers: [1, 2, 3] } },
|
|
465
465
|
},
|
|
466
466
|
]);
|
|
467
467
|
mut.save();
|
package/src/mutator/project.ts
CHANGED
|
@@ -65,7 +65,12 @@ import {
|
|
|
65
65
|
cachedDecode,
|
|
66
66
|
} from "@milaboratories/ts-helpers";
|
|
67
67
|
import type { ProjectHelper } from "../model/project_helper";
|
|
68
|
-
import {
|
|
68
|
+
import {
|
|
69
|
+
extractConfig,
|
|
70
|
+
UiError,
|
|
71
|
+
BLOCK_STORAGE_FACADE_VERSION,
|
|
72
|
+
type BlockConfig,
|
|
73
|
+
} from "@platforma-sdk/model";
|
|
69
74
|
import { getDebugFlags } from "../debug";
|
|
70
75
|
import type { BlockPackInfo } from "../model/block_pack";
|
|
71
76
|
|
|
@@ -622,7 +627,7 @@ export class ProjectMutator {
|
|
|
622
627
|
const info = this.getBlockInfo(blockId);
|
|
623
628
|
const blockConfig = info.config;
|
|
624
629
|
|
|
625
|
-
if (blockConfig.modelAPIVersion !==
|
|
630
|
+
if (blockConfig.modelAPIVersion !== BLOCK_STORAGE_FACADE_VERSION) {
|
|
626
631
|
throw new Error("resetToInitialStorage is only supported for model API version 2");
|
|
627
632
|
}
|
|
628
633
|
|
|
@@ -675,7 +680,7 @@ export class ProjectMutator {
|
|
|
675
680
|
let args: unknown;
|
|
676
681
|
let prerunArgs: unknown;
|
|
677
682
|
|
|
678
|
-
if (req.modelAPIVersion ===
|
|
683
|
+
if (req.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION) {
|
|
679
684
|
const currentStorageJson = info.blockStorageJson;
|
|
680
685
|
if (currentStorageJson === undefined) {
|
|
681
686
|
throw new Error(`Block ${req.blockId} has no blockStorage - this should not happen`);
|
|
@@ -1179,106 +1184,77 @@ export class ProjectMutator {
|
|
|
1179
1184
|
const info = this.getBlockInfo(blockId);
|
|
1180
1185
|
const newConfig = extractConfig(spec.config);
|
|
1181
1186
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1187
|
+
const persistBlockPack = () => {
|
|
1188
|
+
this.setBlockField(
|
|
1189
|
+
blockId,
|
|
1190
|
+
"blockPack",
|
|
1191
|
+
Pl.wrapInHolder(this.tx, createBlockPack(this.tx, spec)),
|
|
1192
|
+
"NotReady",
|
|
1193
|
+
);
|
|
1194
|
+
};
|
|
1195
|
+
|
|
1196
|
+
const applyStorageAndDeriveArgs = (storageJson: string) => {
|
|
1197
|
+
persistBlockPack();
|
|
1198
|
+
this.setBlockStorageRaw(blockId, storageJson);
|
|
1199
|
+
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(newConfig, storageJson);
|
|
1200
|
+
if (!deriveArgsResult.error) {
|
|
1201
|
+
this.setBlockFieldObj(
|
|
1202
|
+
blockId,
|
|
1203
|
+
"currentArgs",
|
|
1204
|
+
this.createJsonFieldValue(deriveArgsResult.value),
|
|
1205
|
+
);
|
|
1206
|
+
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(newConfig, storageJson);
|
|
1207
|
+
if (prerunArgs !== undefined) {
|
|
1208
|
+
this.setBlockFieldObj(
|
|
1209
|
+
blockId,
|
|
1210
|
+
"currentPrerunArgs",
|
|
1211
|
+
this.createJsonFieldValue(prerunArgs),
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1188
1216
|
|
|
1189
1217
|
if (newClearState !== undefined) {
|
|
1190
1218
|
// State is being reset - no migration needed
|
|
1191
|
-
const supportsStorageFromVM = newConfig.modelAPIVersion ===
|
|
1219
|
+
const supportsStorageFromVM = newConfig.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION;
|
|
1192
1220
|
|
|
1193
1221
|
if (supportsStorageFromVM) {
|
|
1194
1222
|
// V2+: Get initial storage directly from VM and derive args from it
|
|
1195
1223
|
const initialStorageJson = this.projectHelper.getInitialStorageInVM(newConfig);
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
// Derive args from storage - only set currentArgs if derivation succeeds
|
|
1199
|
-
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(
|
|
1200
|
-
newConfig,
|
|
1201
|
-
initialStorageJson,
|
|
1202
|
-
);
|
|
1203
|
-
if (!deriveArgsResult.error) {
|
|
1204
|
-
this.setBlockFieldObj(
|
|
1205
|
-
blockId,
|
|
1206
|
-
"currentArgs",
|
|
1207
|
-
this.createJsonFieldValue(deriveArgsResult.value),
|
|
1208
|
-
);
|
|
1209
|
-
// Derive prerunArgs from storage
|
|
1210
|
-
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
1211
|
-
newConfig,
|
|
1212
|
-
initialStorageJson,
|
|
1213
|
-
);
|
|
1214
|
-
if (prerunArgs !== undefined) {
|
|
1215
|
-
this.setBlockFieldObj(
|
|
1216
|
-
blockId,
|
|
1217
|
-
"currentPrerunArgs",
|
|
1218
|
-
this.createJsonFieldValue(prerunArgs),
|
|
1219
|
-
);
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1224
|
+
applyStorageAndDeriveArgs(initialStorageJson);
|
|
1222
1225
|
this.blocksWithChangedInputs.add(blockId);
|
|
1223
1226
|
this.updateLastModified();
|
|
1224
1227
|
} else {
|
|
1225
1228
|
// V1: Use setStates with legacy state format
|
|
1229
|
+
persistBlockPack();
|
|
1226
1230
|
this.setStates([{ modelAPIVersion: 1, blockId, state: newClearState.state }]);
|
|
1227
1231
|
}
|
|
1228
1232
|
} else {
|
|
1229
1233
|
// State is being preserved - run migrations if needed via VM
|
|
1230
1234
|
// Only Model API v2 blocks support migrations
|
|
1231
|
-
const supportsStateMigrations = newConfig.modelAPIVersion ===
|
|
1235
|
+
const supportsStateMigrations = newConfig.modelAPIVersion === BLOCK_STORAGE_FACADE_VERSION;
|
|
1232
1236
|
|
|
1233
1237
|
if (supportsStateMigrations) {
|
|
1234
1238
|
const currentStorageJson = info.blockStorageJson;
|
|
1235
1239
|
|
|
1240
|
+
// Attempt migration BEFORE persisting block pack — on failure,
|
|
1241
|
+
// block stays on old version (no inconsistent new-code/old-storage state)
|
|
1236
1242
|
const migrationResult = this.projectHelper.migrateStorageInVM(
|
|
1237
1243
|
newConfig,
|
|
1238
1244
|
currentStorageJson,
|
|
1239
1245
|
);
|
|
1240
1246
|
|
|
1241
1247
|
if (migrationResult.error !== undefined) {
|
|
1242
|
-
|
|
1243
|
-
`[migrateBlockPack] Block ${blockId} migration
|
|
1248
|
+
throw new Error(
|
|
1249
|
+
`[migrateBlockPack] Block ${blockId} migration failed: ${migrationResult.error}`,
|
|
1244
1250
|
);
|
|
1245
|
-
} else {
|
|
1246
|
-
console.log(`[migrateBlockPack] Block ${blockId}: ${migrationResult.info}`);
|
|
1247
|
-
if (migrationResult.warn) {
|
|
1248
|
-
console.warn(
|
|
1249
|
-
`[migrateBlockPack] Block ${blockId} migration warning: ${migrationResult.warn}`,
|
|
1250
|
-
);
|
|
1251
|
-
}
|
|
1252
|
-
this.setBlockStorageRaw(blockId, migrationResult.newStorageJson);
|
|
1253
|
-
|
|
1254
|
-
// Re-derive currentArgs from migrated storage (new block code + migrated data)
|
|
1255
|
-
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(
|
|
1256
|
-
newConfig,
|
|
1257
|
-
migrationResult.newStorageJson,
|
|
1258
|
-
);
|
|
1259
|
-
if (!deriveArgsResult.error) {
|
|
1260
|
-
this.setBlockFieldObj(
|
|
1261
|
-
blockId,
|
|
1262
|
-
"currentArgs",
|
|
1263
|
-
this.createJsonFieldValue(deriveArgsResult.value),
|
|
1264
|
-
);
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
// Derive prerunArgs from the migrated storage so staging can re-render
|
|
1268
|
-
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
1269
|
-
newConfig,
|
|
1270
|
-
migrationResult.newStorageJson,
|
|
1271
|
-
);
|
|
1272
|
-
if (prerunArgs !== undefined) {
|
|
1273
|
-
this.setBlockFieldObj(
|
|
1274
|
-
blockId,
|
|
1275
|
-
"currentPrerunArgs",
|
|
1276
|
-
this.createJsonFieldValue(prerunArgs),
|
|
1277
|
-
);
|
|
1278
|
-
}
|
|
1279
1251
|
}
|
|
1252
|
+
|
|
1253
|
+
console.log(`[migrateBlockPack] Block ${blockId}: ${migrationResult.info}`);
|
|
1254
|
+
applyStorageAndDeriveArgs(migrationResult.newStorageJson);
|
|
1280
1255
|
} else {
|
|
1281
|
-
// Legacy blocks (modelAPIVersion 1): prerunArgs = currentArgs
|
|
1256
|
+
// Legacy blocks (modelAPIVersion 1): persist block pack, set prerunArgs = currentArgs
|
|
1257
|
+
persistBlockPack();
|
|
1282
1258
|
if (info.fields.currentArgs !== undefined) {
|
|
1283
1259
|
this.setBlockFieldObj(blockId, "currentPrerunArgs", info.fields.currentArgs);
|
|
1284
1260
|
}
|