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

@stardyn/angular-data-source

v2.0.13

Published

Angular Data Source Package - Lightweight, configurable HTTP data source service for Angular applications with authentication, filtering, and storage support

Readme

@stardyn/angular-data-source

Lightweight, configurable HTTP data source service for Angular applications with authentication, filtering, and storage support. Provides comprehensive API client functionality with automatic token refresh, request/response interceptors, and local storage management.

Features

  • HTTP Client Integration: Seamless integration with Axios HTTP client
  • Absolute URL Support: Support for both relative paths and absolute URLs
  • Authentication Support: Token-based authentication with automatic refresh
  • Request/Response Interceptors: Configurable interceptors for all HTTP requests
  • API Response Wrapper: Standardized response handling with ApiResponse class
  • Local Storage Service: Site-specific storage management with debugging
  • Advanced Filtering: Comprehensive filtering system with multiple operators
  • Pagination Support: Built-in pagination handling for data sources
  • Performance Focused: Zero overhead configuration with singleton patterns
  • Rich Logging: Debug mode with detailed logging for development
  • Production Ready: Automatically optimized for production environments

Installation

npm install @stardyn/angular-data-source

Prerequisites

This package requires Angular and RxJS:

npm install @angular/core @angular/common rxjs

Quick Start

1. App Module Configuration

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { provideXconDataSource } from '@stardyn/angular-data-source';

import { AppComponent } from './app.component';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    provideXconDataSource({
      apiUrl: environment.apiUrl,
      site_key: 'my-app',
      debugMode: !environment.production
    })
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

2. Standalone Application Configuration

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideXconDataSource } from '@stardyn/angular-data-source';

import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';

bootstrapApplication(AppComponent, {
  providers: [
    provideXconDataSource({
      apiUrl: environment.apiUrl,
      site_key: 'my-app',
      debugMode: !environment.production
    })
  ]
});

3. Service Usage

