npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@xcons/common

v3.0.1

Published

XCons Common Package - Shared utilities and logger system for XCons ecosystem

Readme

@xcons/common

Shared utilities and logger system for XCons ecosystem with global package-based logging control

npm version License: MIT

🚀 Quick Start

Basic HTML Usage (Recommended)

<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
    
    <!-- STEP 1: Define global configuration BEFORE loading the package -->
    <script>
        window.__XCONS_LOGGER_CONFIG__ = {
            '@xcons/widget': {
                enabled: true,
                level: 3,  // DEBUG level (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG, 4=TRACE)
                prefix: 'WIDGET',
                timestamp: true,
                colors: true
            },
            '@xcons/grid': {
                enabled: true,
                level: 2  // INFO level
            },
            '@xcons/datasource': {
                enabled: false  // Completely disabled
            }
        };
    </script>
    
    <!-- STEP 2: Load the package -->
    <script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>
<body>
    <script>
        // STEP 3: Use the logger
        const { logger, ComponentLogLevel } = XConsCommon;
        
        const myLogger = logger.createChild(
            '@xcons/widget',
            'MY-COMPONENT',
            ComponentLogLevel.BASIC
        );
        
        myLogger.info('Application started!');
        myLogger.debug('Debug information');
    </script>
</body>
</html>

NPM/Node.js Usage

npm install @xcons/common
import { logger, LoggerRegistry, LoggerLogLevel } from '@xcons/common';

// Configure package logging
LoggerRegistry.registerPackage('@xcons/widget', {
    enabled: true,
    level: LoggerLogLevel.DEBUG
});

// Create and use logger
const widgetLogger = logger.createChild('@xcons/widget', 'CORE');
widgetLogger.info('Widget initialized!');

✨ Features

  • 🌐 Global Configuration - Set logging rules before any code loads
  • 🔒 Protected Settings - Global config cannot be overridden (unless forced)
  • 📦 Package-based Control - Enable/disable logging per package
  • 🎯 TypeScript - Full TypeScript support
  • 🚀 Universal - Works in browser and Node.js
  • 🔧 Child Loggers - Component-specific logging with namespace
  • Lightweight - Minimal dependencies
  • 🎨 Configurable - Per-package log levels and settings

📋 Installation

Via CDN (Browser)

<!-- Latest version -->
<script src="https://unpkg.com/@xcons/common@latest/core.js"></script>

<!-- Specific version -->
<script src="https://unpkg.com/@xcons/[email protected]/core.js"></script>

<!-- ES Module -->
<script type="module">
    import { logger } from 'https://unpkg.com/@xcons/common@latest/core.js';
    logger.info('Hello from ES Module!');
</script>

Via NPM

# npm
npm install @xcons/common

# yarn
yarn add @xcons/common

# pnpm
pnpm add @xcons/common

🔧 Global Configuration (Priority System)

⚠️ Priority Rules

CRITICAL: Global configuration ALWAYS has the highest priority!

Priority Order (Highest to Lowest):
1. ✅ Global config (window.__XCONS_LOGGER_CONFIG__) - CANNOT BE OVERRIDDEN
2. ✅ Package registration - Merged with global config
3. ✅ Runtime updates - Cannot override global (unless force: true)

Setting Global Configuration

Method 1: HTML (Before Package Load)

<!DOCTYPE html>
<html>
<head>
    <!-- Define BEFORE loading @xcons/common -->
    <script>
        window.__XCONS_LOGGER_CONFIG__ = {
            '@xcons/widget': {
                enabled: true,
                level: 3,        // DEBUG (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG, 4=TRACE)
                prefix: 'WIDGET',
                timestamp: true,
                colors: true
            },
            '@xcons/grid': {
                enabled: true,
                level: 2         // INFO
            },
            '@xcons/datasource': {
                enabled: false   // Completely off
            }
        };
    </script>
    
    <!-- Now load the package -->
    <script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>

Method 2: Programmatic (Runtime)

import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';

// Set global configuration
LoggerRegistry.setGlobalConfig({
    '@xcons/widget': {
        enabled: true,
        level: LoggerLogLevel.DEBUG,
        prefix: 'WIDGET'
    },
    '@xcons/grid': {
        enabled: false
    }
});

// This will automatically reload and apply to all packages

Log Levels Reference

