trickle-observe 0.2.65 → 0.2.67

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.
@@ -418,6 +418,48 @@ function transformCjsSource(source, filename, moduleName, env) {
418
418
  continue;
419
419
  insertions.push({ position: closeBrace + 1, name, paramNames });
420
420
  }
421
+ // Find class declarations and wrap their methods
422
+ const classRegex = /^[ \t]*class\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(?:extends\s+[a-zA-Z_$.]+\s*)?\{/gm;
423
+ const classInsertions = [];
424
+ let classMatch;
425
+ while ((classMatch = classRegex.exec(source)) !== null) {
426
+ const className = classMatch[1];
427
+ const classOpenBrace = source.indexOf('{', classMatch.index + classMatch[0].length - 1);
428
+ if (classOpenBrace === -1)
429
+ continue;
430
+ const classCloseBrace = findClosingBrace(source, classOpenBrace);
431
+ if (classCloseBrace === -1)
432
+ continue;
433
+ // Extract methods from the class body
434
+ const classBody = source.slice(classOpenBrace + 1, classCloseBrace);
435
+ // Match: methodName(params) { or async methodName(params) { or static methodName(params) {
436
+ const methodRegex = /^[ \t]*(static\s+)?(?:async\s+)?([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(([^)]*)\)\s*\{/gm;
437
+ let methodMatch;
438
+ while ((methodMatch = methodRegex.exec(classBody)) !== null) {
439
+ const isStatic = !!methodMatch[1];
440
+ const methodName = methodMatch[2];
441
+ // Skip constructor and private methods
442
+ if (methodName === 'constructor' || methodName.startsWith('_'))
443
+ continue;
444
+ // Extract param names
445
+ const mParamStr = methodMatch[3].trim();
446
+ const mParamNames = mParamStr
447
+ ? mParamStr.split(',').map((p) => {
448
+ const trimmed = p.trim().split('=')[0].trim().split(':')[0].trim();
449
+ if (trimmed.startsWith('{') || trimmed.startsWith('[') || trimmed.startsWith('...'))
450
+ return '';
451
+ return trimmed;
452
+ }).filter(Boolean)
453
+ : [];
454
+ const target = isStatic ? className : `${className}.prototype`;
455
+ const obsName = `${className}.${methodName}`;
456
+ const paramNamesArg = mParamNames.length > 0 ? JSON.stringify(mParamNames) : 'null';
457
+ classInsertions.push({
458
+ position: classCloseBrace + 1,
459
+ code: `\ntry{${target}.${methodName}=__trickle_wrap(${target}.${methodName},'${obsName}',${paramNamesArg})}catch(__e){}\n`,
460
+ });
461
+ }
462
+ }
421
463
  // Also find variable declarations for tracing
422
464
  const varTraceEnabled = process.env.TRICKLE_TRACE_VARS !== '0';
423
465
  // For TypeScript files (compiled by ts-node/tsc), type declarations (interfaces, type aliases)
@@ -496,7 +538,7 @@ function transformCjsSource(source, filename, moduleName, env) {
496
538
  destructInsertions = findDestructuredDeclarations(source);
497
539
  }
498
540
  }
499
- if (insertions.length === 0 && varInsertions.length === 0 && destructInsertions.length === 0)
541
+ if (insertions.length === 0 && varInsertions.length === 0 && destructInsertions.length === 0 && classInsertions.length === 0)
500
542
  return source;
501
543
  // Resolve the path to the wrap helper (compiled JS)
502
544
  const wrapHelperPath = path_1.default.join(__dirname, 'wrap.js');
@@ -546,6 +588,10 @@ function transformCjsSource(source, filename, moduleName, env) {
546
588
  code: `\n;try{${calls}}catch(__e){}\n`,
547
589
  });
548
590
  }
591
+ // Add class method wrappings
592
+ for (const ci of classInsertions) {
593
+ allInsertions.push(ci);
594
+ }
549
595
  // Sort by position descending (insert from end to preserve earlier positions)
550
596
  allInsertions.sort((a, b) => b.position - a.position);
