bulltrackers-module 1.0.649 → 1.0.651
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.
|
@@ -43,12 +43,26 @@ function isDataEmpty(data) {
|
|
|
43
43
|
* This fixes the 'fetchExistingResults is not a function' TypeError.
|
|
44
44
|
*/
|
|
45
45
|
async function fetchExistingResults(dateStr, calcs, fullManifest, config, deps, isHistoricalContext) {
|
|
46
|
+
const { logger } = deps;
|
|
47
|
+
|
|
48
|
+
// DEBUG: Log entry
|
|
49
|
+
logger.log('INFO', `[DependencyFetcher] 📥 fetchExistingResults called for date: ${dateStr}, calcs: ${calcs.length}, isHistorical: ${isHistoricalContext}`);
|
|
50
|
+
logger.log('INFO', `[DependencyFetcher] 📥 Calcs being processed: ${calcs.map(c => {
|
|
51
|
+
const name = c.name || c.constructor?.name || 'unknown';
|
|
52
|
+
const hasClass = !!c.class;
|
|
53
|
+
const classType = c.class ? (typeof c.class === 'function' ? 'function' : typeof c.class) : 'none';
|
|
54
|
+
return `${name} (has class: ${hasClass}, class type: ${classType})`;
|
|
55
|
+
}).join(', ')}`);
|
|
56
|
+
|
|
46
57
|
// 1. Build Manifest Lookup (Name -> Category)
|
|
47
58
|
const manifestLookup = {};
|
|
48
59
|
if (Array.isArray(fullManifest)) {
|
|
49
60
|
fullManifest.forEach(c => {
|
|
50
61
|
manifestLookup[normalizeName(c.name)] = c.category || 'analytics';
|
|
51
62
|
});
|
|
63
|
+
logger.log('INFO', `[DependencyFetcher] 📥 Built manifest lookup with ${Object.keys(manifestLookup).length} entries`);
|
|
64
|
+
} else {
|
|
65
|
+
logger.log('WARN', `[DependencyFetcher] ⚠️ fullManifest is not an array: ${typeof fullManifest}`);
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
// 2. Convert Date String to Date Object
|
|
@@ -58,7 +72,13 @@ async function fetchExistingResults(dateStr, calcs, fullManifest, config, deps,
|
|
|
58
72
|
// 3. Delegate to fetchDependencies
|
|
59
73
|
// CRITICAL: For historical context (yesterday's data), allow missing dependencies
|
|
60
74
|
// Historical lookbacks are optional - gaps in historical data are permissible
|
|
61
|
-
|
|
75
|
+
const result = await fetchDependencies(dateObj, calcs, config, deps, manifestLookup, isHistoricalContext);
|
|
76
|
+
|
|
77
|
+
// DEBUG: Log result
|
|
78
|
+
const resultKeys = Object.keys(result);
|
|
79
|
+
logger.log('INFO', `[DependencyFetcher] 📤 fetchExistingResults returning ${resultKeys.length} dependencies: ${resultKeys.length > 0 ? resultKeys.join(', ') : 'NONE'}`);
|
|
80
|
+
|
|
81
|
+
return result;
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
/**
|
|
@@ -74,31 +94,74 @@ async function fetchDependencies(date, calcs, config, deps, manifestLookup = {},
|
|
|
74
94
|
const { db, logger } = deps;
|
|
75
95
|
const dStr = date.toISOString().slice(0, 10);
|
|
76
96
|
|
|
97
|
+
// DEBUG: Log entry
|
|
98
|
+
logger.log('INFO', `[DependencyFetcher] 🔍 fetchDependencies called with ${calcs.length} calc(s): ${calcs.map(c => c.name || c.constructor?.name || 'unknown').join(', ')}`);
|
|
99
|
+
|
|
77
100
|
// 1. Identify unique dependencies needed
|
|
78
101
|
// CHANGED: Use a Map to track { normalizedName: originalName }
|
|
79
102
|
const needed = new Map();
|
|
80
103
|
|
|
81
104
|
calcs.forEach(c => {
|
|
105
|
+
const calcName = c.name || c.constructor?.name || 'unknown';
|
|
106
|
+
|
|
107
|
+
// DEBUG: Log what we're checking
|
|
108
|
+
logger.log('INFO', `[DependencyFetcher] 🔍 Processing calc: ${calcName}`);
|
|
109
|
+
logger.log('INFO', `[DependencyFetcher] - has class: ${!!c.class}`);
|
|
110
|
+
logger.log('INFO', `[DependencyFetcher] - class type: ${c.class ? (typeof c.class === 'function' ? 'function' : typeof c.class) : 'none'}`);
|
|
111
|
+
logger.log('INFO', `[DependencyFetcher] - class.getDependencies: ${c.class && typeof c.class.getDependencies === 'function' ? 'YES' : 'NO'}`);
|
|
112
|
+
logger.log('INFO', `[DependencyFetcher] - has getDependencies: ${typeof c.getDependencies === 'function' ? 'YES' : 'NO'}`);
|
|
113
|
+
logger.log('INFO', `[DependencyFetcher] - has dependencies array: ${Array.isArray(c.dependencies) ? `YES (${c.dependencies.length} items)` : 'NO'}`);
|
|
114
|
+
if (Array.isArray(c.dependencies)) {
|
|
115
|
+
logger.log('INFO', `[DependencyFetcher] - dependencies array: ${c.dependencies.join(', ')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
82
118
|
// [FIX] Support both .getDependencies() method and .dependencies array
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
119
|
+
// CRITICAL: Prefer class.getDependencies() over manifest.dependencies
|
|
120
|
+
// because the class method returns original case-sensitive names,
|
|
121
|
+
// while manifest.dependencies contains normalized names
|
|
122
|
+
let reqs = [];
|
|
123
|
+
if (c.class && typeof c.class.getDependencies === 'function') {
|
|
124
|
+
// Use the class method - returns original case-sensitive names
|
|
125
|
+
reqs = c.class.getDependencies();
|
|
126
|
+
logger.log('INFO', `[DependencyFetcher] ✅ Using c.class.getDependencies() - returned: ${JSON.stringify(reqs)}`);
|
|
127
|
+
} else if (typeof c.getDependencies === 'function') {
|
|
128
|
+
// Fallback: direct method call (if c is the class itself)
|
|
129
|
+
reqs = c.getDependencies();
|
|
130
|
+
logger.log('INFO', `[DependencyFetcher] ✅ Using c.getDependencies() - returned: ${JSON.stringify(reqs)}`);
|
|
131
|
+
} else if (c.dependencies && Array.isArray(c.dependencies)) {
|
|
132
|
+
// Last resort: use manifest's dependencies array (normalized)
|
|
133
|
+
// This is less ideal because names are normalized, but we'll use them as-is
|
|
134
|
+
reqs = c.dependencies;
|
|
135
|
+
logger.log('INFO', `[DependencyFetcher] ⚠️ Using c.dependencies array (normalized) - returned: ${JSON.stringify(reqs)}`);
|
|
136
|
+
} else {
|
|
137
|
+
logger.log('WARN', `[DependencyFetcher] ❌ No way to get dependencies for ${calcName} - all methods failed`);
|
|
138
|
+
}
|
|
86
139
|
|
|
87
140
|
if (Array.isArray(reqs)) {
|
|
141
|
+
logger.log('INFO', `[DependencyFetcher] ✅ Found ${reqs.length} dependencies for ${calcName}: ${reqs.join(', ')}`);
|
|
88
142
|
reqs.forEach(r => {
|
|
89
143
|
// We map the normalized version to the original requested version
|
|
90
144
|
// This ensures we fetch the right file (normalized) but return it
|
|
91
145
|
// with the casing the user code expects (original).
|
|
92
146
|
needed.set(normalizeName(r), r);
|
|
93
147
|
});
|
|
148
|
+
} else {
|
|
149
|
+
logger.log('WARN', `[DependencyFetcher] ⚠️ reqs is not an array for ${calcName}: ${typeof reqs}`);
|
|
94
150
|
}
|
|
95
151
|
});
|
|
96
152
|
|
|
97
|
-
if (needed.size === 0)
|
|
153
|
+
if (needed.size === 0) {
|
|
154
|
+
logger.log('WARN', `[DependencyFetcher] ⚠️ No dependencies needed - returning empty object`);
|
|
155
|
+
return {};
|
|
156
|
+
}
|
|
98
157
|
|
|
99
158
|
const calcNames = calcs.map(c => c.name || c.constructor?.name || 'unknown').join(', ');
|
|
100
159
|
logger.log('INFO', `[DependencyFetcher] Fetching ${needed.size} dependencies for computation(s): ${calcNames} (date: ${dStr})`);
|
|
101
160
|
|
|
161
|
+
// DEBUG: Log what dependencies we're looking for
|
|
162
|
+
const depList = Array.from(needed.entries()).map(([norm, orig]) => `${orig} (normalized: ${norm})`).join(', ');
|
|
163
|
+
logger.log('INFO', `[DependencyFetcher] Dependencies requested: ${depList}`);
|
|
164
|
+
|
|
102
165
|
const results = {};
|
|
103
166
|
const missingDeps = [];
|
|
104
167
|
const emptyDeps = [];
|
|
@@ -142,6 +205,9 @@ async function fetchDependencies(date, calcs, config, deps, manifestLookup = {},
|
|
|
142
205
|
} else {
|
|
143
206
|
// CHANGED: Store result using the ORIGINAL name so context.computed['CaseSensitive'] works
|
|
144
207
|
results[originalName] = data;
|
|
208
|
+
// DEBUG: Log successful dependency load
|
|
209
|
+
const dataKeys = Object.keys(data);
|
|
210
|
+
logger.log('INFO', `[DependencyFetcher] ✅ Stored dependency '${originalName}' in results. Keys: ${dataKeys.length} (sample: ${dataKeys.slice(0, 5).join(', ')})`);
|
|
145
211
|
}
|
|
146
212
|
} catch (e) {
|
|
147
213
|
missingDeps.push({ name: originalName, normalizedName: normName, path, error: e.message });
|
|
@@ -156,6 +222,10 @@ async function fetchDependencies(date, calcs, config, deps, manifestLookup = {},
|
|
|
156
222
|
|
|
157
223
|
await Promise.all(promises);
|
|
158
224
|
|
|
225
|
+
// DEBUG: Log what we're returning
|
|
226
|
+
const resultKeys = Object.keys(results);
|
|
227
|
+
logger.log('INFO', `[DependencyFetcher] ✅ Returning ${resultKeys.length} dependencies: ${resultKeys.join(', ')}`);
|
|
228
|
+
|
|
159
229
|
// CRITICAL: Fail if any required dependencies are missing or empty
|
|
160
230
|
// EXCEPTION: For historical/lookback scenarios, missing dependencies are permissible
|
|
161
231
|
if ((missingDeps.length > 0 || emptyDeps.length > 0) && !allowMissing) {
|
|
@@ -177,6 +177,10 @@ class MetaExecutor {
|
|
|
177
177
|
const inst = new c.class();
|
|
178
178
|
inst.manifest = c;
|
|
179
179
|
|
|
180
|
+
// DEBUG: Log what dependencies were fetched
|
|
181
|
+
const fetchedDepKeys = Object.keys(fetchedDeps || {});
|
|
182
|
+
logger.log('INFO', `[MetaExecutor] 📦 Fetched dependencies available: ${fetchedDepKeys.length > 0 ? fetchedDepKeys.join(', ') : 'NONE'}`);
|
|
183
|
+
|
|
180
184
|
const context = ContextFactory.buildMetaContext({
|
|
181
185
|
dateStr: dStr,
|
|
182
186
|
metadata: c,
|
|
@@ -197,7 +201,10 @@ class MetaExecutor {
|
|
|
197
201
|
});
|
|
198
202
|
|
|
199
203
|
// DEBUG: Log dependency availability
|
|
200
|
-
|
|
204
|
+
// CRITICAL: Use class.getDependencies() to get original case-sensitive names
|
|
205
|
+
const depNames = (c.class && typeof c.class.getDependencies === 'function')
|
|
206
|
+
? c.class.getDependencies()
|
|
207
|
+
: (c.getDependencies ? c.getDependencies() : (c.dependencies || []));
|
|
201
208
|
depNames.forEach(depName => {
|
|
202
209
|
const depData = context.computed[depName];
|
|
203
210
|
if (depData) {
|