bulltrackers-module 1.0.163 → 1.0.164
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.
|
@@ -11,11 +11,9 @@
|
|
|
11
11
|
* It has removed all logic for deprecated folder structures (e.g., /historical/).
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
const { calculations } = require('aiden-shared-calculations-unified');
|
|
15
14
|
const fs = require('fs');
|
|
16
15
|
const path = require('path');
|
|
17
|
-
const Viz
|
|
18
|
-
const { Module, render } = require('viz.js/full.render.js');
|
|
16
|
+
const Viz = require('../node-graphviz'); // Uses your local module
|
|
19
17
|
|
|
20
18
|
/* --------------------------------------------------
|
|
21
19
|
* Pretty Console Helpers
|
|
@@ -88,9 +86,10 @@ function getDependencySet(endpoints, adjacencyList) {
|
|
|
88
86
|
/**
|
|
89
87
|
* Builds the full computation manifest.
|
|
90
88
|
* @param {string[]} productLinesToRun - Array of product line categories (folder names) to build for.
|
|
89
|
+
* @param {object} calculations - The injected calculations object from the main application.
|
|
91
90
|
* @returns {object[]} The final sorted manifest array.
|
|
92
91
|
*/
|
|
93
|
-
function buildManifest(productLinesToRun = []) {
|
|
92
|
+
function buildManifest(productLinesToRun = [], calculations) {
|
|
94
93
|
log.divider('Building Dynamic Manifest');
|
|
95
94
|
log.info(`Target Product Lines: [${productLinesToRun.join(', ')}]`);
|
|
96
95
|
const manifestMap = new Map();
|
|
@@ -134,6 +133,14 @@ function buildManifest(productLinesToRun = []) {
|
|
|
134
133
|
adjacency.set(normalizedName, dependencies);
|
|
135
134
|
inDegree.set(normalizedName, dependencies.length);
|
|
136
135
|
dependencies.forEach(dep => { if (!reverseAdjacency.has(dep)) reverseAdjacency.set(dep, []); reverseAdjacency.get(dep).push(normalizedName); }); }
|
|
136
|
+
|
|
137
|
+
// --- UPDATED ---
|
|
138
|
+
// This 'calculations' object is now the one passed in as an argument.
|
|
139
|
+
if (!calculations || typeof calculations !== 'object') {
|
|
140
|
+
log.fatal('Calculations object was not provided or is invalid.');
|
|
141
|
+
throw new Error('Manifest build failed: Invalid calculations object.');
|
|
142
|
+
}
|
|
143
|
+
|
|
137
144
|
for (const category in calculations) {
|
|
138
145
|
if (category === 'legacy') { log.info('Skipping "legacy" calculations package.'); continue; }
|
|
139
146
|
const group = calculations[category];
|
|
@@ -219,7 +226,7 @@ function buildManifest(productLinesToRun = []) {
|
|
|
219
226
|
*/
|
|
220
227
|
async function generateSvgGraph(manifest, filename = 'dependency-tree.svg') {
|
|
221
228
|
log.divider(`Generating SVG Graph: ${filename}`);
|
|
222
|
-
const viz = new Viz({
|
|
229
|
+
const viz = new Viz({ worker: false });
|
|
223
230
|
const categories = [...new Set(manifest.map(e => e.category))];
|
|
224
231
|
const colors = ['#e6194b', '#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#bcf60c', '#fabebe', '#008080', '#e6beff', '#9a6324', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1', '#000075', '#808080'];
|
|
225
232
|
const colorMap = new Map(categories.map((cat, i) => [cat, colors[i % colors.length]]));
|
|
@@ -251,12 +258,13 @@ async function generateSvgGraph(manifest, filename = 'dependency-tree.svg') {
|
|
|
251
258
|
/**
|
|
252
259
|
* Main entry point for building and exporting the manifest.
|
|
253
260
|
* @param {string[]} productLinesToRun - Array of product line categories (folder names) to build for.
|
|
261
|
+
* @param {object} calculations - The injected calculations object.
|
|
254
262
|
*/
|
|
255
|
-
function build(productLinesToRun) {
|
|
263
|
+
function build(productLinesToRun, calculations) {
|
|
256
264
|
try {
|
|
257
265
|
// This function MUST NOT fail or generate SVGs.
|
|
258
266
|
// It has one job: build and return the manifest array.
|
|
259
|
-
const manifest = buildManifest(productLinesToRun);
|
|
267
|
+
const manifest = buildManifest(productLinesToRun, calculations);
|
|
260
268
|
return manifest; // Returns the array
|
|
261
269
|
} catch (error) {
|
|
262
270
|
log.error(error.message);
|
|
@@ -266,29 +274,9 @@ function build(productLinesToRun) {
|
|
|
266
274
|
}
|
|
267
275
|
}
|
|
268
276
|
|
|
269
|
-
|
|
277
|
+
// --- REMOVED ---
|
|
278
|
+
// The entire 'if (require.main === module)' block has been removed
|
|
279
|
+
// to prevent any local 'require' conflicts. This file is now a pure
|
|
280
|
+
// module and must be called by another script.
|
|
270
281
|
|
|
271
|
-
//
|
|
272
|
-
// This block is ONLY executed when you run `node computation_manifest_builder.js`
|
|
273
|
-
// This is now the ONLY place SVG generation happens.
|
|
274
|
-
if (require.main === module) {
|
|
275
|
-
(async () => { // This part remains async for the SVG generation
|
|
276
|
-
log.info('Running manifest builder in local debug mode...');
|
|
277
|
-
const allProductLines = Object.keys(calculations).filter(c => c !== 'legacy');
|
|
278
|
-
|
|
279
|
-
try {
|
|
280
|
-
// 1. Build the full manifest
|
|
281
|
-
const fullManifest = buildManifest(allProductLines); // Sync call
|
|
282
|
-
|
|
283
|
-
if (fullManifest) {
|
|
284
|
-
// 2. Generate the full SVG graph
|
|
285
|
-
await generateSvgGraph(fullManifest, 'dependency-tree-full.svg');
|
|
286
|
-
log.info('Local debug build and graph generation complete.');
|
|
287
|
-
} else {
|
|
288
|
-
log.fatal('Local debug build FAILED.');
|
|
289
|
-
}
|
|
290
|
-
} catch (error) {
|
|
291
|
-
log.error(error.message);
|
|
292
|
-
}
|
|
293
|
-
})();
|
|
294
|
-
}
|
|
282
|
+
module.exports = { build, generateSvgGraph }; // <-- Also exporting generateSvgGraph
|
|
@@ -20,11 +20,25 @@ exports.fetchAndStoreInsights = async (config, dependencies) => {
|
|
|
20
20
|
if (!selectedHeader || !selectedHeader.header) { throw new Error("Could not select a valid header for the request."); }
|
|
21
21
|
logger.log('INFO', `[FetchInsightsHelpers] Using header ID: ${selectedHeader.id}`, { userAgent: selectedHeader.header['User-Agent'] });
|
|
22
22
|
const fetchOptions = { headers: selectedHeader.header, timeout: 30000 };
|
|
23
|
-
|
|
23
|
+
let response;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
logger.log('INFO', '[FetchInsightsHelpers] Attempting fetch via proxy manager...');
|
|
27
|
+
response = await proxyManager.fetch(config.etoroInsightsUrl, fetchOptions);
|
|
28
|
+
} catch (proxyError) {
|
|
29
|
+
logger.log('WARNING', `[FetchInsightsHelpers] Proxy manager fetch failed. Attempting fallback with node-fetch. Error: ${proxyError.message}`);
|
|
30
|
+
try {
|
|
31
|
+
response = await fetch(config.etoroInsightsUrl, fetchOptions);
|
|
32
|
+
} catch (nodeFetchError) {
|
|
33
|
+
logger.log('ERROR', `[FetchInsightsHelpers] Fallback node-fetch also failed. Error: ${nodeFetchError.message}`);
|
|
34
|
+
throw nodeFetchError; // Throw the error from the last attempt
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
if (!response || typeof response.text !== 'function') { const responseString = JSON.stringify(response, null, 2);
|
|
25
|
-
logger.log('ERROR', `[FetchInsightsHelpers] Invalid or incomplete response received. Response object: ${responseString}`); throw new Error(`Invalid response structure received
|
|
39
|
+
logger.log('ERROR', `[FetchInsightsHelpers] Invalid or incomplete response received. Response object: ${responseString}`); throw new Error(`Invalid response structure received.`); }
|
|
26
40
|
if (!response.ok) { const errorText = await response.text();
|
|
27
|
-
throw new Error(`API request failed
|
|
41
|
+
throw new Error(`API request failed with status ${response.status}: ${errorText}`); }
|
|
28
42
|
wasSuccessful = true;
|
|
29
43
|
const insightsData = await response.json();
|
|
30
44
|
if (!Array.isArray(insightsData) || insightsData.length === 0) { throw new Error('API returned empty or invalid data.'); }
|
|
@@ -71,19 +71,20 @@ exports.handleSocialTask = async (message, context, config, dependencies) => {
|
|
|
71
71
|
if (!response.ok) throw new Error(`API error ${response.status}`);
|
|
72
72
|
wasSuccess = true;
|
|
73
73
|
} catch (proxyError) {
|
|
74
|
-
logger.log('WARN', `[SocialTask/${taskId}] Proxy fetch failed for offset ${offset}: ${proxyError.message}`, { err: proxyError.message });
|
|
75
|
-
logger.log('INFO', `[SocialTask/${taskId}] Retrying fetch without proxy
|
|
74
|
+
logger.log('WARN', `[SocialTask/${taskId}] Proxy fetch failed for offset ${offset}: ${proxyError.message}`, { err: proxyError.message, url } );
|
|
75
|
+
logger.log('INFO', `[SocialTask/${taskId}] Retrying fetch without proxy for.`, url);
|
|
76
76
|
try {
|
|
77
77
|
response = await fetch(url, { headers: selectedHeader.header });
|
|
78
|
-
if (!response.ok) throw new Error(`Direct fetch API error ${response.status}`);
|
|
78
|
+
if (!response.ok) throw new Error(`Direct fetch API error ${response.status} for ${url}`);
|
|
79
79
|
} catch (directError) {
|
|
80
|
-
logger.log('ERROR', `[SocialTask/${taskId}] Direct fetch retry failed: ${directError.message}`, { err: directError.message });
|
|
80
|
+
logger.log('ERROR', `[SocialTask/${taskId}] Direct fetch retry failed: ${directError.message}`, { err: directError.message , url});
|
|
81
81
|
if (selectedHeader) headerManager.updatePerformance(selectedHeader.id, false);
|
|
82
82
|
keepFetching = false;
|
|
83
83
|
continue;
|
|
84
84
|
}
|
|
85
85
|
} finally {
|
|
86
86
|
if (selectedHeader) headerManager.updatePerformance(selectedHeader.id, wasSuccess);
|
|
87
|
+
logger.log('DEBUG', 'Response succeeded for', url)
|
|
87
88
|
}
|
|
88
89
|
const page = await response.json();
|
|
89
90
|
const discussions = page?.discussions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bulltrackers-module",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.164",
|
|
4
4
|
"description": "Helper Functions for Bulltrackers.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -33,13 +33,15 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@google-cloud/firestore": "^7.11.3",
|
|
36
|
-
"sharedsetup": "latest",
|
|
37
|
-
"require-all": "^3.0.0",
|
|
38
36
|
"@google-cloud/pubsub": "latest",
|
|
39
|
-
"
|
|
37
|
+
"aiden-shared-calculations-unified": "^1.0.81",
|
|
40
38
|
"cors": "^2.8.5",
|
|
39
|
+
"dotenv": "latest",
|
|
40
|
+
"express": "^4.19.2",
|
|
41
|
+
"node-graphviz": "^0.1.1",
|
|
41
42
|
"p-limit": "^3.1.0",
|
|
42
|
-
"
|
|
43
|
+
"require-all": "^3.0.0",
|
|
44
|
+
"sharedsetup": "latest"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"bulltracker-deployer": "file:../bulltracker-deployer"
|