create-yeow 0.2.43 → 0.2.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-yeow",
3
- "version": "0.2.43",
3
+ "version": "0.2.45",
4
4
  "description": "Scaffold a Yeow plugin project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,7 +48,7 @@ function startWebSocket() {
48
48
  if (msg.type === 'js-error') {
49
49
  await printFormattedError(msg);
50
50
  }
51
- } catch (e) { /* ignore parse errors */ }
51
+ } catch (e) { warn('Error processing message: ' + (e?.message || e)); }
52
52
  });
53
53
  ws.on('close', () => info('Java runtime disconnected'));
54
54
  });
@@ -157,6 +157,7 @@ function startHotReload() {
157
157
  codeFile: compiled.replace(/\\/g, '/'),
158
158
  assetsDir: existsSync(assetsDir) ? assetsDir.replace(/\\/g, '/') : null,
159
159
  });
160
+ _consumer = null; // invalidate stale source-map cache
160
161
  ok('Hot reload sent via WebSocket');
161
162
  }
162
163
  } catch (e) {
@@ -197,42 +198,52 @@ async function getSourceMapConsumer() {
197
198
  }
198
199
 
199
200
  async function printFormattedError(err) {
200
- const c = { r: '\x1b[0m', R: '\x1b[31m', Y: '\x1b[33m', C: '\x1b[36m', B: '\x1b[1m', D: '\x1b[2m' };
201
+ const c = { r: '\x1b[0m', R: '\x1b[31m', Y: '\x1b[33m', C: '\x1b[36m', B: '\x1b[1m', D: '\x1b[2m', g: '\x1b[32m' };
201
202
  let out = `\n${c.R}${c.B} JS Error [${err.plugin}]${c.r}\n`;
202
203
  if (err.context) out += ` ${c.D}context: ${err.context}${c.r}\n`;
203
204
  out += ` ${c.Y}${err.message}${c.r}\n`;
204
205
 
205
- const consumer = (err.fileName === 'main.js' || err.stack) ? await getSourceMapConsumer() : null;
206
- if (!consumer) {
207
- if (err.stack) err.stack.split('\n').slice(0, 5).forEach(l => { out += ` ${c.D} ${l.trim()}${c.r}\n`; });
208
- console.log(out);
209
- return;
206
+ // Check if stack contains any main.js frames if so, load source-map consumer
207
+ const hasMainJs = err.stack?.match(/main\.js:\d+:\d+/) || err.fileName === 'main.js';
208
+ let consumer = null;
209
+ if (hasMainJs) {
210
+ consumer = await getSourceMapConsumer();
211
+ }
212
+ if (hasMainJs && !consumer) {
213
+ const mapFile = resolve(ROOT, 'dist', '.yeow', 'main.js.map');
214
+ out += ` ${c.D}(source-map not found: ${existsSync(mapFile) ? 'exists but failed to parse' : 'missing at ' + mapFile})${c.r}\n`;
210
215
  }
211
216
 
212
217
  // Resolve all stack frames
213
218
  const frames = [];
214
219
  if (err.stack) {
215
- for (const line of err.stack.split('\n')) {
216
- const m = line.match(/at\s+(?:\S+\s+)?\(?(?:\/main\.js|[^:]+):(\d+):(\d+)\)?/);
217
- if (m) {
220
+ for (const rawLine of err.stack.split('\n')) {
221
+ const m = rawLine.match(/at\s+(?:\S+\s+)?\(?main\.js:(\d+):(\d+)\)?/);
222
+ if (m && consumer) {
218
223
  const orig = consumer.originalPositionFor({ line: parseInt(m[1]), column: parseInt(m[2]) });
219
- frames.push({ orig, raw: line });
224
+ if (!orig?.source) {
225
+ // Try adjusted column
226
+ const orig2 = consumer.originalPositionFor({ line: parseInt(m[1]), column: parseInt(m[2]) - 1 });
227
+ if (orig2?.source) { orig.source = orig2.source; orig.line = orig2.line; orig.column = orig2.column; }
228
+ }
229
+ frames.push({ orig, raw: rawLine });
220
230
  } else {
221
- frames.push({ raw: line });
231
+ frames.push({ raw: rawLine });
222
232
  }
223
233
  }
224
234
  }
225
235
 
226
236
  // Find first frame from user's src/ directory (not node_modules)
227
237
  let ctxFrame = frames.find(f => f.orig?.source?.match(/[\\/]src[\\/]/) && !f.orig.source.includes('node_modules'))?.orig || null;
228
- if (!ctxFrame && err.lineNumber > 0) {
229
- ctxFrame = consumer.originalPositionFor({ line: err.lineNumber, column: err.columnNumber || 0 });
230
- }
231
238
 
232
239
  // Show context for the chosen frame
233
- if (ctxFrame?.source && ctxFrame.line) {
240
+ if (ctxFrame?.source && ctxFrame.line && consumer) {
234
241
  const srcPath = ctxFrame.source.replace(/^\.\.\/\.\.\//, '');
235
- out += ` ${c.C}at ${srcPath}:${ctxFrame.line}:${ctxFrame.column}${c.r}\n`;
242
+ // Preserve function name
243
+ const ctxRaw = frames.find(f => f.orig === ctxFrame)?.raw || '';
244
+ const fnM = ctxRaw.match(/at\s+(\S+)\s+\(/);
245
+ const fnS = fnM ? fnM[1] + ' ' : '';
246
+ out += ` ${c.C}at ${fnS}(${srcPath}:${ctxFrame.line}:${ctxFrame.column})${c.r}\n`;
236
247
  const content = consumer.sourceContentFor(ctxFrame.source);
237
248
  if (content) {
238
249
  const lines = content.split('\n');
@@ -257,9 +268,14 @@ async function printFormattedError(err) {
257
268
  for (const f of frames) {
258
269
  if (f.orig?.source) {
259
270
  const srcPath = f.orig.source.replace(/^\.\.\/\.\.\//, '');
260
- out += ` ${c.D} at ${srcPath}:${f.orig.line}:${f.orig.column}${c.r}\n`;
271
+ const fnMatch = f.raw.match(/at\s+(\S+)\s+\(/);
272
+ const fn = fnMatch ? fnMatch[1] + ' ' : '';
273
+ const isUser = srcPath.startsWith('src/');
274
+ const style = isUser ? c.B + c.g : c.D;
275
+ out += ` ${style} at ${fn}(${srcPath}:${f.orig.line}:${f.orig.column})${c.r}\n`;
261
276
  } else {
262
- out += ` ${c.D} ${f.raw}${c.r}\n`;
277
+ const internal = f.raw.includes('init.js') || f.raw.includes('unknown.js') ? ' (internal)' : '';
278
+ out += ` ${c.D} ${f.raw}${internal}${c.r}\n`;
263
279
  }
264
280
  }
265
281
  }
@@ -7,7 +7,7 @@
7
7
  "dev": "node .yeow/dev-server.js"
8
8
  },
9
9
  "dependencies": {
10
- "yeow-api": "^0.2.29",
10
+ "yeow-api": "^0.2.30",
11
11
  "yeow-utils": "^0.1.2"
12
12
  },
13
13
  "devDependencies": {