LoggerLogLevel.ERROR   // 0 - Only errors
LoggerLogLevel.WARN    // 1 - Errors + warnings
LoggerLogLevel.INFO    // 2 - Errors + warnings + info
LoggerLogLevel.DEBUG   // 3 - All above + debug
LoggerLogLevel.TRACE   // 4 - Most detailed logs

Configuration Options

interface LoggerConfig {
    enabled: boolean;      // Enable/disable logging
    level: LoggerLogLevel; // Minimum log level (0-4)
    prefix: string;        // Log prefix (e.g., 'WIDGET')
    timestamp: boolean;    // Show timestamps
    colors: boolean;       // Enable colored output
}

📦 Package-based Logging

Register Packages

import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';

// Enable detailed logging for widgets
LoggerRegistry.registerPackage('@xcons/widget', {
    enabled: true,
    level: LoggerLogLevel.DEBUG,
    prefix: 'WIDGET'
});

// Disable grid logging in production
LoggerRegistry.registerPackage('@xcons/grid', {
    enabled: false,
    level: LoggerLogLevel.ERROR
});

// Only errors and warnings for datasource
LoggerRegistry.registerPackage('@xcons/datasource', {
    enabled: true,
    level: LoggerLogLevel.WARN
});

Use Package Loggers

import { logger, ComponentLogLevel } from '@xcons/common';

// Create logger for @xcons/widget package
const widgetLogger = logger.createChild(
    '@xcons/widget',              // package namespace
    'WIDGET-DECORATOR',           // component name
    ComponentLogLevel.DETAILED    // component log level
);

// Logs respect package configuration
widgetLogger.info('Widget created');
widgetLogger.debug('Configuration loaded', { config });
widgetLogger.trace('Detailed trace'); // Only if DETAILED level

Dynamic Configuration

// Standard update (respects global config)
LoggerRegistry.updatePackage('@xcons/grid', {
    enabled: true,
    level: LoggerLogLevel.INFO
});
// ⚠️ If global config exists, it will be preserved

// Force update (override global config)
LoggerRegistry.updatePackage('@xcons/grid', {
    enabled: true,
    level: LoggerLogLevel.INFO
}, true);  // force=true
// ✅ This will override global config

// Check if package has global protection
if (LoggerRegistry.hasGlobalConfig('@xcons/widget')) {
    console.log('Widget is protected by global config');
}

// Get global config for specific package
const globalConfig = LoggerRegistry.getGlobalPackageConfig('@xcons/widget');

// Clear global protection
LoggerRegistry.clearGlobalConfig('@xcons/widget');
// Now package can be freely configured

// Check registration
if (LoggerRegistry.hasPackage('@xcons/widget')) {
    console.log('Widget package registered');
}

// Get package config
const config = LoggerRegistry.getPackageConfig('@xcons/widget');

// List all packages
const packages = LoggerRegistry.getRegisteredPackages();

// Get all configs
const allConfigs = LoggerRegistry.getAllConfigs();

🎯 Basic Usage

Simple Logging

import { logger } from '@xcons/common';

logger.info('Application started');
logger.warn('Warning message');
logger.error('Error occurred', error);
logger.debug('Debug data', { userId: 123 });

Child Loggers

// Without package (uses parent config)
const simpleLogger = logger.createChild('MyComponent');

// With package namespace
const packageLogger = logger.createChild('@xcons/widget', 'CORE');

// With component log level
const detailedLogger = logger.createChild(
    '@xcons/widget',
    'UI',
    ComponentLogLevel.DETAILED
);

Component Log Levels

import { ComponentLogLevel } from '@xcons/common';

ComponentLogLevel.OFF       // 0 - No component logging
ComponentLogLevel.BASIC     // 1 - Basic component logs
ComponentLogLevel.DETAILED  // 2 - Detailed component logs

🔥 Advanced Features

Performance Timing

const perfLogger = logger.createChild('@xcons/widget', 'PERF');

perfLogger.time('render');
// ... render logic
perfLogger.timeEnd('render'); // Logs: [@xcons/widget:PERF] render: 45.2ms

Table Logging

const dataLogger = logger.createChild('@xcons/datasource', 'LOADER');

dataLogger.table([
    { id: 1, name: 'Item A', status: 'active' },
    { id: 2, name: 'Item B', status: 'inactive' }
]);

Grouped Logging

const widgetLogger = logger.createChild('@xcons/widget', 'MANAGER');

widgetLogger.group('Widget Initialization');
widgetLogger.info('Loading configuration');
widgetLogger.debug('Parsing options');
widgetLogger.groupEnd();

🌍 Environment Setup

Development Environment

import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';

// Development - verbose logging
LoggerRegistry.registerPackage('@xcons/widget', {
    enabled: true,
    level: LoggerLogLevel.TRACE,
    colors: true,
    timestamp: true
});

LoggerRegistry.registerPackage('@xcons/grid', {
    enabled: true,
    level: LoggerLogLevel.DEBUG
});

Production Environment

// Production - minimal logging
LoggerRegistry.registerPackage('@xcons/widget', {
    enabled: true,
    level: LoggerLogLevel.WARN,  // Only warnings and errors
    colors: false
});

LoggerRegistry.registerPackage('@xcons/grid', {
    enabled: false  // Completely disabled
});

Environment-based Configuration

<script>
    // Detect environment
    const isDev = window.location.hostname === 'localhost' || 
                  window.location.hostname === '127.0.0.1';
    
    // Set configuration based on environment
    window.__XCONS_LOGGER_CONFIG__ = isDev ? {
        // Development settings
        '@xcons/widget': { enabled: true, level: 3 },
        '@xcons/grid': { enabled: true, level: 3 },
        '@xcons/datasource': { enabled: true, level: 3 }
    } : {
        // Production settings
        '@xcons/widget': { enabled: true, level: 1 },
        '@xcons/grid': { enabled: false, level: 0 },
        '@xcons/datasource': { enabled: false, level: 0 }
    };
</script>

💼 Real-world Example

import { 
    logger, 
    LoggerRegistry, 
    LoggerLogLevel,
    ComponentLogLevel 
} from '@xcons/common';

// Register package with global config
LoggerRegistry.registerPackage('@xcons/widget', {
    enabled: true,
    level: LoggerLogLevel.DEBUG
});

// Widget class with package logger
export class Widget {
    private logger = logger.createChild(
        '@xcons/widget',
        'WIDGET-CORE',
        ComponentLogLevel.BASIC
    );

    constructor(private id: string) {
        this.logger.info('Widget created', { id });
    }

    async initialize() {
        this.logger.debug('Initializing widget');
        
        this.logger.time('init');
        try {
            await this.loadConfig();
            await this.setupUI();
            this.logger.info('Widget ready');
        } catch (error) {
            this.logger.error('Initialization failed', error);
            throw error;
        } finally {
            this.logger.timeEnd('init');
        }
    }

    private async loadConfig() {
        this.logger.debug('Loading configuration');
        // Config loading logic
    }

    private async setupUI() {
        this.logger.debug('Setting up UI');
        // UI setup logic
    }
}

// Usage
const widget = new Widget('my-widget-1');
await widget.initialize();

🔍 Debugging & Global Access

Browser Console

// Access logger registry
window.__XCONS_LOGGER_REGISTRY__

// View all package configs
LoggerRegistry.getAllConfigs()

// View global config
LoggerRegistry.getGlobalConfigSnapshot()

// Enable package on-the-fly (if not protected)
LoggerRegistry.updatePackage('@xcons/grid', { 
    enabled: true,
    level: 3 
})

// Force enable (override global config)
LoggerRegistry.updatePackage('@xcons/grid', { 
    enabled: true,
    level: 3 
}, true)

// List registered packages
LoggerRegistry.getRegisteredPackages()

// Check global protection
LoggerRegistry.hasGlobalConfig('@xcons/widget')

// Clear global protection
LoggerRegistry.clearGlobalConfig('@xcons/widget')

Node.js

// Access global logger
global.__XCONS_LOGGER_REGISTRY__

📚 Complete HTML Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>XCons Common - Complete Example</title>
    
    <!-- STEP 1: Global Configuration -->
    <script>
        // Environment detection
        const isDev = location.hostname === 'localhost';
        
        // Global logger configuration
        window.__XCONS_LOGGER_CONFIG__ = {
            '@xcons/widget': {
                enabled: true,
                level: isDev ? 3 : 1,  // DEBUG in dev, WARN in prod
                prefix: 'WIDGET',
                timestamp: true,
                colors: true
            },
            '@xcons/grid': {
                enabled: isDev,  // Only in development
                level: 3,
                prefix: 'GRID'
            },
            '@xcons/datasource': {
                enabled: true,
                level: 2,  // INFO level
                prefix: 'DS'
            }
        };
    </script>
    
    <!-- STEP 2: Load Package -->
    <script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>
