npm package: @gl-life/gl-life-core
Description: Foundation package for GoodLife Sargam providing shared TypeScript types, utilities, error handling, logger, event bus, and configuration management
Author: GL.Life
Latest version: 1.0.1

# @gl-life/gl-life-core

[![npm version](https://img.shields.io/npm/v/@gl-life/gl-life-core.svg)](https://www.npmjs.com/package/@gl-life/gl-life-core)
[![License](https://img.shields.io/npm/l/@gl-life/gl-life-core.svg)](https://www.npmjs.com/package/@gl-life/gl-life-core)

Foundation package for GoodLife Sargam - Production-ready TypeScript utilities for error handling, logging, configuration, and more.

## Features

- 🔒 **Type-Safe Error Handling** - Result and Option types for safe error handling
- 📝 **Structured Logging** - JSON logging with context and levels
- 🎯 **Event System** - Type-safe pub/sub with async support
- ⚙️ **Configuration Management** - Environment variables with Zod validation
- 🛠️ **Utilities** - Deep cloning, debounce, throttle, retry, validators
- ✅ **100% TypeScript** - Full type safety and IntelliSense support
- 📦 **Dual Exports** - ESM and CommonJS support
- 🧪 **Well-Tested** - Comprehensive test coverage

## Installation

```bash
npm install @gl-life/gl-life-core
```

```bash
yarn add @gl-life/gl-life-core
```

```bash
pnpm add @gl-life/gl-life-core
```

## Quick Start

```typescript
import {
  Result,
  Logger,
  LogLevel,
  Config,
  EventBus,
  deepClone,
} from '@gl-life/gl-life-core';

// Safe error handling with Result type
const divide = (a: number, b: number): Result<number, string> => {
  if (b === 0) {
    return Result.err('Division by zero');
  }
  return Result.ok(a / b);
};

const result = divide(10, 2);
if (result.isOk()) {
  console.log('Result:', result.unwrap()); // 5
}

// Structured logging
const logger = new Logger({ level: LogLevel.INFO });
logger.info('Application started', { version: '1.0.0' });

// Event bus
const eventBus = new EventBus();
eventBus.subscribe('user:login', (data) => {
  console.log('User logged in:', data);
});
await eventBus.emit('user:login', { userId: 123 });

// Configuration with validation
import { z } from 'zod';

const schema = z.object({
  PORT: z.number().default(3000),
  HOST: z.string().default('localhost'),
});

const config = new Config({
  schema,
  envPrefix: 'APP_',
});

console.log(config.get('PORT')); // From APP_PORT env or default 3000
```

## Core Types

### Result<T, E>

Type-safe error handling without exceptions.

```typescript
import { Result } from '@gl-life/gl-life-core';

// Create results
const success = Result.ok(42);
const failure = Result.err('Something went wrong');

// Check result
if (success.isOk()) {
  console.log(success.unwrap()); // 42
}

// Transform with map
const doubled = success.map(x => x * 2); // Ok(84)

// Chain operations
const result = Result.ok(10)
  .map(x => x * 2)
  .flatMap(x => x > 15 ? Result.ok(x) : Result.err('Too small'));

// Safe unwrapping
const value = result.unwrapOr(0); // Get value or default
```

### Option<T>

Handle nullable values safely.

```typescript
import { Option } from '@gl-life/gl-life-core';

// Create options
const some = Option.some(42);
const none = Option.none<number>();

// From nullable
const opt = Option.fromNullable(maybeNull);

// Transform
const doubled = some.map(x => x * 2); // Some(84)

// Filter
const filtered = some.filter(x => x > 40); // Some(42)

// Chain
const result = some
  .map(x => x * 2)
  .flatMap(x => x > 50 ? Option.some(x) : Option.none());

// Safe unwrapping
const value = result.unwrapOr(0);
```

## Error Handling

Specialized error classes with serialization support.

```typescript
import {
  AppError,
  ValidationError,
  DatabaseError,
  AuthError,
  NetworkError,
} from '@gl-life/gl-life-core';

// Base error
throw new AppError('USER_NOT_FOUND', 'User does not exist', {
  userId: 123,
});

// Validation error
throw new ValidationError(
  'INVALID_EMAIL',
  'Email format is invalid',
  { field: 'email', value: 'bad-email', constraint: 'format' }
);

// Database error
throw new DatabaseError(
  'QUERY_FAILED',
  'Failed to execute query',
  { query: 'SELECT * FROM users', table: 'users' }
);

// Auth error
throw new AuthError(
  'TOKEN_EXPIRED',
  'Authentication token has expired',
  { userId: '123', tokenType: 'JWT', reason: 'expired' }
);

// Network error
throw new NetworkError(
  'REQUEST_FAILED',
  'HTTP request failed',
  { statusCode: 404, url: 'https://api.example.com', method: 'GET' }
);

// Serialization
const error = new ValidationError('ERROR_CODE', 'Message');
const json = error.toJSON();
const restored = AppError.fromJSON(json);
```

## Logging

Structured JSON logging with context and levels.

```typescript
import { Logger, LogLevel } from '@gl-life/gl-life-core';

// Create logger
const logger = new Logger({
  level: LogLevel.INFO,
  context: { service: 'api', version: '1.0.0' },
});

// Log at different levels
logger.debug('Debug message', { details: 'extra info' });
logger.info('User logged in', { userId: 123 });
logger.warn('Rate limit approaching', { requests: 950 });
logger.error('Database connection failed', { error: 'timeout' });

// Child logger with additional context
const requestLogger = logger.createChild({
  requestId: 'abc-123',
  method: 'GET',
  path: '/api/users',
});

requestLogger.info('Request received'); // Includes parent + child context

// Output format (JSON)
// {
//   "timestamp": "2024-01-01T12:00:00.000Z",
//   "level": "info",
//   "message": "Request received",
//   "service": "api",
//   "version": "1.0.0",
//   "requestId": "abc-123",
//   "method": "GET",
//   "path": "/api/users"
// }
```

## Event Bus

Type-safe publish-subscribe event system.

```typescript
import { EventBus } from '@gl-life/gl-life-core';

const eventBus = new EventBus();

// Subscribe to events
const unsubscribe = eventBus.subscribe('user:login', (data) => {
  console.log('User logged in:', data.userId);
});

// Wildcard subscriptions
eventBus.subscribe('*', (data) => {
  console.log('Any event:', data);
});

// Emit events (async with error collection)
const errors = await eventBus.emit('user:login', {
  userId: 123,
  timestamp: new Date(),
});

// Unsubscribe
unsubscribe();
// or
eventBus.unsubscribe('user:login', handler);

// Management
eventBus.listenerCount('user:login'); // Number of handlers
eventBus.eventNames(); // All event names
eventBus.clear(); // Remove all handlers
eventBus.clear('user:login'); // Remove handlers for specific event
```

## Configuration

Configuration management with environment variables and Zod validation.

```typescript
import { Config } from '@gl-life/gl-life-core';
import { z } from 'zod';

// Define schema
const schema = z.object({
  PORT: z.number().min(1).max(65535).default(3000),
  HOST: z.string().default('localhost'),
  DATABASE_URL: z.string().url(),
  DEBUG: z.boolean().default(false),
});

// Create config
const config = new Config({
  schema,
  envPrefix: 'APP_', // Loads from APP_PORT, APP_HOST, etc.
  defaults: { DEBUG: true }, // Override schema defaults
});

// Get values (type-safe with generics)
const port = config.get<number>('PORT'); // 3000 or from APP_PORT
const host = config.get('HOST', 'default-host'); // With fallback

// Set values (validated against schema)
config.set('PORT', 8080);

// Check existence
if (config.has('DATABASE_URL')) {
  // ...
}

// Get all config
const allConfig = config.getAll();

// Delete and clear
config.delete('PORT'); // Returns `this` for chaining
config.clear();

// Type conversion from environment
// APP_PORT=8080 → number
// APP_DEBUG=true → boolean
// APP_CONFIG='{"key":"value"}' → object
```

## Utilities

### Deep Clone

Clone objects with circular reference handling.

```typescript
import { deepClone } from '@gl-life/gl-life-core';

const original = {
  date: new Date(),
  regex: /test/i,
  map: new Map([['key', 'value']]),
  set: new Set([1, 2, 3]),
  nested: { deep: { value: 42 } },
};

// Handle circular references
original.self = original;

const cloned = deepClone(original);
// cloned is a deep copy, cloned.self === cloned
```

### Debounce

Delay function execution until after a wait period.

```typescript
import { debounce } from '@gl-life/gl-life-core';

const search = debounce((query: string) => {
  console.log('Searching for:', query);
}, 300);

search('a');
search('ab');
search('abc'); // Only this will execute after 300ms

// Cancel pending execution
search.cancel();
```

### Throttle

Limit function execution rate.

```typescript
import { throttle } from '@gl-life/gl-life-core';

const onScroll = throttle(() => {
  console.log('Scroll event');
}, 100);

window.addEventListener('scroll', onScroll);
// Executes at most once per 100ms
```

### Retry

Retry async operations with exponential backoff.

```typescript
import { retry } from '@gl-life/gl-life-core';

const fetchData = async () => {
  const response = await fetch('https://api.example.com/data');
  if (!response.ok) throw new Error('Fetch failed');
  return response.json();
};

// Retry up to 3 times with exponential backoff
const data = await retry(fetchData, {
  maxAttempts: 3,
  delay: 1000, // 1s, 2s, 3s between attempts
});
```

### Sleep

Promise-based delay.

```typescript
import { sleep } from '@gl-life/gl-life-core';

async function process() {
  console.log('Start');
  await sleep(1000); // Wait 1 second
  console.log('After 1 second');
}
```

### Validators

Email and URL validation.

```typescript
import { isEmail, isURL } from '@gl-life/gl-life-core';

// Email validation (RFC 5322 compliant)
isEmail('user@example.com'); // true
isEmail('invalid@'); // false

// URL validation (http/https only)
isURL('https://example.com'); // true
isURL('ftp://example.com'); // false
```

## API Reference

### Types

- `Result<T, E>` - Type-safe result type for operations that may fail
- `Option<T>` - Type for optional values

### Errors

- `AppError` - Base error class with code and metadata
- `ValidationError` - Validation failure errors
- `DatabaseError` - Database operation errors
- `AuthError` - Authentication/authorization errors
- `NetworkError` - Network request errors

### Services

- `Logger` - Structured JSON logging with levels and context
- `EventBus` - Publish-subscribe event system
- `Config` - Configuration management with validation

### Utilities

- `deepClone<T>(value: T): T` - Deep clone with circular references
- `debounce<T>(fn: T, wait: number): DebouncedFunction<T>` - Debounce function
- `throttle<T>(fn: T, wait: number): ThrottledFunction<T>` - Throttle function
- `retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>` - Retry with backoff
- `sleep(ms: number): Promise<void>` - Async delay
- `isEmail(email: string): boolean` - Email validator
- `isURL(url: string): boolean` - URL validator

## TypeScript Support

Full TypeScript support with comprehensive type definitions.

```typescript
import type {
  Result,
  Option,
  AppErrorJSON,
  LoggerOptions,
  EventHandler,
  ConfigOptions,
  RetryOptions,
} from '@gl-life/gl-life-core';
```

## Testing

The package includes comprehensive tests with high coverage:

```bash
npm test              # Run tests
npm run test:watch    # Watch mode
npm run test:coverage # Coverage report
```

## Support

For questions, issues, or feature requests, please contact us at [packages@gl.life](mailto:packages@gl.life).

Visit [gl.life](https://gl.life) for more information about GoodLife Sargam.

## License

Apache-2.0 © GoodLife

---

**Part of the GoodLife Sargam ecosystem**

For more information, visit [gl.life](https://gl.life).