@yemi33/minions 0.1.2030 → 0.1.2031
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/dashboard/js/refresh.js
CHANGED
|
@@ -36,13 +36,21 @@ function _detectPageChanges(data) {
|
|
|
36
36
|
|
|
37
37
|
// Change detection — skip renders for sections that haven't changed since last refresh.
|
|
38
38
|
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
39
|
+
// Two-layer cache:
|
|
40
|
+
// 1. `_lastValueByKey` is an O(1) reference-equality precheck: when the server
|
|
41
|
+
// returns 304 Not Modified (refresh.js ~173) we reuse the same `_lastStatusData`
|
|
42
|
+
// reference tick after tick, so every `_changed(key, data.<slice>)` call below
|
|
43
|
+
// would otherwise re-stringify multi-MB slices for nothing. The JSON.stringify
|
|
44
|
+
// path stays as the fallback for the "fresh object, equal contents" case
|
|
45
|
+
// (S3, W-mpgcikfg000g8dc7).
|
|
46
|
+
// 2. RENDER_VERSIONS is the in-process cache-bust knob (R3, W-mpgb0xgc000hf1d3).
|
|
47
|
+
// _changed() caches JSON.stringify(value) per (key, version), so when the
|
|
48
|
+
// input data is byte-identical between ticks the render is skipped. That's
|
|
49
|
+
// the right call 99% of the time, but it has a sharp edge: when a renderer
|
|
50
|
+
// body itself is edited (hot-reloaded via dashboard-build.js or a freshly
|
|
51
|
+
// shipped bundle) and the input stays the same, the stale render persists
|
|
52
|
+
// forever because the cache key still matches. F8 / "projects chip" class
|
|
53
|
+
// of bug.
|
|
46
54
|
//
|
|
47
55
|
// Bump the matching entry below whenever a renderer's *output* may change
|
|
48
56
|
// for the same input. Cross-restart safety lives in the dashboardBuildId
|
|
@@ -74,15 +82,24 @@ const RENDER_VERSIONS = {
|
|
|
74
82
|
pinned: 1,
|
|
75
83
|
};
|
|
76
84
|
const _sectionCache = {};
|
|
85
|
+
const _lastValueByKey = {};
|
|
77
86
|
const _sectionCacheVersions = {};
|
|
78
87
|
function _changed(key, value, version) {
|
|
79
88
|
var v = version == null ? (RENDER_VERSIONS[key] || 0) : version;
|
|
80
89
|
// Drop the stale-version entry so the cache doesn't grow unbounded across bumps.
|
|
90
|
+
// A version bump must also reset the ref-eq sentinel — otherwise the S3
|
|
91
|
+
// short-circuit below would defeat the R3 cache-bust contract when the
|
|
92
|
+
// caller passes the SAME object reference across a version bump.
|
|
81
93
|
if (_sectionCacheVersions[key] !== undefined && _sectionCacheVersions[key] !== v) {
|
|
82
94
|
delete _sectionCache[key + ':v' + _sectionCacheVersions[key]];
|
|
95
|
+
_lastValueByKey[key] = undefined;
|
|
83
96
|
}
|
|
84
97
|
_sectionCacheVersions[key] = v;
|
|
85
98
|
var cacheKey = key + ':v' + v;
|
|
99
|
+
// Reference-equality short-circuit: skip the stringify entirely when the
|
|
100
|
+
// server returned 304 and the same object reference is being re-checked.
|
|
101
|
+
if (_lastValueByKey[key] === value) return false;
|
|
102
|
+
_lastValueByKey[key] = value;
|
|
86
103
|
var json = JSON.stringify(value);
|
|
87
104
|
if (_sectionCache[cacheKey] === json) return false;
|
|
88
105
|
_sectionCache[cacheKey] = json;
|
|
@@ -491,7 +491,7 @@ function openPipelineDetail(id) {
|
|
|
491
491
|
var fresh = list.find(function(x) { return x.id === id; });
|
|
492
492
|
if (fresh) {
|
|
493
493
|
// Only re-render if data changed
|
|
494
|
-
var newHash =
|
|
494
|
+
var newHash = _computePipelineDetailHash(fresh);
|
|
495
495
|
if (newHash !== _pipelinePollHash) {
|
|
496
496
|
_pipelinePollHash = newHash;
|
|
497
497
|
_pipelinesData = _pipelinesData.map(function(x) { return x.id === id ? fresh : x; });
|
|
@@ -504,6 +504,24 @@ function openPipelineDetail(id) {
|
|
|
504
504
|
}
|
|
505
505
|
var _pipelinePollHash = '';
|
|
506
506
|
|
|
507
|
+
// F10: hash all pipeline fields the detail modal renders so stages/cron/monitoredResources/stopWhen
|
|
508
|
+
// edits in another tab trigger re-render. Previously only {runs, enabled, _stoppedBy, _stopReason}.
|
|
509
|
+
function _computePipelineDetailHash(p) {
|
|
510
|
+
if (!p) return '';
|
|
511
|
+
return JSON.stringify({
|
|
512
|
+
runs: p.runs || [],
|
|
513
|
+
enabled: p.enabled,
|
|
514
|
+
_stoppedBy: p._stoppedBy,
|
|
515
|
+
_stopReason: p._stopReason,
|
|
516
|
+
stages: p.stages,
|
|
517
|
+
monitoredResources: p.monitoredResources,
|
|
518
|
+
stopWhen: p.stopWhen,
|
|
519
|
+
trigger: p.trigger,
|
|
520
|
+
name: p.name,
|
|
521
|
+
description: p.description
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
507
525
|
/**
|
|
508
526
|
* Fetch fresh pipeline data and re-render the detail modal immediately.
|
|
509
527
|
* Used after actions (continue, trigger, abort) to avoid waiting for the 4s poll.
|
|
@@ -516,7 +534,7 @@ async function _refreshPipelineDetail(id) {
|
|
|
516
534
|
var fresh = list.find(function(x) { return x.id === id; });
|
|
517
535
|
if (fresh) {
|
|
518
536
|
_pipelinesData = _pipelinesData.map(function(x) { return x.id === id ? fresh : x; });
|
|
519
|
-
_pipelinePollHash =
|
|
537
|
+
_pipelinePollHash = _computePipelineDetailHash(fresh);
|
|
520
538
|
renderPipelines(_pipelinesData);
|
|
521
539
|
openPipelineDetail(id);
|
|
522
540
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2031",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|