Skip to content

Commit 836f01a

Browse files
authored
Merge pull request #8 from AlphaQuantJS/dev
Dev
2 parents 3b8db71 + 53974da commit 836f01a

File tree

110 files changed

+9356
-860
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+9356
-860
lines changed

docs/io-module.md

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
# IO Module Documentation
2+
3+
## Обзор
4+
5+
IO модуль TinyFrameJS предоставляет инструменты для чтения, преобразования и записи данных из различных источников. Модуль включает в себя:
6+
7+
- **Readers** - функции для чтения данных из различных источников (CSV, JSON, Excel и т.д.)
8+
- **Stream Readers** - функции для потоковой обработки больших файлов
9+
- **API Client** - клиент для работы с REST API с поддержкой кеширования, троттлинга и ротации ключей
10+
- **Schema Registry** - реестр схем для автоматического преобразования данных из различных API
11+
- **Transformers** - функции для преобразования данных между различными форматами
12+
- **Pipeline** - конвейер для последовательной обработки данных
13+
14+
## Readers
15+
16+
### Базовые ридеры
17+
18+
```javascript
19+
import { readCsv, readJson, readExcel, readTsv, readSql } from 'tinyframejs/io';
20+
21+
// Чтение CSV файла
22+
const df = await readCsv('data.csv');
23+
24+
// Чтение JSON файла
25+
const df = await readJson('data.json');
26+
27+
// Чтение Excel файла
28+
const df = await readExcel('data.xlsx', { sheet: 'Sheet1' });
29+
30+
// Чтение TSV файла
31+
const df = await readTsv('data.tsv');
32+
33+
// Чтение SQL запроса
34+
const df = await readSql('SELECT * FROM table', connection);
35+
```
36+
37+
### Потоковые ридеры
38+
39+
Для обработки больших файлов без загрузки их полностью в память:
40+
41+
```javascript
42+
import { readCSVStream, readJSONLStream } from 'tinyframejs/io';
43+
44+
// Потоковое чтение CSV файла
45+
await readCSVStream('large-data.csv', {
46+
batchSize: 1000,
47+
onBatch: async (batch) => {
48+
// Обработка каждой партии данных
49+
console.log(`Обработано ${batch.rowCount} строк`);
50+
51+
// Можно вернуть результат обработки
52+
return batch.sum('value');
53+
}
54+
});
55+
56+
// Потоковое чтение JSONL файла
57+
await readJSONLStream('large-data.jsonl', {
58+
batchSize: 500,
59+
onBatch: async (batch) => {
60+
// Обработка каждой партии данных
61+
await processData(batch);
62+
}
63+
});
64+
```
65+
66+
## API Client
67+
68+
API клиент предоставляет унифицированный интерфейс для работы с REST API, включая кеширование, троттлинг и ротацию ключей.
69+
70+
```javascript
71+
import { ApiClient, createApiClient } from 'tinyframejs/io';
72+
73+
// Создание клиента
74+
const client = createApiClient({
75+
baseUrl: 'https://api.example.com',
76+
defaultHeaders: {
77+
'Content-Type': 'application/json',
78+
'Accept': 'application/json'
79+
},
80+
// Настройки аутентификации
81+
auth: {
82+
keys: [
83+
{ id: 'key1', key: 'api-key-1' },
84+
{ id: 'key2', key: 'api-key-2' }
85+
],
86+
authType: 'bearer' // 'bearer', 'basic', 'header', 'query'
87+
},
88+
// Настройки кеширования
89+
cache: {
90+
ttl: 3600000, // 1 час
91+
maxSize: 100 // максимальное количество элементов в кеше
92+
},
93+
// Настройки троттлинга
94+
throttle: {
95+
requestsPerSecond: 5,
96+
requestsPerMinute: 100
97+
},
98+
// Настройки повторных попыток
99+
retry: {
100+
retries: 3,
101+
retryDelay: 1000,
102+
retryOn: [429, 503]
103+
}
104+
});
105+
106+
// Выполнение запросов
107+
const data = await client.fetchJson('/endpoint');
108+
109+
// Выполнение запроса с преобразованием в DataFrame
110+
const df = await client.fetchDataFrame('/endpoint');
111+
112+
// Выполнение запроса с применением схемы
113+
const data = await client.fetchJson('/endpoint', {}, 'binanceOHLCV');
114+
115+
// Выполнение запроса с получением CSV данных
116+
const df = await client.fetchCsv('/endpoint.csv');
117+
```
118+
119+
## Schema Registry
120+
121+
Реестр схем позволяет автоматически преобразовывать данные из различных API к стандартному формату.
122+
123+
```javascript
124+
import {
125+
getSchema,
126+
registerSchema,
127+
applySchema,
128+
binanceOHLCV,
129+
alphaVantageDaily
130+
} from 'tinyframejs/io';
131+
132+
// Получение схемы по имени
133+
const schema = getSchema('binanceOHLCV');
134+
135+
// Регистрация новой схемы
136+
registerSchema('myApiSchema', {
137+
timestamp: 'time',
138+
value: {
139+
path: 'data.value',
140+
transform: (value) => parseFloat(value)
141+
},
142+
name: (obj) => `${obj.type}-${obj.id}`
143+
});
144+
145+
// Применение схемы к данным
146+
const data = await client.fetchJson('/endpoint');
147+
const transformed = applySchema(data, 'myApiSchema');
148+
149+
// Применение встроенной схемы
150+
const binanceData = await client.fetchJson('/binance/klines');
151+
const standardized = applySchema(binanceData, binanceOHLCV);
152+
```
153+
154+
## Pipeline
155+
156+
Конвейер позволяет создавать цепочки обработки данных для ETL процессов.
157+
158+
```javascript
159+
import {
160+
createPipeline,
161+
filter,
162+
map,
163+
sort,
164+
limit,
165+
toDataFrame,
166+
log
167+
} from 'tinyframejs/io';
168+
import { readCsv } from 'tinyframejs/io';
169+
170+
// Создание конвейера
171+
const pipeline = createPipeline(
172+
// Ридер
173+
() => readCsv('data.csv'),
174+
// Трансформеры
175+
[
176+
filter(row => row.value > 0),
177+
map(row => ({ ...row, value: row.value * 2 })),
178+
sort('timestamp'),
179+
limit(1000),
180+
log('Processed data:'),
181+
toDataFrame()
182+
]
183+
);
184+
185+
// Выполнение конвейера
186+
const result = await pipeline();
187+
```
188+
189+
## Batch Processing
190+
191+
Для обработки данных партиями:
192+
193+
```javascript
194+
import { batchProcess } from 'tinyframejs/io';
195+
import { readCSVStream } from 'tinyframejs/io';
196+
197+
// Обработка данных партиями
198+
const results = await batchProcess(
199+
// Ридер
200+
(options) => readCSVStream('large-data.csv', options),
201+
// Обработчик партии
202+
async (batch) => {
203+
// Обработка партии данных
204+
return batch.sum('value');
205+
},
206+
// Опции
207+
{
208+
batchSize: 1000,
209+
onProgress: ({ processedCount, batchCount }) => {
210+
console.log(`Processed ${processedCount} rows in ${batchCount} batches`);
211+
}
212+
}
213+
);
214+
215+
// Результаты содержат массив результатов обработки каждой партии
216+
console.log(`Total sum: ${results.reduce((sum, val) => sum + val, 0)}`);
217+
```
218+
219+
## Middleware Hooks
220+
221+
Хуки (middleware) позволяют расширять функциональность API клиента.
222+
223+
### Logger Hook
224+
225+
```javascript
226+
import { createLoggerHook } from 'tinyframejs/io';
227+
228+
const loggerHook = createLoggerHook({
229+
logRequest: true,
230+
logResponse: true,
231+
logErrors: true,
232+
logTiming: true,
233+
logger: console.log
234+
});
235+
236+
client.addHook(loggerHook);
237+
```
238+
239+
### Cache Hook
240+
241+
```javascript
242+
import { createCacheHook, MemoryCache } from 'tinyframejs/io';
243+
244+
const cache = new MemoryCache({
245+
ttl: 3600000, // 1 час
246+
maxSize: 100
247+
});
248+
249+
const cacheHook = createCacheHook({
250+
cache,
251+
ttl: 3600000,
252+
keyGenerator: (request) => `${request.method}:${request.url}`,
253+
shouldCache: (request) => request.method === 'GET'
254+
});
255+
256+
client.addHook(cacheHook);
257+
```
258+
259+
### Throttle Hook
260+
261+
```javascript
262+
import { createThrottleHook } from 'tinyframejs/io';
263+
264+
const throttleHook = createThrottleHook({
265+
requestsPerSecond: 5,
266+
requestsPerMinute: 100,
267+
requestsPerHour: 1000,
268+
groupByDomain: true,
269+
onThrottle: (waitTime) => console.log(`Request throttled. Waiting ${waitTime}ms`)
270+
});
271+
272+
client.addHook(throttleHook);
273+
```
274+
275+
### Auth Hook
276+
277+
```javascript
278+
import { createAuthHook, KeyRotator } from 'tinyframejs/io';
279+
280+
const authHook = createAuthHook({
281+
keys: [
282+
{ id: 'key1', key: 'api-key-1' },
283+
{ id: 'key2', key: 'api-key-2' }
284+
],
285+
authType: 'bearer', // 'bearer', 'basic', 'header', 'query'
286+
headerName: 'Authorization',
287+
queryParam: 'api_key',
288+
maxErrorsBeforeDisable: 3,
289+
resetErrorsAfter: 3600000, // 1 час
290+
rotationStrategy: 'round-robin' // 'round-robin', 'least-used', 'random'
291+
});
292+
293+
client.addHook(authHook);
294+
```
295+
296+
## Примеры использования
297+
298+
### Загрузка и обработка данных о ценах криптовалют
299+
300+
```javascript
301+
import { createApiClient, applySchema, binanceOHLCV } from 'tinyframejs/io';
302+
303+
async function getBitcoinPrices() {
304+
const client = createApiClient({
305+
baseUrl: 'https://api.binance.com',
306+
cache: { ttl: 300000 }, // 5 минут
307+
throttle: { requestsPerMinute: 60 }
308+
});
309+
310+
// Получение данных
311+
const data = await client.fetchJson('/api/v3/klines?symbol=BTCUSDT&interval=1d&limit=30');
312+
313+
// Применение схемы
314+
const standardized = applySchema(data, binanceOHLCV);
315+
316+
// Преобразование в DataFrame
317+
return DataFrame.fromRows(standardized);
318+
}
319+
320+
// Использование
321+
const btcPrices = await getBitcoinPrices();
322+
btcPrices.plot('line', { x: 'timestamp', y: 'close' });
323+
```
324+
325+
### Потоковая обработка большого CSV файла
326+
327+
```javascript
328+
import { readCSVStream, batchProcess } from 'tinyframejs/io';
329+
330+
async function processLargeCSV(filePath) {
331+
let total = 0;
332+
let count = 0;
333+
334+
await batchProcess(
335+
(options) => readCSVStream(filePath, options),
336+
async (batch) => {
337+
// Вычисление среднего значения для каждой партии
338+
const batchSum = batch.sum('value');
339+
const batchCount = batch.rowCount;
340+
341+
total += batchSum;
342+
count += batchCount;
343+
344+
return { batchSum, batchCount };
345+
},
346+
{
347+
batchSize: 10000,
348+
onProgress: ({ processedCount }) => {
349+
console.log(`Processed ${processedCount} rows`);
350+
}
351+
}
352+
);
353+
354+
return total / count; // Среднее значение по всему файлу
355+
}
356+
357+
// Использование
358+
const average = await processLargeCSV('very-large-file.csv');
359+
console.log(`Average value: ${average}`);
360+
```

0 commit comments

Comments
 (0)