### Initialize Project Environment Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Commands to clone the repository and install dependencies. ```bash git clone git@github.com:AlphaQuantJS/tinyframejs.git cd tinyframejs npm install ``` -------------------------------- ### DataFrame Lifecycle Example Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Demonstrates the internal lifecycle of DataFrame creation and automatic storage engine selection. ```javascript // Example lifecycle // 1. Create DataFrame const df = new DataFrame({ x: [1, 2, 3], y: ['a', 'b', 'c'] }); // 2. DataFrame calls VectorFactory for each column // 3. VectorFactory decides whether to use Arrow or TypedArray // 4. Returns the corresponding ColumnVector // 5. Each column becomes a Series with the chosen ColumnVector // 6. DataFrame methods work uniformly regardless of the storage type ``` -------------------------------- ### Commit Message Examples Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Examples of valid commit messages following the Conventional Commits standard. ```text feat(core): add corrMatrix support fix(frame): handle NaN edge case in rollingMean docs(readme): add usage examples ``` -------------------------------- ### Creating a Method in a Separate File Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Illustrates the first step in the module system: defining a method in its own file. This example shows the `sum` aggregation method. ```javascript // src/methods/dataframe/aggregation/sum.js export const sum = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); // Implementation... return total; }; ``` -------------------------------- ### Transform Method Example: Sorting a DataFrame Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md An example of a 'Transform' method that returns a new DataFrame with sorted data. It requires a `validateColumn` dependency and sorts based on the values in a specified column. ```javascript export const sort = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); // Create indices for sorting const arr = frame.columns[column]; const sortedIndices = [...arr.keys()].sort((a, b) => arr[a] - arr[b]); // Create new frame with sorted data const newColumns = {}; for (const col of Object.keys(frame.columns)) { const originalArray = frame.columns[col]; newColumns[col] = sortedIndices.map(i => originalArray[i]); } return { columns: newColumns, rowCount: frame.rowCount }; }; ``` -------------------------------- ### Method Implementation with Dependency Injection Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Example of a pure function method using dependency injection for testability. ```javascript // Example method with dependency injection export const sum = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); const arr = frame.columns[column]; let total = 0; for (let i = 0; i < arr.length; i++) { total += arr[i]; } return total; }; ``` -------------------------------- ### Aggregation Method Example: Summing a Column Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md An example of an 'Aggregation' method that returns a scalar value. This method calculates the sum of values in a specified column and requires `validateColumn`. ```javascript export const sum = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); const arr = frame.columns[column]; let total = 0; for (let i = 0; i < arr.length; i++) { total += arr[i]; } return total; }; ``` -------------------------------- ### Define a Namespaced Method (e.g., Technical Analysis) Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Create specialized methods within specific packages, like technical analysis, by defining them similarly to core methods. This example shows a 'sma' (Simple Moving Average) function. ```javascript // packages/quant/src/methods/ta/sma.js export const sma = ({ validateColumn }) => (frame, column, period = 14) => { validateColumn(frame, column); // Implementation return result; }; ``` -------------------------------- ### Run Project Verification Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md A single command to format, lint, and test the project. ```bash pnpm format && pnpm lint --fix && pnpm test ``` -------------------------------- ### Project Structure Overview Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Illustrates the monorepo structure of TinyFrameJS, detailing the purpose of each package directory. ```bash packages/ ├─ core/ # Library core: DataFrame, Series, vectors, and basic methods │ ├─ src/ │ │ ├─ core/ # Main classes: DataFrame, Series, VectorFactory │ │ ├─ vectors/ # Vector implementations: TypedArray, Arrow, Simple │ │ ├─ methods/ # DataFrame methods: aggregation, filtering, transformation │ │ └─ utils/ # Utilities: validators, math functions │ ├─ tests/ # Tests for the main module │ └─ package.json # Configuration for the main module ├─ io/ # Module for working with input/output: CSV, JSON, SQL, API ├─ quant/ # Module for financial and quantum calculations ├─ viz/ # Module for visualization and data display └─ utils/ # Common utilities and helper functions tests/ # Integration tests and performance tests benсhmarks/ # Scripts for comparing performance ``` -------------------------------- ### Creating a Barrel File for Method Re-exporting Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Shows how to create a 'barrel' file (`pool.js`) to re-export multiple methods from individual files, consolidating them for easier import. ```javascript // src/methods/dataframe/aggregation/pool.js export { sum } from './sum.js'; export { mean } from './mean.js'; export { min } from './min.js'; export { max } from './max.js'; ``` -------------------------------- ### Modular Method Registration Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Shows how to import core classes and register additional functionality via external packages. ```javascript // Import core classes import { DataFrame } from '@tinyframejs/core'; // Import additional packages (automatically register methods) import '@tinyframejs/viz'; import '@tinyframejs/quant'; // Create DataFrame const df = new DataFrame(data); // Use aggregation methods (from core) console.log(df.sum('price')); // Use visualization methods (from viz) df.plot('price'); // Use technical analysis methods (from quant) const sma = df.ta.sma('price', 14); ``` -------------------------------- ### Run Test Suite Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Executes all tests using Vitest. ```bash pnpm test ``` -------------------------------- ### Development Process Commands Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md These bash commands are used for linting, building, testing, and benchmarking the project. They should be run from the root of the project or within individual package directories. ```bash # Run from the root of the project npm run lint # Code check with ESLint npm run build # Build all packages npm run test # Run tests (Vitest) npm run benchmark # Run performance tests # Work with individual packages cd packages/core npm run build # Build the main package npm run test # Run tests for the main package ``` -------------------------------- ### Format Codebase Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Applies Prettier formatting rules to project files. ```bash pnpm format ``` -------------------------------- ### Execute Release Commands Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Commands to merge development changes into main and tag the release. ```bash git checkout main git merge dev git tag v1.0.0 git push origin main --tags ``` -------------------------------- ### Compare Pure Functions vs Classes for Logic Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Demonstrates the preference for pure functions over class-based state management for simple logic to improve efficiency and testability. ```javascript // Preferred: function calculatePnL(entryPrice, exitPrice) { return exitPrice - entryPrice; } // Less efficient: class Trade { constructor(entry, exit) { this.entry = entry; this.exit = exit; } getPnL() { return this.exit - this.entry; } } ``` -------------------------------- ### Create and Access DataFrames Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Initialize DataFrames from column-oriented data, row-oriented records, or Apache Arrow tables. Use properties like rowCount and col() to inspect data. ```javascript import { DataFrame } from 'tinyframejs'; // Create from column-oriented data (preferred for performance) const df = new DataFrame({ price: [10.5, 11.2, 9.8, 12.3], quantity: [100, 50, 75, 200], symbol: ['AAPL', 'GOOG', 'MSFT', 'AMZN'] }); // Create from row-oriented data (array of objects) const df2 = DataFrame.fromRecords([ { price: 10.5, quantity: 100, symbol: 'AAPL' }, { price: 11.2, quantity: 50, symbol: 'GOOG' }, { price: 9.8, quantity: 75, symbol: 'MSFT' }, { price: 12.3, quantity: 200, symbol: 'AMZN' } ]); // Create from Apache Arrow table const arrowDf = DataFrame.fromArrow(arrowTable); // Access basic properties console.log(df.rowCount); // 4 console.log(df.columns); // ['price', 'quantity', 'symbol'] console.log(df.col('price').toArray()); // [10.5, 11.2, 9.8, 12.3] ``` -------------------------------- ### Registering Methods with extendDataFrame Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Demonstrates the final step of registering methods by importing a pool of methods and using `extendDataFrame` to attach them to the DataFrame prototype. It also shows how to export methods for direct use. ```javascript // src/methods/dataframe/aggregation/index.js import { DataFrame } from '../../../core/DataFrame.js'; import { extendDataFrame } from '../../../core/extendDataFrame.js'; import * as pool from './pool.js'; // Зависимости import { validateColumn } from '../../../utils/validators.js'; const deps = { validateColumn }; // Регистрация методов extendDataFrame(DataFrame.prototype, pool); // Export methods for direct use export * from './pool.js'; ``` -------------------------------- ### Create Feature Branch Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Command to create and switch to a new feature branch. ```bash git checkout -b feat/your-feature-name ``` -------------------------------- ### Unified Method Structure with Dependency Injection Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Demonstrates the standard pattern for defining methods in TinyFrameJS, utilizing dependency injection for testability and consistency. Dependencies are passed explicitly to the method factory. ```javascript /** * Описание метода * @param {Object} frame - Объект DataFrame * @param {String} column - Имя колонки * @returns {Number|Array|Object} - Description of the returned value */ export const methodName = ({ validateColumn, otherDep }) => (frame, column, ...otherArgs) => { // Input data validation validateColumn(frame, column); // Implementation const result = /* ... */; return result; }; ``` -------------------------------- ### API Client Configuration and Usage Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Initialize an API client with built-in caching, throttling, retry logic, and authentication. Supports various HTTP methods and data formats. ```javascript import { createApiClient, ApiClient } from 'tinyframejs'; // Create configured API client const client = createApiClient({ baseUrl: 'https://api.example.com', defaultHeaders: { 'Content-Type': 'application/json' }, auth: { keys: [ { id: 'key1', key: 'api-key-1' }, { id: 'key2', key: 'api-key-2' } ], authType: 'bearer' // 'bearer', 'basic', 'header', 'query' }, cache: { ttl: 3600000, // 1 hour cache maxSize: 100 }, throttle: { requestsPerSecond: 5, requestsPerMinute: 100 }, retry: { retries: 3, retryDelay: 1000, retryOn: [429, 503] } }); // Fetch JSON data const data = await client.fetchJson('/endpoint'); // Fetch and convert to DataFrame const df = await client.fetchDataFrame('/endpoint'); // Fetch with schema transformation const transformed = await client.fetchJson('/endpoint', {}, 'binanceOHLCV'); // Fetch CSV data const csvDf = await client.fetchCsv('/data.csv'); // HTTP methods const response = await client.get('/users'); const created = await client.post('/users', { name: 'Alice', age: 25 }); const updated = await client.put('/users/1', { name: 'Alice Updated' }); const deleted = await client.delete('/users/1'); ``` -------------------------------- ### Data Visualization Usage with @tinyframejs/viz Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Import the viz module and use its methods to create and export charts. Ensure the viz module is registered by importing '@tinyframejs/viz'. Methods like `plot`, `histogram`, and `heatmap` are available for creating visualizations. ```javascript import { DataFrame } from '@tinyframejs/core'; import '@tinyframejs/viz'; // Registers methods in viz namespace const df = new DataFrame({ /* ... */ }); // Usage in viz namespace const lineChart = df.viz.plot('price', { type: 'line' }); const histogram = df.viz.histogram('price', { bins: 10 }); const heatmap = df.viz.heatmap(['x', 'y', 'value']); ``` -------------------------------- ### Object Property Initialization Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Initialize all object properties at creation to avoid hidden class changes. Do not add properties dynamically later and maintain consistent property order. ```javascript // Good function Account(id, balance) { this.id = id; this.balance = balance; } // Bad (hidden class changes) const acc = {}; acc.id = 'A123'; acc.balance = 1000; acc.currency = 'USD'; ``` -------------------------------- ### Generate Coverage Report Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Generates and displays test coverage metrics. ```bash pnpm coverage ``` -------------------------------- ### Chain DataFrame Methods for Analysis Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Demonstrates chaining transform and aggregation methods to perform data filtering, sorting, selection, and calculation. ```javascript // Chain of transform and aggregation methods const avgPrice = df .filter(row => row.quantity > 0) .sort('price') .select(['price', 'quantity']) .mean('price'); ``` -------------------------------- ### API Client Methods Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Standard HTTP methods for interacting with remote APIs using the tinyframejs client. ```APIDOC ## GET /users ### Description Fetches user data from the configured API base URL. ## POST /users ### Description Creates a new user resource. ### Request Body - **name** (string) - Required - **age** (number) - Required ## PUT /users/{id} ### Description Updates an existing user resource. ### Parameters - **id** (string) - Required - User identifier. ## DELETE /users/{id} ### Description Deletes a user resource. ### Parameters - **id** (string) - Required - User identifier. ``` -------------------------------- ### Register New DataFrame Method via Barrel File Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Add your newly created method to the aggregation pool's barrel file to make it available for automatic registration. ```javascript // Add along with other exports export { yourNew } from './yourNew.js'; ``` -------------------------------- ### Use Newly Registered DataFrame Method Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md After registering a new method, it can be directly called on any DataFrame instance. Ensure the core library is imported. ```javascript import { DataFrame } from '@tinyframejs/core'; const df = new DataFrame({ x: [1, 2, 3], y: [4, 5, 6] }); // The method is automatically available in DataFrame const result = df.yourNew('x'); ``` -------------------------------- ### Visualize Branching Workflow Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Diagram showing the relationship between main, dev, feature, and hotfix branches. ```text main (stable) │ ├─ dev (development) │ ├─ feature/lazy-computation │ ├─ feature/arrow-integration │ ├─ fix/null-pointer-issue-32 │ └─ refactor/dataframe-optimizations │ └─ hotfix/dataframe-critical-bug (if urgent fix needed) ``` -------------------------------- ### Automate Git Commit Hooks Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Commands to stage and commit changes, triggering linting and formatting automatically. ```bash git add . git commit -m "feat: describe your change" ``` -------------------------------- ### Use Time Series Utilities in JavaScript Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Perform date range generation, business day calculations, and period boundary identification for financial data. ```javascript import { timeseriesUtils } from 'tinyframejs'; const { dateRange, isBusinessDay, nextBusinessDay, previousBusinessDay, addBusinessDays, startOfMonth, endOfMonth, startOfQuarter, endOfQuarter, startOfYear, endOfYear, inferFrequency } = timeseriesUtils; // Generate date range const dates = dateRange('2024-01-01', '2024-01-31', 'day'); // Business day utilities const date = new Date('2024-01-15'); console.log(isBusinessDay(date)); // true (if Monday-Friday) console.log(nextBusinessDay(date)); // Next business day console.log(previousBusinessDay(date)); // Previous business day console.log(addBusinessDays(date, 5)); // Add 5 business days // Period boundaries console.log(startOfMonth(date)); // First day of month console.log(endOfMonth(date)); // Last day of month console.log(startOfQuarter(date)); // First day of quarter console.log(endOfQuarter(date)); // Last day of quarter console.log(startOfYear(date)); // First day of year console.log(endOfYear(date)); // Last day of year // Infer frequency from data const frequency = inferFrequency(['2024-01-01', '2024-01-02', '2024-01-03']); console.log(frequency); // 'daily' ``` -------------------------------- ### Modular Method Registration Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Registering methods to the DataFrame prototype using the extendDataFrame utility. ```javascript // Example method registration import { DataFrame } from '../core/DataFrame.js'; import { extendDataFrame } from '../utils/extendDataFrame.js'; import * as aggregationMethods from './aggregation/index.js'; // Register methods directly on DataFrame.prototype extendDataFrame(DataFrame.prototype, aggregationMethods); // Register methods in a namespace extendDataFrame(DataFrame.prototype, technicalMethods, { namespace: 'ta' }); ``` -------------------------------- ### Lint and Fix Code Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Runs ESLint to automatically fix style and linting errors. ```bash pnpm lint --fix ``` -------------------------------- ### Create and Render Visualizations in JavaScript Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Generate charts from DataFrames using factory functions or direct type-specific APIs, including financial candlestick charts. ```javascript import { DataFrame } from 'tinyframejs'; import { createChart, renderChart, line, bar, scatter, pie } from 'tinyframejs/viz'; const df = new DataFrame({ date: ['2024-01', '2024-02', '2024-03', '2024-04'], sales: [100, 150, 120, 180], profit: [20, 35, 25, 45] }); // Create charts using factory function const lineChart = createChart(df, 'line', { x: 'date', y: 'sales' }); const barChart = createChart(df, 'bar', { x: 'date', y: 'sales' }); const scatterChart = createChart(df, 'scatter', { x: 'sales', y: 'profit' }); // Direct chart type functions const multiLine = line.multiAxisLineChart(df, { x: 'date', y: ['sales', 'profit'] }); const histogram = bar.histogram(df, { column: 'sales', bins: 10 }); const bubbleChart = scatter.bubbleChart(df, { x: 'sales', y: 'profit', size: 'units' }); // Financial candlestick chart import { financial } from 'tinyframejs/viz'; const ohlcDf = new DataFrame({ date: ['2024-01-01', '2024-01-02'], open: [100, 105], high: [110, 115], low: [95, 100], close: [105, 110] }); const candlestick = financial.candlestickChart(ohlcDf); // Render chart (auto-detects environment) await renderChart(lineChart, { width: 800, height: 400, title: 'Sales Over Time' }); ``` -------------------------------- ### Test Structure for DataFrame Methods Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Standard boilerplate for testing DataFrame methods using Vitest, covering both transformation and aggregation scenarios. ```javascript import { describe, test, expect } from 'vitest'; import { DataFrame } from '../../../src/core/DataFrame.js'; describe('DataFrame.methodName', () => { const df = DataFrame.create({ a: [1, 2, 3], b: [10, 20, 30], }); test('performs expected operation', () => { // For transformation method const result = df.methodName('a'); expect(result).toBeInstanceOf(DataFrame); expect(result.columns).toContain('a'); // For aggregation method const value = df.methodName('a'); expect(value).toBe(expectedValue); }); test('throws on invalid input', () => { expect(() => df.methodName('nonexistent')).toThrow(); }); }); ``` -------------------------------- ### Exporting Charts to Various Formats Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Use the `export` method from the viz namespace to save charts in different formats like PNG, JPEG, PDF, and SVG. The method takes the desired filename and an options object specifying the chart type. ```javascript // Export to various formats: PNG, JPEG, PDF, SVG await df.viz.export('chart.png', { type: 'line' }); await df.viz.export('report.pdf', { type: 'pie' }); ``` -------------------------------- ### Implementation of extendDataFrame Utility Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Provides the core implementation of the `extendDataFrame` function, which iterates over a pool of methods and attaches them to a target prototype, optionally with a namespace and strict conflict checking. ```javascript // src/core/extendDataFrame.js export function extendDataFrame(proto, pool, { namespace, strict = true } = {}) { const target = namespace ? (proto[namespace] ??= {}) : proto; for (const [name, fn] of Object.entries(pool)) { if (strict && name in target) { throw new Error(`Method conflict: ${namespace ? namespace + '.' : ''}${name}`); } target[name] = function (...args) { return fn(this, ...args); // Transparently pass this as the first argument }; } } ``` -------------------------------- ### Define Feature Branch Naming Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Naming conventions for feature, fix, and refactor branches. ```bash feature/ fix/ refactor/ ``` -------------------------------- ### Read Other File Formats Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Load data from JSON, Excel, TSV, and SQL sources using specialized reader functions. ```javascript import { readJson, readExcel, readTsv, readSql } from 'tinyframejs'; // Read JSON file const dfJson = await readJson('/path/to/data.json'); // Read Excel file with sheet selection const dfExcel = await readExcel('/path/to/data.xlsx', { sheet: 'Sheet1' }); // Read TSV (tab-separated values) const dfTsv = await readTsv('/path/to/data.tsv'); // Read from SQL database const dfSql = await readSql( 'SELECT * FROM users WHERE active = 1', dbConnection ); ``` -------------------------------- ### Use Namespaced DataFrame Methods Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Access specialized methods like technical analysis (ta) or visualization (viz) through their respective namespaces. ```javascript // Use methods from namespaces const sma20 = df.ta.sma('price', 20); const histogram = df.viz.histogram('price', { bins: 10 }); ``` -------------------------------- ### Use a Namespaced DataFrame Method Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Access methods registered under a namespace via dot notation on the DataFrame instance (e.g., `df.ta.sma`). Ensure the package containing the methods is imported to trigger registration. ```javascript import { DataFrame } from '@tinyframejs/core'; import '@tinyframejs/quant'; // Registers methods const df = new DataFrame({ close: [100, 101, 102, 101, 99] }); // Access through namespace const smaValues = df.ta.sma('close', 3); ``` -------------------------------- ### Create DataFrame from Column-Oriented Data Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Instantiate a DataFrame using column-oriented data, which is the preferred method for creating DataFrames. ```javascript const df = new DataFrame({ price: [10.5, 11.2, 9.8, 12.3], quantity: [100, 50, 75, 200], }); ``` -------------------------------- ### Transformation vs. Aggregation Implementation Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Distinguishes between methods returning a new DataFrame versus those returning a scalar value. ```javascript // Transformation method example export const filter = ({ validateFunction }) => (frame, predicate) => { validateFunction(predicate); // Implementation that returns a new DataFrame return new DataFrame(/* filtered data */); }; // Aggregation method example export const sum = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); // Implementation that returns a scalar value return total; }; ``` -------------------------------- ### Data Reshaping: Long to Wide and Wide to Long Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Use `pivot` to transform data from a long format to a wide format, and `melt` to transform from wide to long. Ensure the correct columns are specified for index, columns, and values in `pivot`, and for `idVars` and `valueVars` in `melt`. ```javascript // Long to wide const pivoted = df.pivot({ index: 'date', // Column for rows columns: 'symbol', // Column for generating new columns values: 'price' // Column for values }); // Wide to long const melted = df.melt({ idVars: ['date'], // Columns to keep valueVars: ['price', 'volume'] // Columns to transform }); ``` -------------------------------- ### Optimized Rolling Sum Calculation Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Implement rolling sum calculations using a sliding window approach for O(n) complexity, avoiding the O(n*k) complexity of nested loops by updating the sum incrementally. ```javascript // Bad (O(n*k)) function rollingSum(values, windowSize) { const result = new Float64Array(values.length - windowSize + 1); for (let i = 0; i <= values.length - windowSize; i++) { let sum = 0; for (let j = 0; j < windowSize; j++) { sum += values[i + j]; } result[i] = sum; } return result; } // Good (O(n)) function rollingSum(values, windowSize) { const result = new Float64Array(values.length - windowSize + 1); let sum = 0; // Initialize first window for (let i = 0; i < windowSize; i++) { sum += values[i]; } result[0] = sum; // Sliding window for (let i = 1; i <= values.length - windowSize; i++) { sum = sum - values[i - 1] + values[i + windowSize - 1]; result[i] = sum; } return result; } ``` -------------------------------- ### Extending DataFrame with Custom Methods Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Defines custom pure functions and registers them into the DataFrame prototype using a namespace. ```javascript import { DataFrame, extendDataFrame } from '@tinyframejs/core'; // Define methods as pure functions const customMethods = { logReturn(df, column = 'close') { return df.col(column).map((value, i, series) => { if (i === 0) return 0; return Math.log(value / series.get(i - 1)); }); }, volatility(df, column = 'close', window = 5) { const returns = df.logReturn(column); return returns.std({ window }); } }; // Register methods in DataFrame prototype extendDataFrame(DataFrame.prototype, customMethods, { namespace: 'custom' }); // Use custom methods const returns = df.custom.logReturn('price'); const volatility = df.custom.volatility('price', 5); ``` -------------------------------- ### Conventional Commit Format Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md The required structure for commit messages to support automated changelogs. ```text (scope): short summary ``` -------------------------------- ### Automatic Method Registration with extendDataFrame Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Methods exported from the aggregation pool are automatically registered with the DataFrame prototype using 'extendDataFrame'. This makes them directly callable on DataFrame instances. ```javascript import { DataFrame } from '../../../core/DataFrame.js'; import { extendDataFrame } from '../../../core/extendDataFrame.js'; import * as pool from './pool.js'; // Dependencies import { validateColumn } from '../../../utils/validators.js'; const deps = { validateColumn }; // Register methods extendDataFrame(DataFrame.prototype, pool); // Export methods for direct use export * from './pool.js'; ``` -------------------------------- ### Precise Decimal Math Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Using decimal.js for handling precise decimal calculations. ```javascript import Decimal from 'decimal.js'; const total = new Decimal('0.1').plus('0.2'); // "0.3" ``` -------------------------------- ### Export and Manage DataFrame Data in JavaScript Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Convert DataFrames to various formats, manage metadata, and optimize storage for specific operations. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ name: ['Alice', 'Bob', 'Charlie'], age: [25, 30, 35], score: [85, 92, 78] }); // Convert to array of row objects const rows = df.toArray(); // [{ name: 'Alice', age: 25, score: 85 }, ...] // Convert to column objects const columns = df.toColumns(); // { name: ['Alice', 'Bob', 'Charlie'], age: [25, 30, 35], score: [85, 92, 78] } // Export to HTML table const html = df.toHTML(); // ......
// Export to Markdown table const markdown = df.toMarkdown(); // | name | age | score | // | --- | --- | --- | // | Alice | 25 | 85 | // ... // Export to Apache Arrow format const arrowTable = await df.toArrow(); // Set and get metadata df.setMeta({ source: 'API', timestamp: Date.now() }); console.log(df.getMeta()); // { source: 'API', timestamp: ... } // Optimize storage for specific operation const optimized = await df.optimizeFor('aggregation'); ``` -------------------------------- ### Middleware Hooks for API Client Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Extend client functionality by adding hooks for logging, caching, throttling, and authentication. Hooks are added to the client instance using the addHook method. ```javascript import { createLoggerHook, createCacheHook, createThrottleHook, createAuthHook, MemoryCache } from 'tinyframejs'; // Logger hook const loggerHook = createLoggerHook({ logRequest: true, logResponse: true, logErrors: true, logTiming: true, logger: console.log }); // Cache hook const cache = new MemoryCache({ ttl: 3600000, maxSize: 100 }); const cacheHook = createCacheHook({ cache, ttl: 3600000, keyGenerator: (req) => `${req.method}:${req.url}`, shouldCache: (req) => req.method === 'GET' }); // Throttle hook const throttleHook = createThrottleHook({ requestsPerSecond: 5, requestsPerMinute: 100, requestsPerHour: 1000, groupByDomain: true, onThrottle: (waitTime) => console.log(`Waiting ${waitTime}ms`) }); // Auth hook with key rotation const authHook = createAuthHook({ keys: [{ id: 'key1', key: 'api-key-1' }, { id: 'key2', key: 'api-key-2' }], authType: 'bearer', headerName: 'Authorization', maxErrorsBeforeDisable: 3, rotationStrategy: 'round-robin' // 'round-robin', 'least-used', 'random' }); // Add hooks to client client.addHook(loggerHook); client.addHook(cacheHook); client.addHook(throttleHook); client.addHook(authHook); ``` -------------------------------- ### API Schema Registry Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Register and apply schemas to standardize API response formats. Includes built-in support for common financial APIs. ```javascript import { registerSchema, applySchema, getSchema } from 'tinyframejs'; // Register custom schema registerSchema('myApiSchema', { timestamp: 'time', // Simple field mapping value: { path: 'data.value', // Nested path transform: (v) => parseFloat(v) // With transformation }, name: (obj) => `${obj.type}-${obj.id}` // Custom function }); // Apply schema to data const rawData = await client.fetchJson('/endpoint'); const transformed = applySchema(rawData, 'myApiSchema'); // Get registered schema const schema = getSchema('myApiSchema'); // Built-in schemas for financial APIs import { binanceOHLCV, alphaVantageDaily } from 'tinyframejs'; const binanceData = applySchema(rawBinanceData, binanceOHLCV); ``` -------------------------------- ### Method Chaining for Data Transformation Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt TinyFrameJS supports fluent method chaining for creating readable data transformation pipelines. This allows for sequential application of operations like filtering, selecting, sorting, and aggregation. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ date: ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'], symbol: ['AAPL', 'GOOG', 'AAPL', 'GOOG', 'AAPL'], price: [150, 140, 155, 145, 160], volume: [1000, 800, 1200, 900, 1100] }); // Chain multiple operations const result = df .filter(row => row.volume > 850) // Filter high volume .select(['date', 'symbol', 'price']) // Select columns .sort('price', { descending: true }) // Sort by price desc .head(3); // Take top 3 console.log(result.toArray()); // [ // { date: '2024-01-05', symbol: 'AAPL', price: 160 }, // { date: '2024-01-03', symbol: 'AAPL', price: 155 }, // { date: '2024-01-01', symbol: 'AAPL', price: 150 } // ] // Complex transformation pipeline const analysis = df .filter('row.price > 145') .assign({ value: df.col('price').toArray().map((p, i) => p * df.col('volume').get(i)) }) .groupBy('symbol') .agg({ price: 'mean', volume: 'sum', value: 'sum' }); ``` -------------------------------- ### Apply Function to Create Computed Columns Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Transforms DataFrame rows by applying a function to each row, creating new computed columns like 'total' and 'discounted'. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ price: [10, 20, 30], quantity: [5, 10, 15] }); // Apply function to create computed columns const applied = df.apply(row => ({ ...row, total: row.price * row.quantity, discounted: row.price * 0.9 })); ``` -------------------------------- ### Extend DataFrame with Custom Methods Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Register custom methods to the DataFrame prototype, either at the root or within a specific namespace. ```javascript import { DataFrame } from '@tinyframejs/core'; import { extendDataFrame } from '@tinyframejs/core/utils'; // Creating a method const myCustomMethod = (frame, column, factor = 1) => { // Validation and implementation... return result; }; // Register at the root extendDataFrame(DataFrame.prototype, { myCustomMethod }); // Or in a namespace extendDataFrame(DataFrame.prototype, { myNamespacedMethod }, { namespace: 'custom' }); // Usage const df = new DataFrame({ /* ... */ }); const result1 = df.myCustomMethod('price', 2); const result2 = df.custom.myNamespacedMethod('price'); ``` -------------------------------- ### Reshape Data with Pivot Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Transform long-format data into wide-format using pivot. Supports custom aggregation functions and multi-index columns. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ date: ['2024-01', '2024-01', '2024-02', '2024-02'], symbol: ['AAPL', 'GOOG', 'AAPL', 'GOOG'], price: [150, 140, 155, 145] }); // Basic pivot const pivoted = df.pivot('date', 'symbol', 'price'); // Result: // | date | AAPL | GOOG | // |---------|------|------| // | 2024-01 | 150 | 140 | // | 2024-02 | 155 | 145 | // Pivot with aggregation function (when multiple values exist) const pivotedAgg = df.pivot('date', 'symbol', 'price', arr => arr.reduce((a,b) => a+b, 0) / arr.length); // Object-style parameters const pivotedObj = df.pivot({ index: 'date', columns: 'symbol', values: 'price', aggFunc: values => Math.max(...values) }); // Multiple index columns const multiIndex = df.pivot(['date', 'region'], 'symbol', 'price'); ``` -------------------------------- ### Register Namespaced Methods with extendDataFrame Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Register methods under a specific namespace (e.g., 'ta' for technical analysis) by passing the 'namespace' option to 'extendDataFrame'. This prevents naming conflicts and organizes methods. ```javascript // packages/quant/src/methods/ta/index.js import { DataFrame } from '@tinyframejs/core'; import { extendDataFrame } from '@tinyframejs/core'; import * as taMethods from './pool.js'; // Register methods in the 'ta' namespace extendDataFrame(DataFrame.prototype, taMethods, { namespace: 'ta' }); ``` -------------------------------- ### Group and Aggregate DataFrame by Multiple Columns Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Group data by multiple columns and perform aggregations like mean, sum, and count on specified columns. ```javascript // Grouping by multiple columns const multiGrouped = df.groupBy(['sector', 'region']).aggregate({ price: 'mean', volume: 'sum', count: 'count' }); ``` -------------------------------- ### Exception Handling in Hot Loops Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Avoid using try/catch blocks directly within performance-critical loops. Instead, wrap the potentially error-prone logic in a separate function to minimize overhead. ```javascript function process(data) { // hot path } function safeProcess(data) { try { process(data); } catch (e) { logError(e); } } ``` -------------------------------- ### Efficient Array Allocation Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CODING_GUIDELINES.md Pre-allocate memory for result arrays when the size is known in advance, using TypedArrays for numeric data, to reduce garbage collector pressure compared to dynamically pushing elements. ```javascript // Bad const result = []; for (let i = 0; i < data.length; i++) { result.push(data[i] * 2); } // Good const result = new Float64Array(data.length); for (let i = 0; i < data.length; i++) { result[i] = data[i] * 2; } ``` -------------------------------- ### Categorize Numeric Values into Bins Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Divides numeric data into discrete bins with specified labels. Useful for creating categorical features from continuous data. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ price: [10, 20, 30], quantity: [5, 10, 15] }); // Categorize numeric values into bins const binned = df.cut('price', { bins: [0, 10, 20, 30], labels: ['low', 'medium', 'high'] }); ``` -------------------------------- ### Group DataFrame and Aggregate Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Groups data by one or more columns and applies aggregation functions (sum, mean, count) to specified columns within each group. Supports shorthand methods and custom aggregation functions. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ category: ['A', 'B', 'A', 'B', 'A'], region: ['East', 'East', 'West', 'West', 'East'], sales: [100, 200, 150, 250, 120], units: [10, 20, 15, 25, 12] }); // Group by single column and aggregate const grouped = df.groupBy('category').agg({ sales: 'sum', units: 'mean' }); // Shorthand aggregation methods const salesByCategory = df.groupBy('category').sum('sales'); const avgUnits = df.groupBy('category').mean('units'); const counts = df.groupBy('category').count(); // Group by multiple columns const multiGrouped = df.groupBy(['category', 'region']).agg({ sales: ['sum', 'mean'], units: 'count' }); // Direct groupAgg method (one step) const result = df.groupAgg('category', { sales: 'sum', units: 'mean' }); // Custom aggregation function const custom = df.groupAgg('category', { sales: series => series.values.reduce((a, b) => a + b, 0) / series.length }); // Apply custom function to each group const applied = df.groupBy('category').apply(group => { const profit = group.col('sales').sum() - group.col('units').sum() * 5; return { profit }; }); ``` -------------------------------- ### Group and Aggregate DataFrame by Column Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Perform grouping on a single column and then aggregate specified columns using mean and sum operations. ```javascript // Grouping by one column const grouped = df.groupBy('sector').aggregate({ price: 'mean', volume: 'sum' }); ``` -------------------------------- ### Create DataFrame from Row-Oriented Data Source: https://github.com/alphaquantjs/tinyframejs/blob/main/README.md Create a DataFrame from an array of records (row-oriented data) using the static `fromRecords` method. ```javascript const df = DataFrame.fromRecords([ { price: 10.5, quantity: 100 }, { price: 11.2, quantity: 50 }, // ... ]); ``` -------------------------------- ### Define a New DataFrame Aggregation Method Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Create a new aggregation method for the DataFrame by defining a JavaScript function. Ensure it accepts dependencies like 'validateColumn' and returns a function that operates on the DataFrame and a specified column. ```javascript /** * yourNew - example of a new aggregation method * * @param {{ validateColumn(frame, column): void }} deps - Dependencies * @returns {(frame: DataFrame, column: string) => any} - Function for working with DataFrame */ export const yourNew = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); // Your logic here return; /* result */ }; ``` -------------------------------- ### Define Hotfix Branch Naming Source: https://github.com/alphaquantjs/tinyframejs/blob/main/CONTRIBUTING.md Naming convention for emergency hotfix branches. ```bash hotfix/ ``` -------------------------------- ### Perform Series Operations Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Series objects support element-wise mapping, filtering, and various statistical aggregations. ```javascript import { Series } from 'tinyframejs'; // Create a Series const prices = new Series([10.5, 11.2, 9.8, 12.3, NaN], { name: 'price' }); // Basic operations console.log(prices.length); // 5 console.log(prices.get(0)); // 10.5 console.log(prices.toArray()); // [10.5, 11.2, 9.8, 12.3, NaN] // Map and filter operations const doubled = prices.map(x => x * 2); const filtered = prices.filter(x => x > 10); // Aggregation methods console.log(prices.sum()); // 43.8 console.log(prices.mean()); // 10.95 console.log(prices.min()); // 9.8 console.log(prices.max()); // 12.3 console.log(prices.median()); // 10.85 console.log(prices.std()); // Standard deviation console.log(prices.variance()); // Variance console.log(prices.quantile(0.75)); // 75th percentile console.log(prices.cumsum()); // Cumulative sum series console.log(prices.cumprod()); // Cumulative product series ``` -------------------------------- ### Reshape Data with Melt Source: https://context7.com/alphaquantjs/tinyframejs/llms.txt Unpivot wide-format data into long-format. Specify ID variables to keep and value variables to transform. ```javascript import { DataFrame } from 'tinyframejs'; const df = new DataFrame({ date: ['2024-01', '2024-02'], AAPL: [150, 155], GOOG: [140, 145], MSFT: [380, 390] }); // Melt (wide to long) const melted = df.melt( ['date'], // ID variables (columns to keep) ['AAPL', 'GOOG', 'MSFT'], // Value variables (columns to unpivot) 'symbol', // Name for variable column 'price' // Name for value column ); // Result: // | date | symbol | price | // |---------|--------|-------| // | 2024-01 | AAPL | 150 | // | 2024-01 | GOOG | 140 | // | 2024-01 | MSFT | 380 | // | 2024-02 | AAPL | 155 | // | 2024-02 | GOOG | 145 | // | 2024-02 | MSFT | 390 | // Melt all non-ID columns (valueVars optional) const meltedAll = df.melt(['date']); ```