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
- return fetchDependencies(dateObj, calcs, config, deps, manifestLookup, isHistoricalContext);
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
- const reqs = (typeof c.getDependencies === 'function')
84
- ? c.getDependencies()
85
- : (c.dependencies || []);
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) return {};
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
- const depNames = c.getDependencies ? c.getDependencies() : (c.dependencies || []);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.649",
3
+ "version": "1.0.651",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [