static-data-browser
v1.0.5
Published
Browser-compatible static data library for company records and bracket orders
Maintainers
Readme
Static Data Browser Library
A browser-compatible TypeScript library for managing company records and bracket orders using IndexedDB and in-memory caching.
Features
- Company Records: Fetch and cache company information from exchanges.
- Bracket Orders: Check bracket order status for scrips.
- Caching: In-memory caching with automatic expiration and size management.
- Persistence: IndexedDB storage for offline data access.
- Modern Browser Support: Built with modern browsers in mind, using ES modules and modern JavaScript features.
Installation
npm install static-data-browserConfiguration
The library requires configuration when initializing. Here's a complete configuration example:
import { StaticDataManager } from 'static-data-browser';
const config = {
apiConfig: {
baseUrl: 'https://api.example.com/v1',
timeout: 30000, // 30 seconds
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json',
'UserID': 'your-user-id',
'Password': 'your-password'
}
},
cacheConfig: {
maxSize: 1000, // Maximum number of items in cache
maxAge: 3600000 // Cache items expire after 1 hour (in milliseconds)
},
loggerConfig: {
level: 'debug' // Log level for development
},
exchanges: ['N', 'B', 'M'] // Optional: list of exchanges
};
// Initialize
const manager = await StaticDataManager.initialize(config);Usage
Vanilla JavaScript
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Static Data Demo</title>
</head>
<body>
<div id="app">
<h1>Company Information</h1>
<div id="companyInfo"></div>
<div id="bracketStatus"></div>
</div>
<!-- Using ES modules -->
<script type="module">
import { StaticDataManager } from 'static-data-browser';
async function initApp() {
try {
// Initialize with configuration
const manager = await StaticDataManager.initialize({
apiConfig: {
baseUrl: 'https://api.example.com/v1',
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json',
'UserID': 'your-user-id',
'Password': 'your-password'
}
},
cacheConfig: {
maxSize: 1000,
maxAge: 3600000
},
loggerConfig: {
level: 'debug'
},
exchanges: ['N', 'B', 'M']
});
// Example: Fetch company record
const companyRecord = await manager.getCompanyRecord({
exchange: 'N',
exchangeType: 'C',
scripCode: 'RELIANCE'
});
// Display company information
const companyInfoDiv = document.getElementById('companyInfo');
companyInfoDiv.innerHTML = `
<h2>${companyRecord.companyName}</h2>
<p>Exchange: ${companyRecord.exchange}</p>
<p>Type: ${companyRecord.exchangeType}</p>
<p>Symbol: ${companyRecord.symbol}</p>
`;
// Example: Check bracket order status
const hasBracketOrders = await manager.getBracketOrderStatus({
exchange: 'N',
exchangeType: 'C',
scripCode: 'RELIANCE'
});
// Display bracket order status
const bracketStatusDiv = document.getElementById('bracketStatus');
bracketStatusDiv.innerHTML = `
<h3>Bracket Order Status</h3>
<p>${hasBracketOrders ? 'Available' : 'Not Available'}</p>
`;
// Example: Sync cache for specific exchanges
await manager.syncCache(['N', 'B']);
// Example: Validate cache
const validation = await manager.validateCache(['N']);
console.log('Cache validation:', validation);
window.addEventListener('unload', () => {
manager.close();
});
} catch (error) {
console.error('Error:', error);
}
}
initApp();
</script>
</body>
</html>React Project
First, create a custom hook to manage the StaticDataManager:
// src/hooks/useStaticData.ts
import { useEffect, useState, useCallback } from 'react';
import { StaticDataManager } from 'static-data-browser';
import type { CompanyInfoParams, CompanyRecord } from 'static-data-browser';
export function useStaticData() {
const [manager, setManager] = useState<StaticDataManager | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
async function initManager() {
try {
const staticDataManager = await StaticDataManager.initialize({
apiConfig: {
baseUrl: process.env.REACT_APP_API_BASE_URL || 'https://api.example.com/v1',
headers: {
'Authorization': `Bearer ${process.env.REACT_APP_API_TOKEN}`,
'Content-Type': 'application/json',
'UserID': process.env.REACT_APP_USER_ID || '',
'Password': process.env.REACT_APP_PASSWORD || ''
}
},
cacheConfig: {
maxSize: 1000,
maxAge: 3600000
},
loggerConfig: {
level: process.env.NODE_ENV === 'development' ? 'debug' : 'error'
},
exchanges: ['N', 'B', 'M']
});
setManager(staticDataManager);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to initialize StaticDataManager'));
} finally {
setLoading(false);
}
}
initManager();
return () => {
if (manager) {
manager.close();
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getCompanyRecord = useCallback(async (params: CompanyInfoParams): Promise<CompanyRecord | null> => {
if (!manager) throw new Error('Manager not initialized');
return manager.getCompanyRecord(params);
}, [manager]);
const getBracketOrderStatus = useCallback(async (params: CompanyInfoParams): Promise<boolean> => {
if (!manager) throw new Error('Manager not initialized');
return manager.getBracketOrderStatus(params);
}, [manager]);
const syncCache = useCallback(async (exchanges: string[]): Promise<void> => {
if (!manager) throw new Error('Manager not initialized');
return manager.syncCache(exchanges);
}, [manager]);
return {
manager,
loading,
error,
getCompanyRecord,
getBracketOrderStatus,
syncCache,
};
}Then use it in your React components:
// src/components/CompanyInfo.tsx
import React, { useEffect, useState } from 'react';
import { useStaticData } from '../hooks/useStaticData';
import type { CompanyRecord } from 'static-data-browser';
interface CompanyInfoProps {
scripCode: string;
exchange: string;
exchangeType: string;
}
export function CompanyInfo({ scripCode, exchange, exchangeType }: CompanyInfoProps) {
const { loading, error, getCompanyRecord, getBracketOrderStatus } = useStaticData();
const [companyData, setCompanyData] = useState<CompanyRecord | null>(null);
const [hasBracketOrders, setHasBracketOrders] = useState<boolean>(false);
useEffect(() => {
async function fetchData() {
try {
const [record, bracketStatus] = await Promise.all([
getCompanyRecord({ scripCode, exchange, exchangeType }),
getBracketOrderStatus({ scripCode, exchange, exchangeType })
]);
setCompanyData(record);
setHasBracketOrders(bracketStatus);
} catch (err) {
console.error('Error fetching data:', err);
}
}
if (!loading) {
fetchData();
}
}, [scripCode, exchange, exchangeType, loading, getCompanyRecord, getBracketOrderStatus]);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!companyData) return <div>No data found</div>;
return (
<div>
<h2>{companyData.companyName}</h2>
<p>Exchange: {companyData.exchange}</p>
<p>Type: {companyData.exchangeType}</p>
<p>Symbol: {companyData.symbol}</p>
<p>Bracket Orders: {hasBracketOrders ? 'Available' : 'Not Available'}</p>
</div>
);
}Error Handling
The library provides specific error types that you can catch and handle:
import { NetworkError, DatabaseError, CacheError } from 'static-data-browser';
try {
const record = await manager.getCompanyRecord(params);
} catch (error) {
if (error instanceof NetworkError) {
// Handle network-related errors
console.error('Network error:', error.message);
} else if (error instanceof DatabaseError) {
// Handle database-related errors
console.error('Database error:', error.message);
} else if (error instanceof CacheError) {
// Handle cache-related errors
console.error('Cache error:', error.message);
} else {
// Handle other errors
console.error('Unknown error:', error);
}
}Browser Support
The library is built for modern browsers and supports:
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Development
# Install dependencies
npm install
# Build the library
npm run build
# Run tests
npm test
# Lint code
npm run lint
# Format code
npm run formatLicense
MIT