import { Component, OnInit } from '@angular/core';
import { DataSourceApi, StorageService } from '@stardyn/angular-data-source';

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ title }}</h1>
    <button (click)="loadData()">Load Data</button>
  `
})
export class AppComponent implements OnInit {
  title = 'My App with Data Source';

  constructor(
    private apiService: DataSourceApi,
    private storage: StorageService
  ) {}

  ngOnInit() {
    // Set authentication token
    const token = this.storage.get('auth_token', null);
    if (token) {
      this.apiService.getDataSource().tokenSet(token);
    }
  }

  async loadData() {
    try {
      const response = await this.apiService.get('/api/users');
      if (response.success) {
        console.log('Users loaded:', response.data);
      }
    } catch (error) {
      console.error('Failed to load users:', error);
    }
  }
}

API Reference

DataSource Configuration

interface XconDataSourceBasicConfig {
  apiUrl?: string;        // Base API URL
  site_key?: string;      // Site key for storage isolation
  debugMode?: boolean;    // Enable/disable debug logging
}

DataSourceWithRefresh Configuration

interface XconDataSourceConfig {
  apiUrl?: string;
  site_key?: string;
  debugMode?: boolean;
  refreshToken?: () => Promise<ApiResponse>;  // Token refresh callback
  onAuthFail?: () => void;                    // Authentication failure callback
}

DataSourceApi Methods

// HTTP Methods
async post(path: string, data: any): Promise<ApiResponse>
async get(path: string): Promise<ApiResponse>
async put(path: string, data: any): Promise<ApiResponse>
async del(path: string, data: any): Promise<ApiResponse>

// Utility Methods
getDataSource(): DataSource
isReady(): boolean

StorageService Methods

// Basic Storage Operations
set(key: string, value: any): void
get(key: string, defaultValue: any): any
remove(key: string): void
exists(key: string): boolean

// Advanced Operations
getKeys(): string[]
clear(): void                    // Clear site-specific data
clean(): void                   // Clear all localStorage
getStorageSize(): number
isStorageAvailable(): boolean

ApiResponse Class

class ApiResponse {
  code: number;           // HTTP status code
  data: any;             // Response data
  success: boolean;      // Success flag
  message: string;       // Response message
  dataItems: any;        // Items array for paginated responses
  dataItemCount: number; // Total item count

  static create(params: {
    success: boolean;
    data?: any;
    message?: string;
    code?: number;
  }): ApiResponse
}

Configuration Examples

Basic Configuration

provideXconDataSource({
  apiUrl: 'https://api.example.com',
  site_key: 'my-app',
  debugMode: true
})

Configuration with Token Refresh

provideXconDataSourceWithRefreshToken({
  apiUrl: 'https://api.example.com',
  site_key: 'my-app',
  debugMode: true,
  refreshToken: async () => {
    // Your token refresh logic
    const response = await fetch('/auth/refresh');
    const data = await response.json();
    return ApiResponse.create({
      success: response.ok,
      data: data
    });
  },
  onAuthFail: () => {
    // Redirect to login or show authentication error
    window.location.href = '/login';
  }
})

Environment-Based Configuration

// environments/environment.ts
export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api',
  dataSource: {
    site_key: 'dev-app',
    debugMode: true
  }
};

// app.module.ts
provideXconDataSource({
  apiUrl: environment.apiUrl,
  ...environment.dataSource
})

Advanced Usage

URL Handling: Relative vs Absolute

The DataSource API supports both relative paths and absolute URLs:

Relative Paths (uses configured baseURL)

// With baseURL configured as 'https://api.example.com'
await apiService.get('/users');
// Requests: https://api.example.com/users

await apiService.post('/auth/login', credentials);
// Requests: https://api.example.com/auth/login

Absolute URLs (bypasses baseURL)

// Direct external API calls
await apiService.get('https://external-api.com/data');
// Requests: https://external-api.com/data

await apiService.post('https://another-service.com/webhook', payload);
// Requests: https://another-service.com/webhook

Mixed Usage Example

async loadAllData() {
  // Internal API (uses baseURL)
  const users = await this.apiService.get('/users');
  
  // External API (absolute URL)
  const weather = await this.apiService.get('https://api.weather.com/current');
  
  // Another microservice (absolute URL)
  const analytics = await this.apiService.get('https://analytics.myapp.com/stats');
  
  return { users, weather, analytics };
}

Benefits of Absolute URL Support

  • Microservices: Easy integration with multiple backend services
  • Third-Party APIs: Direct calls to external APIs without proxy
  • Token Management: Authorization headers automatically included for both relative and absolute URLs
  • Interceptors: All requests go through configured interceptors
  • Refresh Token: Automatic token refresh works for absolute URLs too

Filtering and Pagination

import { ApiPage, ApiPageFilter, ApiPageFilterOperator } from '@stardyn/angular-data-source';

// Create pagination
const page = new ApiPage(1, 20); // Page 1, 20 items per page

// Add filters
page.filter.filters.push({
  field: 'name',
  operator: ApiPageFilterOperator.Contains,
  value: 'john'
});

page.filter.filters.push({
  field: 'age',
  operator: ApiPageFilterOperator.GreaterThan,
  value: 18
});

// Convert to query string
const queryString = page.toDataSourceRequestString();
// Result: "skip=0&take=20&pageSize=20&page=1&query=..."

// Use with API
const response = await apiService.get(`/api/users?${queryString}`);

Storage Management

// Store user preferences
storage.set('user_preferences', {
  theme: 'dark',
  language: 'en'
});

// Retrieve with default
const preferences = storage.get('user_preferences', {
  theme: 'light',
  language: 'tr'
});

// Check storage status
if (storage.isStorageAvailable()) {
  console.log('Storage size:', storage.getStorageSize(), 'bytes');
  console.log('Keys:', storage.getKeys());
}

Error Handling

try {
  const response = await apiService.post('/api/users', userData);
  
  if (response.success) {
    console.log('User created:', response.data);
  } else {
    console.error('API Error:', response.message);
  }
} catch (error) {
  if (error.response?.status === 401) {
    // Handle authentication error
    console.log('Authentication required');
  } else {
    console.error('Network error:', error);
  }
}

Provider Functions

Standard DataSource

// Provide both DataSource and DataSourceApi
provideXconDataSource(config): Provider

// Provide only DataSource
provideXconDataSourceOnly(config): Provider

// Provide only DataSourceApi
provideXconDataSourceApiOnly(config): Provider

DataSource with Refresh Token

// Provide DataSourceWithRefresh and DataSourceWithRefreshApi
provideXconDataSourceWithRefreshToken(config): Provider

// Provide only DataSourceWithRefresh
provideXconDataSourceWithRefreshOnly(config): Provider

// Provide only DataSourceWithRefreshApi
provideXconDataSourceWithRefreshApiOnly(config): Provider

Storage Service

// Provide StorageService
provideXconStorage(config): Provider

Debug Output Examples

When debug mode is enabled, console outputs appear in this format:

[XconDataSource] DataSource service initialized
[XconDataSource] Setting environment configuration {"apiUrl": "...", "siteKey": "..."}
[XconDataSourceApi] POST request initiated {"path": "/api/users", "hasData": true}
[XconDataSourceApi] Using relative path with baseURL {"method": "POST", "path": "/api/users"}
[XconDataSourceApi] API POST /api/users [200] (245ms)

[XconDataSourceApi] GET request initiated {"path": "https://external-api.com/data"}
[XconDataSourceApi] Using absolute URL for request {"method": "GET", "path": "https://external-api.com/data"}
[XconDataSourceApi] API GET https://external-api.com/data [200] (312ms)

Dependencies

Peer Dependencies

  • @angular/core >= 16.0.0
  • @angular/common >= 16.0.0
  • rxjs >= 7.0.0

Dependencies

  • axios - HTTP client
  • @stardyn/angular-console - Console logging service

Performance

  • Singleton Pattern: Services use singleton pattern to prevent multiple instances
  • Memory Efficient: Minimal memory footprint with proper cleanup
  • Production Optimized: Debug logging automatically disabled in production
  • Lazy Loading: Services only initialize when first used

TypeScript Support

Full TypeScript support with intellisense and type safety:

import { 
  XconDataSourceBasicConfig, 
  XconDataSourceConfig,
  ApiResponse,
  ApiPageFilterOperator
} from '@stardyn/angular-data-source';

Troubleshooting

API Requests Failing

  1. Check if DataSource is properly configured with apiUrl
  2. Verify authentication token is set if required
  3. Enable debug mode to see detailed request logs
  4. For absolute URLs, ensure the full URL including protocol is provided

Storage Issues

  1. Check if localStorage is available in the browser
  2. Verify site_key is properly configured
  3. Check browser storage quota if saving large data

Token Refresh Not Working

  1. Ensure refreshToken callback is properly implemented
  2. Check onAuthFail callback is handling failures
  3. Verify token refresh endpoint returns proper response format

Absolute URL Not Working

  1. Ensure URL starts with http:// or https://
  2. Check CORS settings on the external API
  3. Verify authentication token is being sent if required

License

MIT License - see LICENSE file for details.

Repository

https://github.com/stardyn/angular-data-source