551
597
  let result = source;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trickle-observe",
3
- "version": "0.2.65",
3
+ "version": "0.2.67",
4
4
  "description": "Runtime type observability for JavaScript applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -389,6 +389,46 @@ function transformCjsSource(source: string, filename: string, moduleName: string
389
389
  insertions.push({ position: closeBrace + 1, name, paramNames });
390
390
  }
391
391
 
392
+ // Find class declarations and wrap their methods
393
+ const classRegex = /^[ \t]*class\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(?:extends\s+[a-zA-Z_$.]+\s*)?\{/gm;
394
+ const classInsertions: Array<{ position: number; code: string }> = [];
395
+ let classMatch;
396
+ while ((classMatch = classRegex.exec(source)) !== null) {
397
+ const className = classMatch[1];
398
+ const classOpenBrace = source.indexOf('{', classMatch.index + classMatch[0].length - 1);
399
+ if (classOpenBrace === -1) continue;
400
+ const classCloseBrace = findClosingBrace(source, classOpenBrace);
401
+ if (classCloseBrace === -1) continue;
402
+
403
+ // Extract methods from the class body
404
+ const classBody = source.slice(classOpenBrace + 1, classCloseBrace);
405
+ // Match: methodName(params) { or async methodName(params) { or static methodName(params) {
406
+ const methodRegex = /^[ \t]*(static\s+)?(?:async\s+)?([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(([^)]*)\)\s*\{/gm;
407
+ let methodMatch;
408
+ while ((methodMatch = methodRegex.exec(classBody)) !== null) {
409
+ const isStatic = !!methodMatch[1];
410
+ const methodName = methodMatch[2];
411
+ // Skip constructor and private methods
412
+ if (methodName === 'constructor' || methodName.startsWith('_')) continue;
413
+ // Extract param names
414
+ const mParamStr = methodMatch[3].trim();
415
+ const mParamNames = mParamStr
416
+ ? mParamStr.split(',').map((p: string) => {
417
+ const trimmed = p.trim().split('=')[0].trim().split(':')[0].trim();
418
+ if (trimmed.startsWith('{') || trimmed.startsWith('[') || trimmed.startsWith('...')) return '';
419
+ return trimmed;
420
+ }).filter(Boolean)
421
+ : [];
422
+ const target = isStatic ? className : `${className}.prototype`;
423
+ const obsName = `${className}.${methodName}`;
424
+ const paramNamesArg = mParamNames.length > 0 ? JSON.stringify(mParamNames) : 'null';
425
+ classInsertions.push({
426
+ position: classCloseBrace + 1,
427
+ code: `\ntry{${target}.${methodName}=__trickle_wrap(${target}.${methodName},'${obsName}',${paramNamesArg})}catch(__e){}\n`,
428
+ });
429
+ }
430
+ }
431
+
392
432
  // Also find variable declarations for tracing
393
433
  const varTraceEnabled = process.env.TRICKLE_TRACE_VARS !== '0';
394
434
 
@@ -468,7 +508,7 @@ function transformCjsSource(source: string, filename: string, moduleName: string
468
508
  }
469
509
  }
470
510
 
471
- if (insertions.length === 0 && varInsertions.length === 0 && destructInsertions.length === 0) return source;
511
+ if (insertions.length === 0 && varInsertions.length === 0 && destructInsertions.length === 0 && classInsertions.length === 0) return source;
472
512
 
473
513
  // Resolve the path to the wrap helper (compiled JS)
474
514
  const wrapHelperPath = path.join(__dirname, 'wrap.js');
@@ -531,6 +571,11 @@ function transformCjsSource(source: string, filename: string, moduleName: string
531
571
  });
532
572
  }
533
573
 
574
+ // Add class method wrappings
575
+ for (const ci of classInsertions) {
576
+ allInsertions.push(ci);
577
+ }
578
+
534
579
  // Sort by position descending (insert from end to preserve earlier positions)
535
580
  allInsertions.sort((a, b) => b.position - a.position);
536
581