poi-plugin-remodel-assistant 1.2.5-beta.1 → 1.2.5-beta.2
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 +1 -1
- package/views/new-interface/app/decision-snapshot-jobs.js +16 -29
- package/views/new-interface/app/decision-snapshot-service.js +4 -1
- package/views/new-interface/app/decision-snapshot-worker.js +27 -1
- package/views/new-interface/app/new-interface-area.js +67 -48
- package/views/new-interface/app/startup-decision-snapshot-storage.js +84 -0
- package/views/new-interface/incremental/plan-decision-index.js +120 -43
- package/views/new-interface/shared/components/detail-panel.js +2 -1
- package/views/shared/plugin-resource-paths.js +9 -1
- package/views/shared/plugin-state-commands.js +0 -72
package/package.json
CHANGED
|
@@ -5,8 +5,6 @@ exports.executeDecisionSnapshotJob = exports.resetDecisionSnapshotJobState = exp
|
|
|
5
5
|
|
|
6
6
|
var _pluginMeta = require("../../shared/plugin-meta");
|
|
7
7
|
|
|
8
|
-
var _kcraTrace__ = require("../../shared/__kcra-trace__");
|
|
9
|
-
|
|
10
8
|
var _planDecisionIndex = require("../incremental/plan-decision-index");
|
|
11
9
|
|
|
12
10
|
var _decisionSnapshotDomain = require("../decisions/domain/decision-snapshot-domain");
|
|
@@ -76,20 +74,7 @@ const publishDecisionSnapshot = ({
|
|
|
76
74
|
assignmentFindings: effective.assignmentFindings || [],
|
|
77
75
|
assignmentDiagnostics: [...(userAllocation && userAllocation.assignmentDiagnostics || []), ...(effective.assignmentDiagnostics || [])]
|
|
78
76
|
};
|
|
79
|
-
|
|
80
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('snapshot.publish.summary', {
|
|
81
|
-
itemCount: snapshot.items.length,
|
|
82
|
-
workbenchCount: snapshot.workbenchItems.length,
|
|
83
|
-
retainedBindingCount: snapshot.retainedBindingCurrentIds.length,
|
|
84
|
-
bindingCount: Object.keys(snapshot.assignmentPersistenceBindings || {}).length,
|
|
85
|
-
bindingTransitions: snapshot.assignmentBindingTransitions,
|
|
86
|
-
assignmentFindings: snapshot.assignmentFindings,
|
|
87
|
-
assignmentDiagnosticCount: snapshot.assignmentDiagnostics.length,
|
|
88
|
-
alignmentFindings
|
|
89
|
-
});
|
|
90
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('snapshot.publish.full', snapshot, {
|
|
91
|
-
full: true
|
|
92
|
-
});
|
|
77
|
+
logPublishedDecisionSnapshotAlignment(snapshot, effective.currentInventoryBindings || {});
|
|
93
78
|
return snapshot;
|
|
94
79
|
};
|
|
95
80
|
|
|
@@ -292,18 +277,20 @@ const buildFullDecisionSnapshotPayload = input => {
|
|
|
292
277
|
useitems: job.useitems || {},
|
|
293
278
|
resourceBudget: job.resourceBudget || {}
|
|
294
279
|
});
|
|
295
|
-
};
|
|
280
|
+
}; // Transient projection caches only. They are optimization state, never Plan/Binding authority.
|
|
281
|
+
// Clearing them must be semantically equivalent to a Full rebuild from current Reality.
|
|
282
|
+
|
|
296
283
|
|
|
297
284
|
exports.buildFullDecisionSnapshotPayload = buildFullDecisionSnapshotPayload;
|
|
298
|
-
let
|
|
299
|
-
let
|
|
285
|
+
let baseIncrementalProjectionCacheState = null;
|
|
286
|
+
let effectiveIncrementalProjectionCacheState = null;
|
|
300
287
|
|
|
301
288
|
const buildDecisionSnapshotPayload = (input, profile = null) => {
|
|
302
289
|
const job = input || {};
|
|
303
290
|
|
|
304
291
|
if (_pluginMeta.FORCE_FULL_DECISION_REBUILD) {
|
|
305
|
-
|
|
306
|
-
|
|
292
|
+
baseIncrementalProjectionCacheState = null;
|
|
293
|
+
effectiveIncrementalProjectionCacheState = null;
|
|
307
294
|
return buildFullDecisionSnapshotPayload(job, profile);
|
|
308
295
|
}
|
|
309
296
|
|
|
@@ -316,15 +303,15 @@ const buildDecisionSnapshotPayload = (input, profile = null) => {
|
|
|
316
303
|
|
|
317
304
|
const baseResult = (0, _planDecisionIndex.buildIncrementalDecisionSnapshot)(_extends({}, job, {
|
|
318
305
|
currentInventoryBindings: baseBindings,
|
|
319
|
-
previous:
|
|
306
|
+
previous: baseIncrementalProjectionCacheState,
|
|
320
307
|
allocationScope: 'user',
|
|
321
308
|
profile: prefixedProfile(profile, 'base')
|
|
322
309
|
}));
|
|
323
310
|
measureProfile(profile, 'base-core-total', phaseStartedAt, {
|
|
324
|
-
hadPrevious: Boolean(
|
|
311
|
+
hadPrevious: Boolean(baseIncrementalProjectionCacheState),
|
|
325
312
|
planGroupCount: Object.keys(job.plans || {}).length
|
|
326
313
|
});
|
|
327
|
-
|
|
314
|
+
baseIncrementalProjectionCacheState = baseResult.state;
|
|
328
315
|
const base = baseResult.value;
|
|
329
316
|
observeAllocationStage(job, 'UserAllocation', _extends({
|
|
330
317
|
mode: 'incremental'
|
|
@@ -367,8 +354,8 @@ const buildDecisionSnapshotPayload = (input, profile = null) => {
|
|
|
367
354
|
// incremental diff remains the correctness gate and recomputes every changed
|
|
368
355
|
// Plan/Binding target.
|
|
369
356
|
|
|
370
|
-
const effectivePrevious =
|
|
371
|
-
const seededEffectiveFromBase = !
|
|
357
|
+
const effectivePrevious = effectiveIncrementalProjectionCacheState || baseResult.state;
|
|
358
|
+
const seededEffectiveFromBase = !effectiveIncrementalProjectionCacheState && Boolean(baseResult.state);
|
|
372
359
|
const effectiveResult = (0, _planDecisionIndex.buildIncrementalDecisionSnapshot)(_extends({}, job, {
|
|
373
360
|
plans: composition.plans,
|
|
374
361
|
currentInventoryBindings: effectiveBindings,
|
|
@@ -381,7 +368,7 @@ const buildDecisionSnapshotPayload = (input, profile = null) => {
|
|
|
381
368
|
seededFromBase: seededEffectiveFromBase,
|
|
382
369
|
planGroupCount: Object.keys(composition.plans || {}).length
|
|
383
370
|
});
|
|
384
|
-
|
|
371
|
+
effectiveIncrementalProjectionCacheState = effectiveResult.state;
|
|
385
372
|
const effective = effectiveResult.value;
|
|
386
373
|
observeAllocationStage(job, 'ConsumableAllocation', _extends({
|
|
387
374
|
mode: 'incremental'
|
|
@@ -404,8 +391,8 @@ const buildDecisionSnapshotPayload = (input, profile = null) => {
|
|
|
404
391
|
exports.buildDecisionSnapshotPayload = buildDecisionSnapshotPayload;
|
|
405
392
|
|
|
406
393
|
const resetDecisionSnapshotJobState = () => {
|
|
407
|
-
|
|
408
|
-
|
|
394
|
+
baseIncrementalProjectionCacheState = null;
|
|
395
|
+
effectiveIncrementalProjectionCacheState = null;
|
|
409
396
|
};
|
|
410
397
|
|
|
411
398
|
exports.resetDecisionSnapshotJobState = resetDecisionSnapshotJobState;
|
|
@@ -9,6 +9,8 @@ var _startupPerformance = require("../../shared/startup-performance");
|
|
|
9
9
|
|
|
10
10
|
var _equipmentBlacklistDomain = require("../equipment/domain/equipment-blacklist-domain");
|
|
11
11
|
|
|
12
|
+
var _pluginResourcePaths = require("../../shared/plugin-resource-paths");
|
|
13
|
+
|
|
12
14
|
var _decisionSnapshotJobs = require("./decision-snapshot-jobs");
|
|
13
15
|
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -173,7 +175,8 @@ const requestDecisionSnapshot = inputs => {
|
|
|
173
175
|
planRouteSelections: inputs.planRouteSelections,
|
|
174
176
|
routeAcquisitionIndex: inputs.routeAcquisitionIndex || {},
|
|
175
177
|
currentInventoryBindings: inputs.currentInventoryBindings || {},
|
|
176
|
-
lowPriorityEquipmentIds: (0, _equipmentBlacklistDomain.getLowPriorityEquipmentIds)(inputs.equipmentBlacklist)
|
|
178
|
+
lowPriorityEquipmentIds: (0, _equipmentBlacklistDomain.getLowPriorityEquipmentIds)(inputs.equipmentBlacklist),
|
|
179
|
+
startupSnapshotPath: (0, _pluginResourcePaths.getStartupSnapshotPath)()
|
|
177
180
|
};
|
|
178
181
|
|
|
179
182
|
if (workerRuntime() === 'inline') {
|
|
@@ -7,10 +7,33 @@ const {
|
|
|
7
7
|
executeDecisionSnapshotJob
|
|
8
8
|
} = require('./decision-snapshot-jobs');
|
|
9
9
|
|
|
10
|
+
const {
|
|
11
|
+
writePersistentStartupDecisionSnapshot
|
|
12
|
+
} = require('./startup-decision-snapshot-storage');
|
|
13
|
+
|
|
14
|
+
let startupSnapshotPersistTimer = null;
|
|
15
|
+
let pendingStartupSnapshotPersistence = null;
|
|
16
|
+
|
|
10
17
|
const send = message => {
|
|
11
18
|
if (parentPort) parentPort.postMessage(message);else if (typeof process.send === 'function') process.send(message);
|
|
12
19
|
};
|
|
13
20
|
|
|
21
|
+
const scheduleStartupSnapshotPersistence = (filePath, snapshot) => {
|
|
22
|
+
if (!filePath || !snapshot) return;
|
|
23
|
+
pendingStartupSnapshotPersistence = {
|
|
24
|
+
filePath,
|
|
25
|
+
snapshot
|
|
26
|
+
};
|
|
27
|
+
if (startupSnapshotPersistTimer) clearTimeout(startupSnapshotPersistTimer);
|
|
28
|
+
startupSnapshotPersistTimer = setTimeout(() => {
|
|
29
|
+
startupSnapshotPersistTimer = null;
|
|
30
|
+
const pending = pendingStartupSnapshotPersistence;
|
|
31
|
+
pendingStartupSnapshotPersistence = null;
|
|
32
|
+
if (!pending) return;
|
|
33
|
+
writePersistentStartupDecisionSnapshot(pending.snapshot, pending.filePath);
|
|
34
|
+
}, 1000);
|
|
35
|
+
};
|
|
36
|
+
|
|
14
37
|
const respond = (requestId, job) => {
|
|
15
38
|
try {
|
|
16
39
|
const result = executeDecisionSnapshotJob(job);
|
|
@@ -18,7 +41,10 @@ const respond = (requestId, job) => {
|
|
|
18
41
|
requestId,
|
|
19
42
|
ok: true,
|
|
20
43
|
result
|
|
21
|
-
});
|
|
44
|
+
}); // Persistence is deliberately scheduled only after the calculated snapshot
|
|
45
|
+
// has been returned to Poi. It therefore cannot delay renderer publication.
|
|
46
|
+
|
|
47
|
+
scheduleStartupSnapshotPersistence(job && job.startupSnapshotPath, result);
|
|
22
48
|
} catch (error) {
|
|
23
49
|
send({
|
|
24
50
|
requestId,
|
|
@@ -17,8 +17,6 @@ var _core = require("@blueprintjs/core");
|
|
|
17
17
|
|
|
18
18
|
var _pluginMeta = require("../../shared/plugin-meta");
|
|
19
19
|
|
|
20
|
-
var _kcraTrace__ = require("../../shared/__kcra-trace__");
|
|
21
|
-
|
|
22
20
|
var _startupPerformance = require("../../shared/startup-performance");
|
|
23
21
|
|
|
24
22
|
var _dataPackageDomain = require("../../shared/domain/data-package-domain");
|
|
@@ -29,6 +27,8 @@ var _decisionFoundationService = require("./decision-foundation-service");
|
|
|
29
27
|
|
|
30
28
|
var _decisionSnapshotService = require("./decision-snapshot-service");
|
|
31
29
|
|
|
30
|
+
var _startupDecisionSnapshotStorage = require("./startup-decision-snapshot-storage");
|
|
31
|
+
|
|
32
32
|
var _decisionSnapshotRequestGate = require("./decision-snapshot-request-gate");
|
|
33
33
|
|
|
34
34
|
var _search = require("../../shared/search");
|
|
@@ -205,8 +205,9 @@ class NewInterfaceArea extends _react.Component {
|
|
|
205
205
|
this.plansOverrideBase = null;
|
|
206
206
|
this.decisionSnapshotTaskId = 0;
|
|
207
207
|
this.decisionSnapshotRequestGate = (0, _decisionSnapshotRequestGate.createDecisionSnapshotRequestGate)();
|
|
208
|
-
this.
|
|
209
|
-
this.
|
|
208
|
+
this.decisionSnapshotInvalidationQueue = [];
|
|
209
|
+
this.decisionSnapshotInvalidationDrainScheduled = false;
|
|
210
|
+
this.decisionRealityReadyCallbacks = [];
|
|
210
211
|
this.exclusionRecommendationTaskId = 0;
|
|
211
212
|
const workbenchFilters = (0, _uiPreferences.getWorkbenchFilters)(_pluginStateStorage.pluginConfig);
|
|
212
213
|
this.state = {
|
|
@@ -245,16 +246,29 @@ class NewInterfaceArea extends _react.Component {
|
|
|
245
246
|
this.planEquipmentAssignments = persistedPlanEquipmentAssignments();
|
|
246
247
|
const snapshotInputs = decisionSnapshotInputsFor(props, this.state, this.plansOverride, this.plansOverrideBase, this.planEquipmentAssignments);
|
|
247
248
|
const processCacheStartedAt = (0, _startupPerformance.startupPerformanceNow)();
|
|
248
|
-
|
|
249
|
+
const legacyRecoveryPending = (0, _legacyAssignmentRecovery.hasUnfinishedLegacyAssignmentRecovery)((0, _pluginStateStorage.getPluginStateSnapshot)());
|
|
250
|
+
const processSnapshot = legacyRecoveryPending ? null : (0, _decisionSnapshotCache.readProcessDecisionSnapshotCache)(snapshotInputs);
|
|
251
|
+
const startupSnapshot = !legacyRecoveryPending && !processSnapshot ? (0, _startupDecisionSnapshotStorage.readPersistentStartupDecisionSnapshot)() : null;
|
|
252
|
+
this.currentDecisionSnapshot = processSnapshot || startupSnapshot;
|
|
249
253
|
(0, _startupPerformance.measureStartupPerformance)('decision.process-cache-lookup', processCacheStartedAt, {
|
|
250
|
-
cacheHit: Boolean(
|
|
254
|
+
cacheHit: Boolean(processSnapshot),
|
|
255
|
+
persistentStartupHit: Boolean(startupSnapshot)
|
|
251
256
|
});
|
|
252
257
|
|
|
253
|
-
if (!
|
|
258
|
+
if (!processSnapshot) {
|
|
254
259
|
(0, _startupPerformance.markStartupPerformance)('decision.process-cache-miss-detail', (0, _decisionSnapshotCache.inspectDecisionSnapshotCache)(snapshotInputs));
|
|
255
260
|
}
|
|
256
261
|
|
|
257
|
-
|
|
262
|
+
if (startupSnapshot) {
|
|
263
|
+
(0, _startupPerformance.markStartupPerformance)('decision.persistent-startup-snapshot-published', {
|
|
264
|
+
itemCount: Array.isArray(startupSnapshot.items) ? startupSnapshot.items.length : 0
|
|
265
|
+
});
|
|
266
|
+
} // A persistent startup snapshot is presentation-only stale state. Never give
|
|
267
|
+
// it current input identity: componentDidMount must still run the current
|
|
268
|
+
// Reality Full path instead of treating the stale snapshot as an exact cache hit.
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
this.currentDecisionSnapshotInputs = processSnapshot ? snapshotInputs : null;
|
|
258
272
|
this.decisionSnapshotFeedbackGuard = (0, _decisionSnapshotRequestGate.createDecisionSnapshotFeedbackGuard)();
|
|
259
273
|
this.latestStableStateValidation = null;
|
|
260
274
|
if (this.currentDecisionSnapshot) this.state.decisionSnapshotLoading = false;
|
|
@@ -307,8 +321,11 @@ class NewInterfaceArea extends _react.Component {
|
|
|
307
321
|
this.mounted = false;
|
|
308
322
|
this.decisionSnapshotTaskId += 1;
|
|
309
323
|
this.decisionSnapshotRequestGate.reset();
|
|
310
|
-
this.
|
|
311
|
-
|
|
324
|
+
this.decisionSnapshotInvalidationQueue.splice(0).forEach(item => {
|
|
325
|
+
if (item && typeof item.resolve === 'function') item.resolve(null);
|
|
326
|
+
});
|
|
327
|
+
this.decisionSnapshotInvalidationDrainScheduled = false;
|
|
328
|
+
this.decisionRealityReadyCallbacks = [];
|
|
312
329
|
this.exclusionRecommendationTaskId += 1;
|
|
313
330
|
this.stopObservingWorkspaceSize();
|
|
314
331
|
this.setEquipmentDividerRef(null);
|
|
@@ -743,9 +760,6 @@ var _initialiseProps = function () {
|
|
|
743
760
|
snapshot
|
|
744
761
|
});
|
|
745
762
|
this.latestStableStateValidation = stableValidation;
|
|
746
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('validator.stable-state', stableValidation, {
|
|
747
|
-
full: true
|
|
748
|
-
});
|
|
749
763
|
return {
|
|
750
764
|
ok: true,
|
|
751
765
|
stableValidation
|
|
@@ -774,7 +788,7 @@ var _initialiseProps = function () {
|
|
|
774
788
|
|
|
775
789
|
if (!snapshotInputs.equipmentRealityReady) {
|
|
776
790
|
(0, _startupPerformance.markStartupPerformance)('decision.waiting-for-reality');
|
|
777
|
-
if (afterReady) this.
|
|
791
|
+
if (afterReady) this.decisionRealityReadyCallbacks.push(afterReady);
|
|
778
792
|
return Promise.resolve(null);
|
|
779
793
|
}
|
|
780
794
|
|
|
@@ -782,15 +796,6 @@ var _initialiseProps = function () {
|
|
|
782
796
|
planGroupCount: Object.keys(snapshotInputs.plans || {}).length,
|
|
783
797
|
bindingCount: Object.keys(snapshotInputs.currentInventoryBindings || {}).length
|
|
784
798
|
});
|
|
785
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('snapshot.request.inputs', {
|
|
786
|
-
plans: snapshotInputs.plans,
|
|
787
|
-
planRouteSelections: snapshotInputs.planRouteSelections,
|
|
788
|
-
currentInventoryBindings: snapshotInputs.currentInventoryBindings,
|
|
789
|
-
equipmentRealityReady: snapshotInputs.equipmentRealityReady,
|
|
790
|
-
actualEquipInventory: snapshotInputs.actualEquipInventory
|
|
791
|
-
}, {
|
|
792
|
-
full: true
|
|
793
|
-
});
|
|
794
799
|
const recoveryStartedAt = (0, _startupPerformance.startupPerformanceNow)();
|
|
795
800
|
const recovery = (0, _pluginStateCommands.runPendingLegacyAssignmentRecovery)({
|
|
796
801
|
equipInventory: snapshotInputs.actualEquipInventory
|
|
@@ -816,8 +821,8 @@ var _initialiseProps = function () {
|
|
|
816
821
|
});
|
|
817
822
|
}
|
|
818
823
|
|
|
819
|
-
const deferredAfterReady = afterReady || this.
|
|
820
|
-
const callbacks = this.
|
|
824
|
+
const deferredAfterReady = afterReady || this.decisionRealityReadyCallbacks.length > 0 ? snapshot => {
|
|
825
|
+
const callbacks = this.decisionRealityReadyCallbacks.splice(0);
|
|
821
826
|
callbacks.forEach(callback => callback(snapshot));
|
|
822
827
|
if (afterReady) afterReady(snapshot);
|
|
823
828
|
} : null;
|
|
@@ -838,32 +843,49 @@ var _initialiseProps = function () {
|
|
|
838
843
|
const activeRequest = this.decisionSnapshotRequestGate.readActive();
|
|
839
844
|
|
|
840
845
|
if (activeRequest) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
846
|
+
// Snapshot invalidations are a FIFO work queue, not a coalescing flag. Each
|
|
847
|
+
// invalidation is consumed after the current isolated Snapshot finishes. A
|
|
848
|
+
// queued item intentionally reads the latest Reality when it starts; this
|
|
849
|
+
// runtime requires eventual consistency, not historical event replay.
|
|
850
|
+
const queued = new Promise(resolve => {
|
|
851
|
+
this.decisionSnapshotInvalidationQueue.push({
|
|
852
|
+
afterReady,
|
|
853
|
+
resolve
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
if (!this.decisionSnapshotInvalidationDrainScheduled) {
|
|
858
|
+
this.decisionSnapshotInvalidationDrainScheduled = true;
|
|
859
|
+
|
|
860
|
+
const drain = () => {
|
|
861
|
+
if (!this.mounted) {
|
|
862
|
+
this.decisionSnapshotInvalidationDrainScheduled = false;
|
|
863
|
+
this.decisionSnapshotInvalidationQueue.splice(0).forEach(item => item.resolve(null));
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const item = this.decisionSnapshotInvalidationQueue.shift();
|
|
868
|
+
|
|
869
|
+
if (!item) {
|
|
870
|
+
this.decisionSnapshotInvalidationDrainScheduled = false;
|
|
871
|
+
return null;
|
|
855
872
|
}
|
|
856
873
|
|
|
857
874
|
return this.scheduleDecisionSnapshotRefresh({
|
|
858
|
-
afterReady:
|
|
875
|
+
afterReady: item.afterReady
|
|
876
|
+
}).then(snapshot => {
|
|
877
|
+
item.resolve(snapshot);
|
|
878
|
+
return drain();
|
|
879
|
+
}, () => {
|
|
880
|
+
item.resolve(null);
|
|
881
|
+
return drain();
|
|
859
882
|
});
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
});
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
activeRequest.then(drain, drain);
|
|
864
886
|
}
|
|
865
887
|
|
|
866
|
-
return
|
|
888
|
+
return queued;
|
|
867
889
|
}
|
|
868
890
|
|
|
869
891
|
const taskId = this.decisionSnapshotTaskId + 1;
|
|
@@ -1030,9 +1052,6 @@ var _initialiseProps = function () {
|
|
|
1030
1052
|
snapshot: this.currentDecisionSnapshot
|
|
1031
1053
|
});
|
|
1032
1054
|
this.latestStableStateValidation = result;
|
|
1033
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('validator.manual-stable-state', result, {
|
|
1034
|
-
full: true
|
|
1035
|
-
});
|
|
1036
1055
|
return result;
|
|
1037
1056
|
}
|
|
1038
1057
|
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.STARTUP_DECISION_SNAPSHOT_SCHEMA = exports.STARTUP_DECISION_SNAPSHOT_FORMAT = exports.clearPersistentStartupDecisionSnapshot = exports.writePersistentStartupDecisionSnapshot = exports.readPersistentStartupDecisionSnapshot = void 0;
|
|
5
|
+
|
|
6
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
7
|
+
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
|
|
10
|
+
var _pluginMeta = require("../../shared/plugin-meta");
|
|
11
|
+
|
|
12
|
+
var _pluginResourcePaths = require("../../shared/plugin-resource-paths");
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
const v8 = require('v8');
|
|
17
|
+
|
|
18
|
+
const STARTUP_DECISION_SNAPSHOT_FORMAT = `${_pluginMeta.PLUGIN_ID}.startup-decision-snapshot`;
|
|
19
|
+
exports.STARTUP_DECISION_SNAPSHOT_FORMAT = STARTUP_DECISION_SNAPSHOT_FORMAT;
|
|
20
|
+
const STARTUP_DECISION_SNAPSHOT_SCHEMA = 2;
|
|
21
|
+
exports.STARTUP_DECISION_SNAPSHOT_SCHEMA = STARTUP_DECISION_SNAPSHOT_SCHEMA;
|
|
22
|
+
|
|
23
|
+
const isPlainObject = value => value != null && typeof value === 'object' && !Array.isArray(value);
|
|
24
|
+
|
|
25
|
+
const snapshotEnvelope = snapshot => ({
|
|
26
|
+
format: STARTUP_DECISION_SNAPSHOT_FORMAT,
|
|
27
|
+
schemaVersion: STARTUP_DECISION_SNAPSHOT_SCHEMA,
|
|
28
|
+
snapshot
|
|
29
|
+
}); // Startup Snapshot is disposable derived presentation state. The renderer reads
|
|
30
|
+
// it synchronously so the previous UI can paint before the current-Reality Full.
|
|
31
|
+
// V8 structured serialization is used because the Decision Snapshot is already
|
|
32
|
+
// transferred through advanced IPC and is not guaranteed to be JSON-serializable.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const readPersistentStartupDecisionSnapshot = () => {
|
|
36
|
+
const filePath = (0, _pluginResourcePaths.getStartupSnapshotPath)();
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
if (!_fs.default.existsSync(filePath)) return null;
|
|
40
|
+
const value = v8.deserialize(_fs.default.readFileSync(filePath));
|
|
41
|
+
|
|
42
|
+
if (!isPlainObject(value) || value.format !== STARTUP_DECISION_SNAPSHOT_FORMAT || Number(value.schemaVersion) !== STARTUP_DECISION_SNAPSHOT_SCHEMA || !isPlainObject(value.snapshot)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return value.snapshot;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}; // This function is intended for the Decision worker, never the Poi renderer.
|
|
51
|
+
// Cache durability is deliberately best-effort: a partial/corrupt write simply
|
|
52
|
+
// becomes a cache miss at the next startup and the normal Full path rebuilds it.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
exports.readPersistentStartupDecisionSnapshot = readPersistentStartupDecisionSnapshot;
|
|
56
|
+
|
|
57
|
+
const writePersistentStartupDecisionSnapshot = (snapshot, filePath = null) => {
|
|
58
|
+
if (!isPlainObject(snapshot)) return false;
|
|
59
|
+
const targetPath = filePath || (0, _pluginResourcePaths.getStartupSnapshotPath)();
|
|
60
|
+
const directory = filePath ? _path.default.dirname(targetPath) : (0, _pluginResourcePaths.getStartupSnapshotDirectory)();
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
_fs.default.mkdirSync(directory, {
|
|
64
|
+
recursive: true
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
_fs.default.writeFileSync(targetPath, v8.serialize(snapshotEnvelope(snapshot)));
|
|
68
|
+
|
|
69
|
+
return true;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
exports.writePersistentStartupDecisionSnapshot = writePersistentStartupDecisionSnapshot;
|
|
76
|
+
|
|
77
|
+
const clearPersistentStartupDecisionSnapshot = () => {
|
|
78
|
+
try {
|
|
79
|
+
_fs.default.unlinkSync((0, _pluginResourcePaths.getStartupSnapshotPath)());
|
|
80
|
+
} catch (error) {// Best-effort cache cleanup: missing/unremovable cache is not fatal.
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
exports.clearPersistentStartupDecisionSnapshot = clearPersistentStartupDecisionSnapshot;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
-
exports.buildIncrementalDecisionSnapshot = void 0;
|
|
4
|
+
exports.buildIncrementalDecisionSnapshot = exports.plansAcceptingEquipmentIds = exports.buildPlanAcceptIndex = void 0;
|
|
5
5
|
|
|
6
6
|
var _decisionChainDomain = require("../decisions/domain/decision-chain-domain");
|
|
7
7
|
|
|
@@ -81,23 +81,64 @@ const projectDecisionItemDay = (item, today, ownedShipMasterIds, edgeCostResolve
|
|
|
81
81
|
routeChoice,
|
|
82
82
|
planCost
|
|
83
83
|
});
|
|
84
|
-
};
|
|
84
|
+
}; // Accept Index is an inverted structural dependency index: equipmentId -> Plan target ids
|
|
85
|
+
// whose compiled Route Metadata contains that equipment state. It is deliberately
|
|
86
|
+
// conservative and has no Allocation authority. False positives only cause a cheap
|
|
87
|
+
// Plan recomputation; false negatives would be a correctness defect.
|
|
88
|
+
//
|
|
89
|
+
// Build this index from durable Plan intent + structural Route Metadata, not from
|
|
90
|
+
// the previous pending-planning projection. Completed Plans intentionally have no
|
|
91
|
+
// pending occurrences, but an Equipment Reality change may make their completion
|
|
92
|
+
// predicate false again; they must therefore remain discoverable here.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
const buildPlanAcceptIndex = ({
|
|
96
|
+
plans = {},
|
|
97
|
+
preparedGraph = null,
|
|
98
|
+
routeAcquisitionIndex = {}
|
|
99
|
+
} = {}) => {
|
|
100
|
+
const acceptedByEquipmentId = {};
|
|
101
|
+
|
|
102
|
+
const add = (equipmentId, planId) => {
|
|
103
|
+
const equipment = Number(equipmentId);
|
|
104
|
+
const plan = Number(planId);
|
|
105
|
+
if (!Number.isInteger(equipment) || equipment <= 0 || !Number.isInteger(plan) || plan <= 0) return;
|
|
106
|
+
if (!acceptedByEquipmentId[equipment]) acceptedByEquipmentId[equipment] = new Set();
|
|
107
|
+
acceptedByEquipmentId[equipment].add(plan);
|
|
108
|
+
};
|
|
85
109
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
Object.keys(plans || {}).forEach(rawPlanId => {
|
|
111
|
+
const planId = Number(rawPlanId);
|
|
112
|
+
if (!Number.isInteger(planId) || planId <= 0) return;
|
|
113
|
+
(0, _planFactsDomain.configuredPlanGoals)(plans[rawPlanId] || {}).forEach(goal => {
|
|
114
|
+
const targetLevel = Number(goal && goal.star);
|
|
115
|
+
if (!Number.isInteger(targetLevel) || targetLevel < 0) return;
|
|
116
|
+
const metadata = (0, _currentStartCandidateDomain.buildPlanRouteMetadata)({
|
|
117
|
+
preparedGraph,
|
|
118
|
+
target: {
|
|
119
|
+
id: planId,
|
|
120
|
+
level: targetLevel
|
|
121
|
+
},
|
|
122
|
+
routeAcquisitionIndex
|
|
123
|
+
});
|
|
124
|
+
Object.keys(metadata && metadata.stateIndex || {}).forEach(key => {
|
|
125
|
+
const state = metadata.stateIndex[key];
|
|
126
|
+
add(state && state.equipmentId, planId);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
98
129
|
});
|
|
130
|
+
return Object.keys(acceptedByEquipmentId).reduce((result, equipmentId) => {
|
|
131
|
+
result[equipmentId] = Array.from(acceptedByEquipmentId[equipmentId]).sort((a, b) => a - b);
|
|
132
|
+
return result;
|
|
133
|
+
}, {});
|
|
99
134
|
};
|
|
100
135
|
|
|
136
|
+
exports.buildPlanAcceptIndex = buildPlanAcceptIndex;
|
|
137
|
+
|
|
138
|
+
const plansAcceptingEquipmentIds = (acceptIndex = {}, equipmentIds = []) => numericIds((equipmentIds || []).reduce((result, equipmentId) => result.concat(acceptIndex[Number(equipmentId)] || []), []));
|
|
139
|
+
|
|
140
|
+
exports.plansAcceptingEquipmentIds = plansAcceptingEquipmentIds;
|
|
141
|
+
|
|
101
142
|
const changedRouteSelectionTargets = (previousSelections = {}, nextSelections = {}) => {
|
|
102
143
|
const previous = previousSelections || {};
|
|
103
144
|
const next = nextSelections || {};
|
|
@@ -231,10 +272,14 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
231
272
|
affectedPlanCount: 0,
|
|
232
273
|
recomputedPlanCount: 0,
|
|
233
274
|
affectedPlanIds: [],
|
|
275
|
+
routePlanningWorkPlanIds: [],
|
|
234
276
|
recomputedPlanIds: [],
|
|
277
|
+
recomputedRoutePlanningPlanIds: [],
|
|
235
278
|
recomputedDecisionItemCount: 0,
|
|
236
279
|
recomputedDecisionItemIds: [],
|
|
280
|
+
decisionProjectionDirtyItemIds: [],
|
|
237
281
|
recomputedTodayEntryPlanCount: 0,
|
|
282
|
+
todayProjectionDirtyPlanIds: [],
|
|
238
283
|
dateChanged: false,
|
|
239
284
|
durationMs: Date.now() - startedAt
|
|
240
285
|
}
|
|
@@ -261,9 +306,11 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
261
306
|
phaseStartedAt = profileNow();
|
|
262
307
|
const edgeCostResolver = (0, _edgeCostIndex.createEdgeCostResolver)(foundation.edgeCostIndex || {});
|
|
263
308
|
const decisionItemById = previous ? _extends({}, previous.decisionItemById || {}) : {};
|
|
264
|
-
const evolutionTargetIds = evolutionTargets(foundation.effectiveData || []);
|
|
265
|
-
|
|
266
|
-
|
|
309
|
+
const evolutionTargetIds = evolutionTargets(foundation.effectiveData || []); // Projection dirty-set: these ids rebuild Decision presentation/facts only.
|
|
310
|
+
// They are not concrete Binding work and carry no Allocation authority.
|
|
311
|
+
|
|
312
|
+
const decisionProjectionDirtyItemIds = previous ? numericIds(changedPlanIds.concat(changedInventoryItemIds).concat(changedDecisionSelectionItemIds).concat(changedInventoryBindingTargets).concat(foundationAffectedIds).concat(changedLowPriorityItemIds).concat(ownedShipsChanged ? rowIds : [])) : rowIds;
|
|
313
|
+
decisionProjectionDirtyItemIds.forEach(id => {
|
|
267
314
|
if (!rowsById[id]) return;
|
|
268
315
|
decisionItemById[id] = (0, _decisionDomain.buildDecisionItem)(rowsById[id], {
|
|
269
316
|
plans,
|
|
@@ -285,12 +332,12 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
285
332
|
if (!rowsById[id]) delete decisionItemById[id];
|
|
286
333
|
});
|
|
287
334
|
measureProfile(profile, 'decision-items', phaseStartedAt, {
|
|
288
|
-
recomputedDecisionItemCount:
|
|
335
|
+
recomputedDecisionItemCount: decisionProjectionDirtyItemIds.length
|
|
289
336
|
});
|
|
290
337
|
phaseStartedAt = profileNow();
|
|
291
338
|
const dayItemById = previous ? _extends({}, previous.dayItemById || {}) : {};
|
|
292
|
-
const
|
|
293
|
-
|
|
339
|
+
const dayProjectionDirtyItemIds = !previous || dateChanged || ownedShipsChanged ? rowIds : decisionProjectionDirtyItemIds;
|
|
340
|
+
dayProjectionDirtyItemIds.forEach(id => {
|
|
294
341
|
if (!decisionItemById[id]) return;
|
|
295
342
|
dayItemById[id] = projectDecisionItemDay(decisionItemById[id], initialDay, ownedShipMasterIds, edgeCostResolver);
|
|
296
343
|
});
|
|
@@ -299,25 +346,47 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
299
346
|
});
|
|
300
347
|
const dayItems = rowIds.map(id => dayItemById[id]).filter(Boolean);
|
|
301
348
|
measureProfile(profile, 'day-projection', phaseStartedAt, {
|
|
302
|
-
affectedItemCount:
|
|
349
|
+
affectedItemCount: dayProjectionDirtyItemIds.length,
|
|
303
350
|
dayItemCount: dayItems.length
|
|
304
351
|
});
|
|
305
352
|
phaseStartedAt = profileNow();
|
|
306
353
|
const routePlanningById = previous ? _extends({}, previous.routePlanningById || {}) : {};
|
|
307
354
|
const planEntryById = previous ? _extends({}, previous.planEntryById || {}) : {};
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
355
|
+
const previousAcceptIndex = previous ? previous.planAcceptIndex || buildPlanAcceptIndex({
|
|
356
|
+
plans,
|
|
357
|
+
preparedGraph: foundation.improvementGraph || null,
|
|
358
|
+
routeAcquisitionIndex
|
|
359
|
+
}) : {};
|
|
360
|
+
const currentAcceptIndex = buildPlanAcceptIndex({
|
|
361
|
+
plans,
|
|
362
|
+
preparedGraph: foundation.improvementGraph || null,
|
|
363
|
+
routeAcquisitionIndex
|
|
364
|
+
});
|
|
365
|
+
const inventoryRoutePlanningCandidateIds = previous ? plansAcceptingEquipmentIds(previousAcceptIndex, changedInventoryItemIds) : []; // Acquisition facts participate in compiled Route Metadata. Use both the old and
|
|
366
|
+
// current Accept Index so additions and removals are symmetric: a Plan affected
|
|
367
|
+
// only before or only after the acquisition change is still rediscovered.
|
|
368
|
+
|
|
369
|
+
const acquisitionRoutePlanningCandidateIds = previous ? numericIds(plansAcceptingEquipmentIds(previousAcceptIndex, changedAcquisitionItemIds).concat(plansAcceptingEquipmentIds(currentAcceptIndex, changedAcquisitionItemIds))) : []; // Route selection and Binding changes already carry target Plan ids. Foundation
|
|
370
|
+
// `affectedItemIds` is structurally closed by the Foundation engine (including
|
|
371
|
+
// topology-family propagation), so expanding families again here would be a
|
|
372
|
+
// second dependency authority.
|
|
373
|
+
|
|
374
|
+
const directRoutePlanningSeedIds = numericIds(changedPlanIds.concat(changedSelectionTargets).concat(changedInventoryBindingTargets).concat(foundationAffectedIds)); // Route Planning work-set: legal-route analysis is read-only and Plan-local.
|
|
375
|
+
// This set must not be confused with the concrete Assignment Coordinator,
|
|
376
|
+
// which still performs one ordered frozen Allocation round below.
|
|
377
|
+
|
|
378
|
+
const routePlanningWorkPlanIds = previous ? numericIds(directRoutePlanningSeedIds.concat(inventoryRoutePlanningCandidateIds).concat(acquisitionRoutePlanningCandidateIds)) : numericIds(Object.keys(plans));
|
|
379
|
+
const recomputedRoutePlanningPlanIds = [];
|
|
380
|
+
const activeRoutePlanningWorkPlanIds = routePlanningWorkPlanIds.filter(id => Object.prototype.hasOwnProperty.call(plans, id) || Object.prototype.hasOwnProperty.call(plans, String(id)));
|
|
381
|
+
const routePlanningWorkPlans = activeRoutePlanningWorkPlanIds.reduce((result, id) => {
|
|
313
382
|
result[id] = plans[id] || plans[String(id)] || {};
|
|
314
383
|
return result;
|
|
315
384
|
}, {});
|
|
316
385
|
|
|
317
|
-
if (
|
|
386
|
+
if (activeRoutePlanningWorkPlanIds.length > 0) {
|
|
318
387
|
const refreshed = (0, _currentStartCandidateDomain.buildCurrentStartPlanningStates)({
|
|
319
388
|
data: foundation.effectiveData || [],
|
|
320
|
-
plans:
|
|
389
|
+
plans: routePlanningWorkPlans,
|
|
321
390
|
equipLevels,
|
|
322
391
|
equipInventory,
|
|
323
392
|
routeAcquisitionIndex,
|
|
@@ -329,23 +398,23 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
329
398
|
});
|
|
330
399
|
refreshed.forEach(planning => {
|
|
331
400
|
routePlanningById[Number(planning.id)] = planning;
|
|
332
|
-
|
|
401
|
+
recomputedRoutePlanningPlanIds.push(Number(planning.id));
|
|
333
402
|
});
|
|
334
403
|
}
|
|
335
404
|
|
|
336
|
-
|
|
405
|
+
routePlanningWorkPlanIds.forEach(id => {
|
|
337
406
|
if (!Object.prototype.hasOwnProperty.call(plans, id) && !Object.prototype.hasOwnProperty.call(plans, String(id))) {
|
|
338
407
|
delete routePlanningById[id];
|
|
339
408
|
delete planEntryById[id];
|
|
340
409
|
}
|
|
341
410
|
});
|
|
342
411
|
measureProfile(profile, 'route-planning', phaseStartedAt, {
|
|
343
|
-
affectedPlanCount:
|
|
344
|
-
recomputedPlanCount:
|
|
412
|
+
affectedPlanCount: routePlanningWorkPlanIds.length,
|
|
413
|
+
recomputedPlanCount: recomputedRoutePlanningPlanIds.length
|
|
345
414
|
});
|
|
346
415
|
phaseStartedAt = profileNow();
|
|
347
|
-
const
|
|
348
|
-
|
|
416
|
+
const todayProjectionDirtyPlanIds = !previous || dateChanged || ownedShipsChanged ? numericIds(Object.keys(plans)) : numericIds(routePlanningWorkPlanIds.concat(changedDecisionSelectionItemIds).concat(changedLowPriorityItemIds));
|
|
417
|
+
todayProjectionDirtyPlanIds.forEach(id => {
|
|
349
418
|
const item = dayItemById[id];
|
|
350
419
|
const planning = routePlanningById[id] || defaultRoutePlanning(item || {
|
|
351
420
|
id,
|
|
@@ -366,7 +435,7 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
366
435
|
});
|
|
367
436
|
const projectedWorkbenchItems = (0, _decisionDomain.sortDecisionItems)(rowIds.reduce((result, id) => result.concat(planEntryById[id] || []), []));
|
|
368
437
|
measureProfile(profile, 'today-entry-projection', phaseStartedAt, {
|
|
369
|
-
affectedPlanCount:
|
|
438
|
+
affectedPlanCount: todayProjectionDirtyPlanIds.length,
|
|
370
439
|
workbenchCount: projectedWorkbenchItems.length
|
|
371
440
|
});
|
|
372
441
|
phaseStartedAt = profileNow();
|
|
@@ -377,7 +446,10 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
377
446
|
const allocationRetainedBindingCurrentIds = (0, _currentStartAssignmentDomain.finalRetainedBindingCurrentIds)({
|
|
378
447
|
plans,
|
|
379
448
|
routePlannings: numericIds(Object.keys(routePlanningById)).map(id => routePlanningById[id])
|
|
380
|
-
});
|
|
449
|
+
}); // Concrete Binding authority. The Coordinator itself is the synchronous
|
|
450
|
+
// authority-ordered consumer; incremental dirty-sets above only avoid rebuilding
|
|
451
|
+
// read-only Plan/Projection inputs and never decide inventory ownership.
|
|
452
|
+
|
|
381
453
|
const ownership = (0, _currentStartAssignmentDomain.reconcileCurrentStartAssignments)({
|
|
382
454
|
entries: projectedWorkbenchItems,
|
|
383
455
|
equipInventory,
|
|
@@ -463,13 +535,17 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
463
535
|
changedPlanIds,
|
|
464
536
|
changedAcquisitionItemCount: changedAcquisitionItemIds.length,
|
|
465
537
|
changedAcquisitionItemIds,
|
|
466
|
-
affectedPlanCount:
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
538
|
+
affectedPlanCount: routePlanningWorkPlanIds.length,
|
|
539
|
+
affectedPlanIds: routePlanningWorkPlanIds,
|
|
540
|
+
recomputedPlanCount: recomputedRoutePlanningPlanIds.length,
|
|
541
|
+
routePlanningWorkPlanIds,
|
|
542
|
+
recomputedPlanIds: recomputedRoutePlanningPlanIds,
|
|
543
|
+
recomputedRoutePlanningPlanIds,
|
|
544
|
+
recomputedDecisionItemCount: decisionProjectionDirtyItemIds.length,
|
|
545
|
+
recomputedDecisionItemIds: decisionProjectionDirtyItemIds,
|
|
546
|
+
decisionProjectionDirtyItemIds,
|
|
547
|
+
recomputedTodayEntryPlanCount: todayProjectionDirtyPlanIds.length,
|
|
548
|
+
todayProjectionDirtyPlanIds,
|
|
473
549
|
dateChanged,
|
|
474
550
|
durationMs: Date.now() - startedAt
|
|
475
551
|
}
|
|
@@ -485,6 +561,7 @@ const buildIncrementalDecisionSnapshot = ({
|
|
|
485
561
|
acquisitionSignatures: currentAcquisitionSignatures,
|
|
486
562
|
routeAcquisitionIndexRef: routeAcquisitionIndex,
|
|
487
563
|
routePlanningById,
|
|
564
|
+
planAcceptIndex: currentAcceptIndex,
|
|
488
565
|
planEntryById,
|
|
489
566
|
planRouteSelections,
|
|
490
567
|
decisionSelections,
|
|
@@ -383,7 +383,8 @@ class DetailPanel extends _react.Component {
|
|
|
383
383
|
const showUpgradeRoute = mode === 'equipment' && item && Number(item.id) === Number(upgradeRouteItemId);
|
|
384
384
|
const executionLevel = hasResolvedExecutionItem ? currentExecutionLevel(displayItem) : null;
|
|
385
385
|
const selectablePlanEntries = isPlanWorkbenchItem && Array.isArray(item.planEntries) ? item.planEntries : [];
|
|
386
|
-
const
|
|
386
|
+
const allRelatedPlans = isPlanWorkbenchItem ? buildRelatedPlanReferences(item) : [];
|
|
387
|
+
const relatedPlans = selectablePlanEntries.length === 0 ? allRelatedPlans : allRelatedPlans.filter(reference => reference.kind === 'consumable');
|
|
387
388
|
return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("div", {
|
|
388
389
|
className: "decision-detail-dock is-open"
|
|
389
390
|
}, _react.default.createElement("aside", {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
-
exports.getPluginStatePaths = exports.getPluginBackupDirectory = exports.getPluginStateDirectory = exports.getPluginDataDirectory = exports.resolvePoiAppDataPath = void 0;
|
|
4
|
+
exports.getPluginStatePaths = exports.getStartupSnapshotPath = exports.getStartupSnapshotDirectory = exports.getPluginBackupDirectory = exports.getPluginStateDirectory = exports.getPluginDataDirectory = exports.resolvePoiAppDataPath = void 0;
|
|
5
5
|
|
|
6
6
|
var _os = _interopRequireDefault(require("os"));
|
|
7
7
|
|
|
@@ -45,6 +45,14 @@ const getPluginBackupDirectory = () => _path.default.join(getPluginDataDirectory
|
|
|
45
45
|
|
|
46
46
|
exports.getPluginBackupDirectory = getPluginBackupDirectory;
|
|
47
47
|
|
|
48
|
+
const getStartupSnapshotDirectory = () => _path.default.join(getPluginDataDirectory(), 'startup-snapshot');
|
|
49
|
+
|
|
50
|
+
exports.getStartupSnapshotDirectory = getStartupSnapshotDirectory;
|
|
51
|
+
|
|
52
|
+
const getStartupSnapshotPath = () => _path.default.join(getStartupSnapshotDirectory(), 'current.bin');
|
|
53
|
+
|
|
54
|
+
exports.getStartupSnapshotPath = getStartupSnapshotPath;
|
|
55
|
+
|
|
48
56
|
const getPluginStatePaths = () => {
|
|
49
57
|
const base = getPluginStateDirectory();
|
|
50
58
|
return {
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.commitDecisionSnapshotRuntimeState = exports.commitCurrentPlanRuntimeState = exports.finalizeLegacyAssignmentRecoveryFromSnapshot = exports.runPendingLegacyAssignmentRecovery = void 0;
|
|
5
5
|
|
|
6
|
-
var _kcraTrace__ = require("./__kcra-trace__");
|
|
7
|
-
|
|
8
6
|
var _pluginStateStorage = require("./plugin-state-storage");
|
|
9
7
|
|
|
10
8
|
var _currentStartSelectionDomain = require("../new-interface/plan/domain/current-start-selection-domain");
|
|
@@ -33,15 +31,6 @@ const runPendingLegacyAssignmentRecovery = ({
|
|
|
33
31
|
};
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.pending.input', {
|
|
37
|
-
stateRevision: Number(snapshot.revision) || 0,
|
|
38
|
-
routeSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(snapshot),
|
|
39
|
-
assignments: (0, _pluginStateSchema.getStatePlanEquipmentAssignments)(snapshot),
|
|
40
|
-
recovery: snapshot.migration && snapshot.migration.assignmentRecovery,
|
|
41
|
-
equipInventory
|
|
42
|
-
}, {
|
|
43
|
-
full: true
|
|
44
|
-
});
|
|
45
34
|
const result = (0, _legacyAssignmentRecovery.recoverLegacyAssignmentState)({
|
|
46
35
|
plans: snapshot.user && snapshot.user.plans || {},
|
|
47
36
|
currentRouteSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(snapshot),
|
|
@@ -53,13 +42,6 @@ const runPendingLegacyAssignmentRecovery = ({
|
|
|
53
42
|
state: snapshot,
|
|
54
43
|
audit: result.audit
|
|
55
44
|
};
|
|
56
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.pending.candidate', {
|
|
57
|
-
routeSelections: result.routeSelections,
|
|
58
|
-
assignments: result.assignments,
|
|
59
|
-
audit: result.audit
|
|
60
|
-
}, {
|
|
61
|
-
full: true
|
|
62
|
-
});
|
|
63
45
|
const state = (0, _pluginStateStorage.mutatePluginState)(draft => {
|
|
64
46
|
(0, _pluginStateSchema.setStateCurrentStartSelections)(draft, result.routeSelections);
|
|
65
47
|
(0, _pluginStateSchema.setStatePlanEquipmentAssignments)(draft, result.assignments);
|
|
@@ -68,14 +50,6 @@ const runPendingLegacyAssignmentRecovery = ({
|
|
|
68
50
|
const cleanup = draft.migration.assignmentCleanup;
|
|
69
51
|
if (cleanup) (0, _pluginStateSchema.setStatePendingRebindCurrentIds)(draft, []);
|
|
70
52
|
});
|
|
71
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.pending.persisted', {
|
|
72
|
-
stateRevision: Number(state.revision) || 0,
|
|
73
|
-
routeSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(state),
|
|
74
|
-
assignments: (0, _pluginStateSchema.getStatePlanEquipmentAssignments)(state),
|
|
75
|
-
audit: state.migration && state.migration.assignmentRecovery
|
|
76
|
-
}, {
|
|
77
|
-
full: true
|
|
78
|
-
});
|
|
79
53
|
return {
|
|
80
54
|
changed: true,
|
|
81
55
|
state,
|
|
@@ -101,14 +75,6 @@ const finalizeLegacyAssignmentRecoveryFromSnapshot = ({
|
|
|
101
75
|
};
|
|
102
76
|
}
|
|
103
77
|
|
|
104
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.validation.input', {
|
|
105
|
-
stateRevision: Number(state.revision) || 0,
|
|
106
|
-
recovery,
|
|
107
|
-
assignmentBindingTransitions: snapshot && snapshot.assignmentBindingTransitions || [],
|
|
108
|
-
assignmentFindings: snapshot && snapshot.assignmentFindings || []
|
|
109
|
-
}, {
|
|
110
|
-
full: true
|
|
111
|
-
});
|
|
112
78
|
const protectedIds = new Set((recovery.protectedLegacyRouteCurrentIds || []).map(value => String(value || '').trim()).filter(Boolean));
|
|
113
79
|
const invalidProtectedIds = Array.from(new Set((snapshot && snapshot.assignmentBindingTransitions || []).filter(transition => transition && transition.type === 'invalid-persisted-binding-released' && protectedIds.has(String(transition.currentId || '').trim())).map(transition => String(transition.currentId || '').trim()).filter(Boolean)));
|
|
114
80
|
|
|
@@ -130,14 +96,6 @@ const finalizeLegacyAssignmentRecoveryFromSnapshot = ({
|
|
|
130
96
|
routeValidationFailedCurrentIds: invalidProtectedIds
|
|
131
97
|
});
|
|
132
98
|
});
|
|
133
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.validation.degraded-and-retry', {
|
|
134
|
-
invalidProtectedIds,
|
|
135
|
-
routeSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(committed),
|
|
136
|
-
assignments: (0, _pluginStateSchema.getStatePlanEquipmentAssignments)(committed),
|
|
137
|
-
audit: committed.migration && committed.migration.assignmentRecovery
|
|
138
|
-
}, {
|
|
139
|
-
full: true
|
|
140
|
-
});
|
|
141
99
|
return {
|
|
142
100
|
changed: true,
|
|
143
101
|
retry: true,
|
|
@@ -153,13 +111,6 @@ const finalizeLegacyAssignmentRecoveryFromSnapshot = ({
|
|
|
153
111
|
routeValidationFailedCurrentIds: []
|
|
154
112
|
});
|
|
155
113
|
});
|
|
156
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('recovery.validation.completed', {
|
|
157
|
-
routeSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(committed),
|
|
158
|
-
assignments: (0, _pluginStateSchema.getStatePlanEquipmentAssignments)(committed),
|
|
159
|
-
audit: committed.migration && committed.migration.assignmentRecovery
|
|
160
|
-
}, {
|
|
161
|
-
full: true
|
|
162
|
-
});
|
|
163
114
|
return {
|
|
164
115
|
changed: true,
|
|
165
116
|
retry: false,
|
|
@@ -243,38 +194,15 @@ const commitDecisionSnapshotRuntimeState = ({
|
|
|
243
194
|
const pendingChanged = Array.isArray(pendingRebind) && pendingRebind.length > 0;
|
|
244
195
|
|
|
245
196
|
if (sameValue(nextSelections, currentSelections) && sameValue(nextAssignments, currentAssignments) && !pendingChanged) {
|
|
246
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('state.binding-commit.noop', {
|
|
247
|
-
stateRevision: Number(snapshot.revision) || 0,
|
|
248
|
-
activeCurrentIds: Array.from(active),
|
|
249
|
-
assignments: currentAssignments
|
|
250
|
-
});
|
|
251
197
|
return snapshot;
|
|
252
198
|
}
|
|
253
199
|
|
|
254
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('state.binding-commit.before', {
|
|
255
|
-
stateRevision: Number(snapshot.revision) || 0,
|
|
256
|
-
activeCurrentIds: Array.from(active),
|
|
257
|
-
currentAssignments,
|
|
258
|
-
proposedAssignments: nextAssignments,
|
|
259
|
-
currentSelections,
|
|
260
|
-
nextSelections,
|
|
261
|
-
pendingRebind
|
|
262
|
-
}, {
|
|
263
|
-
full: true
|
|
264
|
-
});
|
|
265
200
|
const committed = (0, _pluginStateStorage.mutatePluginState)(state => {
|
|
266
201
|
(0, _pluginStateSchema.setStateCurrentStartSelections)(state, nextSelections);
|
|
267
202
|
(0, _pluginStateSchema.setStatePlanEquipmentAssignments)(state, nextAssignments);
|
|
268
203
|
const stateCleanup = state.migration && state.migration.assignmentCleanup;
|
|
269
204
|
if (stateCleanup && pendingChanged) (0, _pluginStateSchema.setStatePendingRebindCurrentIds)(state, []);
|
|
270
205
|
});
|
|
271
|
-
(0, _kcraTrace__.__KCRA_TRACE__)('state.binding-commit.after', {
|
|
272
|
-
stateRevision: Number(committed.revision) || 0,
|
|
273
|
-
assignments: (0, _pluginStateSchema.getStatePlanEquipmentAssignments)(committed),
|
|
274
|
-
routeSelections: (0, _pluginStateSchema.getStateCurrentStartSelections)(committed)
|
|
275
|
-
}, {
|
|
276
|
-
full: true
|
|
277
|
-
});
|
|
278
206
|
return committed;
|
|
279
207
|
};
|
|
280
208
|
|