bulltrackers-module 1.0.171 → 1.0.173
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/README.MD +3 -179
- package/functions/computation-system/controllers/computation_controller.js +211 -0
- package/functions/computation-system/helpers/computation_manifest_builder.js +15 -20
- package/functions/computation-system/helpers/computation_pass_runner.js +68 -35
- package/functions/computation-system/helpers/orchestration_helpers.js +185 -717
- package/functions/computation-system/layers/math_primitives.js +747 -0
- package/functions/task-engine/helpers/update_helpers.js +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FIXED: computation_pass_runner.js
|
|
3
|
-
*
|
|
4
|
-
* --- MODIFIED: Passes 'existingResults' to 'runStandardComputationPass'
|
|
5
|
-
* to replicate the test harness's 7-argument signature. ---
|
|
3
|
+
* V3: Fetches Previous Day's Results to enable State Persistence.
|
|
6
4
|
*/
|
|
7
5
|
|
|
8
6
|
const { groupByPass, checkRootDataAvailability, fetchExistingResults, runStandardComputationPass, runMetaComputationPass } = require('./orchestration_helpers.js');
|
|
@@ -11,63 +9,98 @@ const PARALLEL_BATCH_SIZE = 7;
|
|
|
11
9
|
|
|
12
10
|
async function runComputationPass(config, dependencies, computationManifest) {
|
|
13
11
|
const { logger } = dependencies;
|
|
14
|
-
const passToRun
|
|
15
|
-
if (!passToRun)
|
|
12
|
+
const passToRun = String(config.COMPUTATION_PASS_TO_RUN);
|
|
13
|
+
if (!passToRun)
|
|
14
|
+
return logger.log('ERROR', '[PassRunner] No pass defined. Aborting.');
|
|
15
|
+
|
|
16
16
|
logger.log('INFO', `🚀 Starting PASS ${passToRun}...`);
|
|
17
17
|
|
|
18
|
-
const earliestDates
|
|
18
|
+
const earliestDates = { portfolio: new Date('2025-09-25T00:00:00Z'), history: new Date('2025-11-05T00:00:00Z'), social: new Date('2025-10-30T00:00:00Z'), insights: new Date('2025-08-26T00:00:00Z') };
|
|
19
19
|
earliestDates.absoluteEarliest = Object.values(earliestDates).reduce((a,b) => a < b ? a : b);
|
|
20
|
-
logger.log('INFO', `Hardcoded earliest dates: ${Object.entries(earliestDates).map(([k,v]) => `${k}=${v.toISOString().slice(0,10)}`).join(', ')}`);
|
|
21
20
|
|
|
22
|
-
const passes
|
|
21
|
+
const passes = groupByPass(computationManifest);
|
|
23
22
|
const calcsInThisPass = passes[passToRun] || [];
|
|
24
|
-
|
|
23
|
+
|
|
24
|
+
if (!calcsInThisPass.length)
|
|
25
|
+
return logger.log('WARN', `[PassRunner] No calcs for Pass ${passToRun}. Exiting.`);
|
|
26
|
+
|
|
25
27
|
const calcEarliestDates = new Map();
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
|
|
29
|
+
for (const calc of calcsInThisPass) {
|
|
30
|
+
const deps = calc.rootDataDependencies || [];
|
|
31
|
+
|
|
32
|
+
if (!deps.length)
|
|
33
|
+
{ calcEarliestDates.set(calc.name, earliestDates.absoluteEarliest); continue; }
|
|
34
|
+
|
|
35
|
+
const latestDep = new Date(Math.max(...deps.map(d => earliestDates[d]?.getTime() || 0)));
|
|
36
|
+
const calcDate = calc.isHistorical
|
|
37
|
+
? new Date(latestDep.getTime() + 86400000)
|
|
38
|
+
: latestDep;
|
|
39
|
+
|
|
40
|
+
calcEarliestDates.set(calc.name, calcDate);
|
|
41
|
+
}
|
|
31
42
|
|
|
32
43
|
const passEarliestDate = new Date(Math.min(...Array.from(calcEarliestDates.values()).map(d => d.getTime())));
|
|
33
|
-
|
|
34
|
-
const endDateUTC = new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate() - 1));
|
|
44
|
+
const endDateUTC = new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate() - 1));
|
|
35
45
|
const allExpectedDates = getExpectedDateStrings(passEarliestDate, endDateUTC);
|
|
36
|
-
const standardCalcs
|
|
37
|
-
const metaCalcs
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
46
|
+
const standardCalcs = calcsInThisPass.filter(c => c.type === 'standard');
|
|
47
|
+
const metaCalcs = calcsInThisPass.filter(c => c.type === 'meta');
|
|
48
|
+
|
|
49
|
+
const checkDeps = (calc, rootData, existingResults, dateToProcess) => {
|
|
50
|
+
if (existingResults[calc.name])
|
|
51
|
+
return false;
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
if (missingRoot.length) return false;
|
|
53
|
+
const earliest = calcEarliestDates.get(calc.name);
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
if (earliest && dateToProcess < earliest)
|
|
56
|
+
return false;
|
|
57
|
+
|
|
58
|
+
const missingRoot = (calc.rootDataDependencies || []).filter(dep => !rootData.status[`has${dep[0].toUpperCase() + dep.slice(1)}`]);
|
|
59
|
+
|
|
60
|
+
if (missingRoot.length)
|
|
61
|
+
return false;
|
|
62
|
+
|
|
63
|
+
if (calc.type === 'meta')
|
|
64
|
+
{ const missingComputed = (calc.dependencies || []).filter(d => !existingResults[d]);
|
|
65
|
+
if (missingComputed.length)
|
|
66
|
+
return false; }
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
46
69
|
|
|
47
70
|
const processDate = async (dateStr) => {
|
|
48
71
|
const dateToProcess = new Date(dateStr + 'T00:00:00Z');
|
|
49
72
|
try {
|
|
50
73
|
const rootData = await checkRootDataAvailability(dateStr, config, dependencies, earliestDates);
|
|
51
74
|
if (!rootData) return logger.log('WARN', `[PassRunner] Skipping ${dateStr}: No root data.`);
|
|
52
|
-
|
|
75
|
+
|
|
76
|
+
// 1. Fetch TODAY'S results (Check what is already done)
|
|
77
|
+
const existingResults = await fetchExistingResults(dateStr, calcsInThisPass, computationManifest, config, dependencies, false);
|
|
78
|
+
|
|
79
|
+
// 2. Fetch YESTERDAY'S results (For State Persistence) We calculate T-1 date string
|
|
80
|
+
const prevDate = new Date(dateToProcess); prevDate.setUTCDate(prevDate.getUTCDate() - 1);
|
|
81
|
+
const prevDateStr = prevDate.toISOString().slice(0, 10);
|
|
82
|
+
|
|
83
|
+
// We pass 'true' to includeSelf, because we need the calc's OWN history (e.g. mimetic-latency needs previous mimetic-latency)
|
|
84
|
+
const previousResults = await fetchExistingResults(prevDateStr, calcsInThisPass, computationManifest, config, dependencies, true);
|
|
85
|
+
|
|
53
86
|
const standardToRun = standardCalcs.filter(c => checkDeps(c, rootData, existingResults, dateToProcess));
|
|
54
87
|
const metaToRun = metaCalcs.filter(c => checkDeps(c, rootData, existingResults, dateToProcess));
|
|
88
|
+
|
|
55
89
|
if (!standardToRun.length && !metaToRun.length) return logger.log('INFO', `[PassRunner] All calcs complete for ${dateStr}. Skipping.`);
|
|
90
|
+
|
|
56
91
|
logger.log('INFO', `[PassRunner] Running ${dateStr}: ${standardToRun.length} standard, ${metaToRun.length} meta`);
|
|
57
92
|
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// --- END CHANGE ---
|
|
63
|
-
|
|
64
|
-
if (metaToRun.length) await runMetaComputationPass(dateToProcess, metaToRun, `Pass ${passToRun} (Meta)`, config, dependencies, existingResults, rootData);
|
|
93
|
+
// Pass 'previousResults' to the runners
|
|
94
|
+
if (standardToRun.length) await runStandardComputationPass(dateToProcess, standardToRun, `Pass ${passToRun} (Standard)`, config, dependencies, rootData, existingResults, previousResults);
|
|
95
|
+
if (metaToRun.length) await runMetaComputationPass(dateToProcess, metaToRun, `Pass ${passToRun} (Meta)`, config, dependencies, existingResults, previousResults, rootData);
|
|
96
|
+
|
|
65
97
|
} catch (err) { logger.log('ERROR', `[PassRunner] FAILED Pass ${passToRun} for ${dateStr}`, { errorMessage: err.message, stack: err.stack }); }
|
|
66
98
|
};
|
|
67
99
|
|
|
68
|
-
for (let i = 0; i < allExpectedDates.length; i += PARALLEL_BATCH_SIZE) {
|
|
69
|
-
|
|
70
|
-
|
|
100
|
+
for (let i = 0; i < allExpectedDates.length; i += PARALLEL_BATCH_SIZE) {
|
|
101
|
+
const batch = allExpectedDates.slice(i, i + PARALLEL_BATCH_SIZE);
|
|
102
|
+
await Promise.all(batch.map(processDate));
|
|
103
|
+
}
|
|
71
104
|
logger.log('INFO', `[PassRunner] Pass ${passToRun} orchestration finished.`);
|
|
72
105
|
}
|
|
73
106
|
|