<body>
    <h1>XCons Common Logger Example</h1>
    <button onclick="testLogs()">Test Logs</button>
    <button onclick="showConfigs()">Show Configs</button>
    
    <script>
        // STEP 3: Import and Use
        const { 
            logger, 
            LoggerRegistry,
            LoggerLogLevel,
            ComponentLogLevel 
        } = XConsCommon;
        
        // Create loggers for different packages
        const widgetLogger = logger.createChild(
            '@xcons/widget',
            'UI-COMPONENT',
            ComponentLogLevel.BASIC
        );
        
        const gridLogger = logger.createChild(
            '@xcons/grid',
            'DATA-GRID',
            ComponentLogLevel.DETAILED
        );
        
        const dsLogger = logger.createChild(
            '@xcons/datasource',
            'API-CLIENT'
        );
        
        // Test function
        function testLogs() {
            console.clear();
            
            // Widget logs (level: WARN in prod, DEBUG in dev)
            widgetLogger.error('Widget error message');
            widgetLogger.warn('Widget warning message');
            widgetLogger.info('Widget info message');
            widgetLogger.debug('Widget debug message');
            
            // Grid logs (disabled in production)
            gridLogger.info('Grid initialized');
            gridLogger.debug('Grid rendering data');
            
            // Datasource logs (INFO level)
            dsLogger.info('Fetching data from API');
            dsLogger.debug('API response received');
        }
        
        // Show configurations
        function showConfigs() {
            console.group('📋 Logger Configurations');
            
            console.log('Global Config:', 
                LoggerRegistry.getGlobalConfigSnapshot());
            
            console.log('All Configs:', 
                LoggerRegistry.getAllConfigs());
            
            console.log('Registered Packages:', 
                LoggerRegistry.getRegisteredPackages());
            
            console.groupEnd();
        }
        
        // Auto-run on load
        window.addEventListener('load', () => {
            widgetLogger.info('Application loaded successfully! 🎉');
            showConfigs();
        });
    </script>
</body>
</html>

📖 API Reference

LoggerRegistry

| Method | Description | |--------|-------------| | setGlobalConfig(config) | Set global configuration programmatically | | getGlobalConfigSnapshot() | Get current global configuration | | registerPackage(name, config, force?) | Register package with config | | getPackageConfig(name) | Get package configuration | | hasPackage(name) | Check if package is registered | | hasGlobalConfig(name) | Check if package has global protection | | getGlobalPackageConfig(name) | Get global config for specific package | | clearGlobalConfig(name) | Clear global protection for package | | clearAllGlobalConfigs() | Clear all global protections | | unregisterPackage(name) | Remove package from registry | | updatePackage(name, config, force?) | Update package configuration | | getRegisteredPackages() | Get all registered packages | | getAllConfigs() | Get all package configs | | reloadFromGlobal() | Reload from global config | | clear() | Clear all packages |

CoreLogger

| Method | Description | |--------|-------------| | createChild(namespace, component?, level?) | Create child logger with package support | | configure(config) | Update logger configuration | | setLevel(level) | Set minimum log level | | enable() / disable() | Enable/disable logging | | getConfig() | Get current configuration |

ChildLogger

| Method | Description | |--------|-------------| | info(message, ...data) | Info level logging | | warn(message, ...data) | Warning level logging | | error(message, ...data) | Error level logging | | debug(message, ...data) | Debug level logging | | trace(message, ...data) | Trace level logging | | group(title) / groupEnd() | Group related logs | | time(label) / timeEnd(label) | Measure execution time | | table(data) | Display data in table format | | getNamespace() | Get package namespace | | getComponentName() | Get component name |

🌐 Browser Support

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

🔧 Node.js Support

  • Node.js 16+

📄 License

MIT © XCon Studio

🔗 Links

🤝 Contributing

Contributions, issues and feature requests are welcome!

⭐ Support

Give a ⭐️ if this project helped you!


Made with ❤️ by XCon Studio