@milaboratories/pl-middle-layer 1.54.7 → 1.55.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-middle-layer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.55.1",
|
|
4
4
|
"description": "Pl Middle Layer",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -30,24 +30,24 @@
|
|
|
30
30
|
"utility-types": "^3.11.0",
|
|
31
31
|
"yaml": "^2.8.0",
|
|
32
32
|
"zod": "~3.23.8",
|
|
33
|
-
"@milaboratories/computable": "2.9.2",
|
|
34
|
-
"@milaboratories/pf-spec-driver": "1.2.4",
|
|
35
33
|
"@milaboratories/helpers": "1.14.1",
|
|
36
34
|
"@milaboratories/pf-driver": "1.3.3",
|
|
37
35
|
"@milaboratories/pl-client": "3.0.0",
|
|
36
|
+
"@milaboratories/pf-spec-driver": "1.2.4",
|
|
38
37
|
"@milaboratories/pl-deployments": "2.16.5",
|
|
39
|
-
"@milaboratories/
|
|
40
|
-
"@milaboratories/pl-http": "1.2.4",
|
|
38
|
+
"@milaboratories/computable": "2.9.2",
|
|
41
39
|
"@milaboratories/pl-drivers": "1.12.8",
|
|
40
|
+
"@milaboratories/pl-http": "1.2.4",
|
|
42
41
|
"@milaboratories/pl-model-backend": "1.2.6",
|
|
42
|
+
"@milaboratories/pl-errors": "1.2.6",
|
|
43
43
|
"@milaboratories/pl-model-common": "1.31.1",
|
|
44
44
|
"@milaboratories/pl-model-middle-layer": "1.16.3",
|
|
45
45
|
"@milaboratories/resolve-helper": "1.1.3",
|
|
46
|
+
"@milaboratories/ts-helpers": "1.8.1",
|
|
46
47
|
"@milaboratories/pl-tree": "1.9.7",
|
|
47
48
|
"@platforma-sdk/block-tools": "2.7.5",
|
|
48
|
-
"@platforma-sdk/workflow-tengo": "5.
|
|
49
|
-
"@platforma-sdk/model": "1.63.1"
|
|
50
|
-
"@milaboratories/ts-helpers": "1.8.1"
|
|
49
|
+
"@platforma-sdk/workflow-tengo": "5.12.0",
|
|
50
|
+
"@platforma-sdk/model": "1.63.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "~24.5.2",
|
|
@@ -433,6 +433,77 @@ test("v3 blocks: migrateBlockPack with storage migration re-derives args and pre
|
|
|
433
433
|
});
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
+
test("v3 blocks: resetToInitialStorage derives prerunArgs even when args() throws", async () => {
|
|
437
|
+
const quickJs = await getQuickJS();
|
|
438
|
+
|
|
439
|
+
await TestHelpers.withTempRoot(async (pl) => {
|
|
440
|
+
const prj = await pl.withWriteTx("CreatingProject", async (tx) => {
|
|
441
|
+
const prjRef = await createProject(tx);
|
|
442
|
+
tx.createField(field(tx.clientRoot, "prj"), "Dynamic", prjRef);
|
|
443
|
+
await tx.commit();
|
|
444
|
+
return await toGlobalResourceId(prjRef);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// Add block with valid data so args and prerunArgs are both set
|
|
448
|
+
await pl.withWriteTx("AddBlock", async (tx) => {
|
|
449
|
+
const mut = await ProjectMutator.load(new ProjectHelper(quickJs), tx, prj);
|
|
450
|
+
mut.addBlock(
|
|
451
|
+
{ id: "enter1", label: "Enter Numbers V3", renderingMode: "Heavy" },
|
|
452
|
+
{
|
|
453
|
+
storageMode: "fromModel",
|
|
454
|
+
blockPack: await TestBPPreparer.prepare(BPSpecEnterV3),
|
|
455
|
+
},
|
|
456
|
+
);
|
|
457
|
+
mut.setStates([
|
|
458
|
+
{
|
|
459
|
+
modelAPIVersion: 2,
|
|
460
|
+
blockId: "enter1",
|
|
461
|
+
payload: { operation: "update-block-data", value: { numbers: [4, 2, 6] } },
|
|
462
|
+
},
|
|
463
|
+
]);
|
|
464
|
+
mut.save();
|
|
465
|
+
await tx.commit();
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// Verify both args and prerunArgs are set
|
|
469
|
+
await poll(pl, async (tx) => {
|
|
470
|
+
const prjR = await tx.get(prj);
|
|
471
|
+
const currentArgs = await prjR.get(projectFieldName("enter1", "currentArgs"));
|
|
472
|
+
const argsData = JSON.parse(Buffer.from(currentArgs.data.data!).toString());
|
|
473
|
+
expect(argsData).toStrictEqual({ numbers: [2, 4, 6] });
|
|
474
|
+
|
|
475
|
+
const currentPrerunArgs = await prjR.get(projectFieldName("enter1", "currentPrerunArgs"));
|
|
476
|
+
const prerunData = JSON.parse(Buffer.from(currentPrerunArgs.data.data!).toString());
|
|
477
|
+
expect(prerunData).toStrictEqual({ evenNumbers: [2, 4, 6] });
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
// Reset to initial storage — init() returns { numbers: [] }
|
|
481
|
+
// args() will throw "Numbers are required!" but prerunArgs() should still succeed
|
|
482
|
+
await pl.withWriteTx("ResetToInitial", async (tx) => {
|
|
483
|
+
const mut = await ProjectMutator.load(new ProjectHelper(quickJs), tx, prj);
|
|
484
|
+
mut.resetToInitialStorage("enter1");
|
|
485
|
+
mut.save();
|
|
486
|
+
await tx.commit();
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Verify: currentArgs is cleared (args threw), but currentPrerunArgs is still derived
|
|
490
|
+
await poll(pl, async (tx) => {
|
|
491
|
+
const prjR = await tx.get(prj);
|
|
492
|
+
|
|
493
|
+
// currentArgs should be gone since args() throws for empty numbers
|
|
494
|
+
const currentArgsField = prjR.data.fields.find(
|
|
495
|
+
(f) => f.name === projectFieldName("enter1", "currentArgs"),
|
|
496
|
+
);
|
|
497
|
+
expect(currentArgsField).toBeUndefined();
|
|
498
|
+
|
|
499
|
+
// currentPrerunArgs should still be set with empty even numbers
|
|
500
|
+
const currentPrerunArgs = await prjR.get(projectFieldName("enter1", "currentPrerunArgs"));
|
|
501
|
+
const prerunData = JSON.parse(Buffer.from(currentPrerunArgs.data.data!).toString());
|
|
502
|
+
expect(prerunData).toStrictEqual({ evenNumbers: [] });
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
436
507
|
test("v3 blocks: migrateBlockPack assigns author marker", async () => {
|
|
437
508
|
const quickJs = await getQuickJS();
|
|
438
509
|
|
package/src/mutator/project.ts
CHANGED
|
@@ -751,6 +751,17 @@ export class ProjectMutator {
|
|
|
751
751
|
const initialStorageJson = this.projectHelper.getInitialStorageInVM(blockConfig);
|
|
752
752
|
this.setBlockStorageRaw(blockId, initialStorageJson);
|
|
753
753
|
|
|
754
|
+
// Derive prerunArgs first — always derived independently of args validation
|
|
755
|
+
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
756
|
+
blockConfig,
|
|
757
|
+
initialStorageJson,
|
|
758
|
+
);
|
|
759
|
+
if (prerunArgs !== undefined) {
|
|
760
|
+
this.setBlockFieldObj(blockId, "currentPrerunArgs", this.createJsonFieldValue(prerunArgs));
|
|
761
|
+
} else {
|
|
762
|
+
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
763
|
+
}
|
|
764
|
+
|
|
754
765
|
// Derive args from storage - set or clear currentArgs based on derivation result
|
|
755
766
|
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(
|
|
756
767
|
blockConfig,
|
|
@@ -762,24 +773,8 @@ export class ProjectMutator {
|
|
|
762
773
|
"currentArgs",
|
|
763
774
|
this.createJsonFieldValue(deriveArgsResult.value),
|
|
764
775
|
);
|
|
765
|
-
// Derive prerunArgs from storage
|
|
766
|
-
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
767
|
-
blockConfig,
|
|
768
|
-
initialStorageJson,
|
|
769
|
-
);
|
|
770
|
-
if (prerunArgs !== undefined) {
|
|
771
|
-
this.setBlockFieldObj(blockId, "currentPrerunArgs", this.createJsonFieldValue(prerunArgs));
|
|
772
|
-
} else {
|
|
773
|
-
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
774
|
-
}
|
|
775
776
|
} else {
|
|
776
|
-
if (info.fields.currentPrerunArgs !== undefined) {
|
|
777
|
-
this.projectHelper.logger.warn(
|
|
778
|
-
`[staging] ${blockId}: currentPrerunArgs cleared (args derivation failed)`,
|
|
779
|
-
);
|
|
780
|
-
}
|
|
781
777
|
this.deleteBlockFields(blockId, "currentArgs");
|
|
782
|
-
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
783
778
|
}
|
|
784
779
|
}
|
|
785
780
|
|
|
@@ -823,22 +818,18 @@ export class ProjectMutator {
|
|
|
823
818
|
this.createGzJsonFieldValueFromContent(updatedStorageJson),
|
|
824
819
|
);
|
|
825
820
|
|
|
826
|
-
// Derive
|
|
821
|
+
// Derive prerunArgs first — always derived independently of args validation
|
|
822
|
+
prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
823
|
+
blockConfig,
|
|
824
|
+
updatedStorageJson,
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
// Derive args from storage (VM extracts data internally)
|
|
827
828
|
const derivedArgsResult = this.projectHelper.deriveArgsFromStorage(
|
|
828
829
|
blockConfig,
|
|
829
830
|
updatedStorageJson,
|
|
830
831
|
);
|
|
831
|
-
|
|
832
|
-
args = undefined;
|
|
833
|
-
prerunArgs = undefined;
|
|
834
|
-
} else {
|
|
835
|
-
args = derivedArgsResult.value;
|
|
836
|
-
// Derive prerunArgs from storage, or fall back to args
|
|
837
|
-
prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(
|
|
838
|
-
blockConfig,
|
|
839
|
-
updatedStorageJson,
|
|
840
|
-
);
|
|
841
|
-
}
|
|
832
|
+
args = derivedArgsResult.error ? undefined : derivedArgsResult.value;
|
|
842
833
|
} else {
|
|
843
834
|
this.setBlockFieldObj(req.blockId, "blockStorage", this.createGzJsonFieldValue(req.state));
|
|
844
835
|
if (req.state !== null && typeof req.state === "object" && "args" in req.state) {
|
|
@@ -1118,18 +1109,15 @@ export class ProjectMutator {
|
|
|
1118
1109
|
// Model API v2+: get initial storage and derive args from it
|
|
1119
1110
|
storageToWrite = this.projectHelper.getInitialStorageInVM(blockConfig);
|
|
1120
1111
|
|
|
1121
|
-
// Derive
|
|
1112
|
+
// Derive prerunArgs first — always derived independently of args validation
|
|
1113
|
+
prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(blockConfig, storageToWrite);
|
|
1114
|
+
|
|
1115
|
+
// Derive args from storage (VM extracts data internally)
|
|
1122
1116
|
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(
|
|
1123
1117
|
blockConfig,
|
|
1124
1118
|
storageToWrite,
|
|
1125
1119
|
);
|
|
1126
|
-
|
|
1127
|
-
args = undefined;
|
|
1128
|
-
prerunArgs = undefined;
|
|
1129
|
-
} else {
|
|
1130
|
-
args = deriveArgsResult.value;
|
|
1131
|
-
prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(blockConfig, storageToWrite);
|
|
1132
|
-
}
|
|
1120
|
+
args = deriveArgsResult.error ? undefined : deriveArgsResult.value;
|
|
1133
1121
|
} else if (spec.storageMode === "legacy") {
|
|
1134
1122
|
// Model API v1: use legacyState from spec
|
|
1135
1123
|
const parsedState = JSON.parse(spec.legacyState);
|
|
@@ -1406,6 +1394,15 @@ export class ProjectMutator {
|
|
|
1406
1394
|
const applyStorageAndDeriveArgs = (storageJson: string) => {
|
|
1407
1395
|
persistBlockPack();
|
|
1408
1396
|
this.setBlockStorageRaw(blockId, storageJson);
|
|
1397
|
+
|
|
1398
|
+
// Derive prerunArgs first — always derived independently of args validation
|
|
1399
|
+
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(newConfig, storageJson);
|
|
1400
|
+
if (prerunArgs !== undefined) {
|
|
1401
|
+
this.setBlockFieldObj(blockId, "currentPrerunArgs", this.createJsonFieldValue(prerunArgs));
|
|
1402
|
+
} else {
|
|
1403
|
+
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1409
1406
|
const deriveArgsResult = this.projectHelper.deriveArgsFromStorage(newConfig, storageJson);
|
|
1410
1407
|
if (!deriveArgsResult.error) {
|
|
1411
1408
|
this.setBlockFieldObj(
|
|
@@ -1413,19 +1410,8 @@ export class ProjectMutator {
|
|
|
1413
1410
|
"currentArgs",
|
|
1414
1411
|
this.createJsonFieldValue(deriveArgsResult.value),
|
|
1415
1412
|
);
|
|
1416
|
-
const prerunArgs = this.projectHelper.derivePrerunArgsFromStorage(newConfig, storageJson);
|
|
1417
|
-
if (prerunArgs !== undefined) {
|
|
1418
|
-
this.setBlockFieldObj(
|
|
1419
|
-
blockId,
|
|
1420
|
-
"currentPrerunArgs",
|
|
1421
|
-
this.createJsonFieldValue(prerunArgs),
|
|
1422
|
-
);
|
|
1423
|
-
} else {
|
|
1424
|
-
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
1425
|
-
}
|
|
1426
1413
|
} else {
|
|
1427
1414
|
this.deleteBlockFields(blockId, "currentArgs");
|
|
1428
|
-
this.deleteBlockFields(blockId, "currentPrerunArgs");
|
|
1429
1415
|
}
|
|
1430
1416
|
};
|
|
1431
1417
|
|