JSPM

@pivot-blitz/server-client

0.2.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 13
    • Score
      100M100P100Q66531F
    • License SEE LICENSE IN LICENSE.md

    TypeScript client for PivotBlitz Server - connect pivot tables to databases

    Package Exports

    • @pivot-blitz/server-client

    Readme

    @pivotblitz/server-client

    TypeScript client for PivotBlitz Server - connect pivot tables directly to databases.

    Installation

    pnpm add @pivotblitz/server-client

    Features

    • Full TypeScript Support - Complete type definitions
    • Multiple Databases - PostgreSQL, MySQL, SQLite via PivotBlitz Server
    • Data Adapters - Easy integration with @pivotblitz/svelte
    • Caching - Built-in response caching
    • Authentication - JWT and API key support

    Quick Start

    import { PivotBlitzClient, createServerAdapter } from '@pivotblitz/server-client';
    
    // Create client
    const client = new PivotBlitzClient({
      baseUrl: 'http://localhost:8080',
      apiKey: 'your-api-key' // optional
    });
    
    // Execute pivot query
    const result = await client.pivot({
      connection: 'postgres_main',
      table: 'sales',
      rows: ['region'],
      cols: ['product'],
      vals: ['amount'],
      aggregator: 'Sum'
    });
    
    console.log(result.data);

    API Reference

    PivotBlitzClient

    The main client class for communicating with PivotBlitz Server.

    import { PivotBlitzClient } from '@pivotblitz/server-client';
    
    const client = new PivotBlitzClient({
      baseUrl: 'http://localhost:8080',
      timeout: 30000,        // Request timeout in ms
      apiKey: 'your-key',    // API key authentication
      token: 'jwt-token',    // JWT authentication
      headers: {             // Custom headers
        'X-Custom': 'value'
      },
      fetch: customFetch     // Custom fetch implementation (for SSR)
    });

    Methods

    health()

    Check server health and connection status.

    const health = await client.health();
    // {
    //   status: 'healthy',
    //   version: '0.1.0',
    //   connections: { postgres: 'ok', mysql: 'ok' }
    // }
    listConnections()

    List available database connections.

    const connections = await client.listConnections();
    // [
    //   { name: 'postgres_main', driver: 'postgres', database: 'myapp', status: 'connected' },
    //   { name: 'mysql_analytics', driver: 'mysql', database: 'analytics', status: 'connected' }
    // ]
    testConnection(name)

    Test a specific database connection.

    const result = await client.testConnection('postgres_main');
    // { status: 'ok', message: 'Connection successful' }
    listTables(connection)

    List tables in a database connection.

    const tables = await client.listTables('postgres_main');
    // ['sales', 'customers', 'products', 'orders']
    getTableSchema(connection, table)

    Get schema information for a table.

    const schema = await client.getTableSchema('postgres_main', 'sales');
    // {
    //   table: 'sales',
    //   columns: [
    //     { name: 'id', type: 'integer', nullable: false },
    //     { name: 'region', type: 'varchar', nullable: true },
    //     { name: 'amount', type: 'decimal', nullable: true }
    //   ]
    // }
    pivot(request)

    Execute a pivot query.

    const result = await client.pivot({
      connection: 'postgres_main',
      table: 'sales',
      rows: ['region', 'country'],
      cols: ['product'],
      vals: ['amount', 'quantity'],
      aggregator: 'Sum',
      filters: [
        { field: 'date', operator: 'gte', value: '2024-01-01' },
        { field: 'region', operator: 'in', value: ['North', 'South'] }
      ],
      sort: [
        { field: 'amount', direction: 'desc' }
      ],
      page: 1,
      pageSize: 1000
    });
    
    // {
    //   data: [
    //     { region: 'North', country: 'USA', product: 'Widget', sum_amount: 5000 },
    //     ...
    //   ],
    //   total: 150,
    //   page: 1,
    //   pageSize: 1000,
    //   aggregator: 'Sum',
    //   executionTime: 45
    // }
    previewPivot(request)

    Preview the SQL that would be generated.

    const preview = await client.previewPivot({
      connection: 'postgres_main',
      table: 'sales',
      rows: ['region'],
      vals: ['amount'],
      aggregator: 'Sum'
    });
    
    // {
    //   sql: 'SELECT "region", SUM("amount") AS sum_amount FROM "sales" GROUP BY "region" ORDER BY "region"',
    //   parameters: [],
    //   dialect: 'postgres'
    // }

    Authentication

    // Set JWT token
    client.setToken('new-jwt-token');
    
    // Set API key
    client.setApiKey('new-api-key');
    
    // Clear authentication
    client.clearAuth();

    Data Adapters

    createServerAdapter

    Create a data fetching function for use with @pivotblitz/svelte.

    <script>
      import { PivotBlitzClient, createServerAdapter } from '@pivotblitz/server-client';
      import { PivotTable } from '@pivotblitz/svelte';
    
      const client = new PivotBlitzClient({ baseUrl: 'http://localhost:8080' });
      
      const fetchData = createServerAdapter({
        client,
        connection: 'postgres_main',
        table: 'sales'
      });
    
      // Fetch data
      let data = $state([]);
      
      async function loadData() {
        const result = await fetchData({
          rows: ['region'],
          cols: ['product'],
          vals: ['amount'],
          aggregatorName: 'Sum',
          filters: {
            region: ['North', 'South']
          }
        });
        data = result.data;
      }
    </script>

    createReactiveDataSource

    Create a cached, reactive data source.

    import { createReactiveDataSource } from '@pivotblitz/server-client';
    
    const dataSource = createReactiveDataSource({
      client,
      connection: 'postgres_main',
      table: 'sales'
    });
    
    // Fetch with caching (30s TTL)
    const data = await dataSource.fetch({
      rows: ['region'],
      cols: [],
      vals: ['amount'],
      aggregatorName: 'Sum'
    });
    
    // Clear cache
    dataSource.clearCache();
    
    // Invalidate specific entries
    dataSource.invalidate('region');

    getFieldsFromSchema

    Automatically categorize fields into dimensions and measures.

    import { getFieldsFromSchema } from '@pivotblitz/server-client';
    
    const { dimensions, measures } = await getFieldsFromSchema(
      client,
      'postgres_main',
      'sales'
    );
    
    // dimensions: ['region', 'country', 'product', 'date']
    // measures: ['id', 'amount', 'quantity', 'price']

    Types

    import type {
      PivotBlitzClientConfig,
      PivotRequest,
      PivotResponse,
      PivotFilter,
      PivotSort,
      FilterOperator,
      SortDirection,
      Aggregator,
      ColumnSchema,
      TableSchema,
      ConnectionInfo,
      HealthResponse,
      PreviewResponse,
      ErrorResponse
    } from '@pivotblitz/server-client';

    PivotRequest

    interface PivotRequest {
      connection: string;      // Connection name
      table: string;           // Table or view name
      rows: string[];          // Row fields
      cols?: string[];         // Column fields
      vals: string[];          // Value fields
      aggregator?: Aggregator; // Sum, Count, Average, etc.
      filters?: PivotFilter[]; // Filter conditions
      sort?: PivotSort[];      // Sort specifications
      page?: number;           // Page number (1-based)
      pageSize?: number;       // Page size (max 10000)
    }

    FilterOperator

    type FilterOperator = 
      | 'eq' | 'neq'           // Equals, not equals
      | 'gt' | 'gte'           // Greater than
      | 'lt' | 'lte'           // Less than
      | 'in' | 'not_in'        // In list
      | 'like' | 'not_like'    // Pattern matching
      | 'is_null' | 'is_not_null';

    Aggregator

    type Aggregator = 
      | 'Sum' | 'Count' | 'Average' | 'Min' | 'Max'
      | 'Median' | 'Variance' | 'StdDev'
      | 'CountDistinct' | 'First' | 'Last';

    Error Handling

    import { PivotBlitzClient, PivotBlitzError } from '@pivotblitz/server-client';
    
    try {
      const result = await client.pivot(request);
    } catch (error) {
      if (error instanceof PivotBlitzError) {
        console.error('API Error:', error.message);
        console.error('Code:', error.code);      // e.g., 'CONNECTION_NOT_FOUND'
        console.error('Status:', error.status);   // HTTP status code
        console.error('Details:', error.details); // Additional info
      }
    }

    Server Setup

    This client requires PivotBlitz Server to be running.

    # Start server with Docker
    cd packages/server
    cp config.example.yaml config.yaml
    docker-compose up -d
    
    # Server runs at http://localhost:8080

    License

    MIT