tardis-dev 16.3.1 → 16.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/consts.d.ts +2 -1
  2. package/dist/consts.d.ts.map +1 -1
  3. package/dist/consts.js +5 -2
  4. package/dist/consts.js.map +1 -1
  5. package/dist/handy.d.ts +9 -0
  6. package/dist/handy.d.ts.map +1 -1
  7. package/dist/handy.js +15 -0
  8. package/dist/handy.js.map +1 -1
  9. package/dist/mappers/bullish.d.ts +161 -0
  10. package/dist/mappers/bullish.d.ts.map +1 -0
  11. package/dist/mappers/bullish.js +218 -0
  12. package/dist/mappers/bullish.js.map +1 -0
  13. package/dist/mappers/bybit.d.ts +2 -2
  14. package/dist/mappers/bybitspot.d.ts +1 -1
  15. package/dist/mappers/cryptocom.d.ts +1 -1
  16. package/dist/mappers/huobi.d.ts +3 -3
  17. package/dist/mappers/index.d.ts +6 -0
  18. package/dist/mappers/index.d.ts.map +1 -1
  19. package/dist/mappers/index.js +10 -4
  20. package/dist/mappers/index.js.map +1 -1
  21. package/dist/realtimefeeds/bullish.d.ts +18 -0
  22. package/dist/realtimefeeds/bullish.d.ts.map +1 -0
  23. package/dist/realtimefeeds/bullish.js +113 -0
  24. package/dist/realtimefeeds/bullish.js.map +1 -0
  25. package/dist/realtimefeeds/index.d.ts.map +1 -1
  26. package/dist/realtimefeeds/index.js +3 -1
  27. package/dist/realtimefeeds/index.js.map +1 -1
  28. package/dist/types.d.ts +1 -0
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/worker.d.ts.map +1 -1
  31. package/dist/worker.js +52 -43
  32. package/dist/worker.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/consts.ts +6 -2
  35. package/src/handy.ts +17 -0
  36. package/src/mappers/bullish.ts +374 -0
  37. package/src/mappers/index.ts +16 -4
  38. package/src/realtimefeeds/bullish.ts +140 -0
  39. package/src/realtimefeeds/index.ts +3 -1
  40. package/src/types.ts +2 -1
  41. package/src/worker.ts +82 -54
package/src/worker.ts CHANGED
@@ -28,6 +28,7 @@ process.on('unhandledRejection', (err, promise) => {
28
28
 
29
29
  async function getDataFeedSlices(payload: WorkerJobPayload) {
30
30
  const MILLISECONDS_IN_MINUTE = 60 * 1000
31
+ const MIN_WAIT_WHEN_DATA_NOT_AVAILABLE_OFFSET = 6
31
32
  const CONCURRENCY_LIMIT = 60
32
33
  // deduplicate filters (if the channel was provided multiple times)
33
34
  const filters = optimizeFilters(payload.filters)
@@ -39,70 +40,97 @@ async function getDataFeedSlices(payload: WorkerJobPayload) {
39
40
  // each filter will have separate sub dir based on it's sha hash
40
41
  const cacheDir = `${payload.cacheDir}/feeds/${payload.exchange}/${sha256(filters)}`
41
42
 
42
- const waitOffsetMS =
43
+ const waitOffsetMinutes =
43
44
  typeof payload.waitWhenDataNotYetAvailable === 'number'
44
- ? payload.waitWhenDataNotYetAvailable * MILLISECONDS_IN_MINUTE
45
- : 30 * MILLISECONDS_IN_MINUTE
46
-
47
- if (payload.waitWhenDataNotYetAvailable && payload.toDate.valueOf() > new Date().valueOf() - waitOffsetMS) {
48
- let timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
49
-
50
- // in case when even initial from date is not yet available wait until it is
51
- if (timestampForLastAvailableData < payload.fromDate.valueOf()) {
52
- const initialWaitTime = payload.fromDate.valueOf() - timestampForLastAvailableData
53
- if (initialWaitTime > 0) {
54
- await wait(initialWaitTime)
55
- }
56
- }
45
+ ? Math.max(payload.waitWhenDataNotYetAvailable, MIN_WAIT_WHEN_DATA_NOT_AVAILABLE_OFFSET)
46
+ : 30
47
+ const waitOffsetMS = waitOffsetMinutes * MILLISECONDS_IN_MINUTE
57
48
 
58
- // fetch concurently any data that is already available
59
- timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
60
- const minutesCountThatAreAlreadyAvailableToFetch = Math.floor(
61
- (timestampForLastAvailableData - payload.fromDate.valueOf()) / MILLISECONDS_IN_MINUTE
62
- )
49
+ const minutesCountThatAreAlreadyAvailableToFetch = await getAvailableMinutesCount(
50
+ payload,
51
+ minutesCountToFetch,
52
+ waitOffsetMS,
53
+ MILLISECONDS_IN_MINUTE
54
+ )
63
55
 
64
- await pMap(sequence(minutesCountThatAreAlreadyAvailableToFetch, 0), (offset) => getDataFeedSlice(payload, offset, filters, cacheDir), {
65
- concurrency: CONCURRENCY_LIMIT
66
- })
56
+ await getAvailableDataFeedSlices(payload, filters, cacheDir, minutesCountThatAreAlreadyAvailableToFetch, CONCURRENCY_LIMIT)
67
57
 
68
- // for remaining data iterate one by one and wait as needed
69
- for (let offset = minutesCountThatAreAlreadyAvailableToFetch; offset < minutesCountToFetch; offset++) {
70
- const timestampToFetch = payload.fromDate.valueOf() + offset * MILLISECONDS_IN_MINUTE
71
- timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
58
+ // for remaining data iterate one by one and wait as needed
59
+ for (let offset = minutesCountThatAreAlreadyAvailableToFetch; offset < minutesCountToFetch; offset++) {
60
+ const timestampToFetch = payload.fromDate.valueOf() + offset * MILLISECONDS_IN_MINUTE
61
+ const timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
72
62
 
73
- if (timestampToFetch > timestampForLastAvailableData) {
74
- const waitTime = timestampToFetch - timestampForLastAvailableData + 100
63
+ if (timestampToFetch > timestampForLastAvailableData) {
64
+ const waitTime = timestampToFetch - timestampForLastAvailableData + 100
75
65
 
76
- await wait(waitTime)
77
- }
78
- await getDataFeedSlice(payload, offset, filters, cacheDir)
66
+ await wait(waitTime)
79
67
  }
80
- } else {
81
- // fetch last slice - it will tell us if user has access to the end of requested date range and data is available
82
- // also fetch it from API to get current suggested slice size headers
83
- const lastSlice = await getDataFeedSlice(payload, minutesCountToFetch - 1, filters, cacheDir, DEFAULT_DATA_FEED_SLICE_SIZE, false)
84
-
85
- // fetch first slice - it will tell us if user has access to the beginning of requested date range
86
- const firstSlice =
87
- minutesCountToFetch === 1 ? lastSlice : await getDataFeedSlice(payload, 0, filters, cacheDir, DEFAULT_DATA_FEED_SLICE_SIZE, false)
88
-
89
- const replaySliceSize =
90
- filters.length === 0 ? DEFAULT_DATA_FEED_SLICE_SIZE : Math.max(firstSlice.suggestedSliceSize, lastSlice.suggestedSliceSize)
91
- const sliceOffsets: number[] = []
92
- for (let offset = 1; offset < minutesCountToFetch - 1; offset += replaySliceSize) {
93
- sliceOffsets.push(offset)
68
+ await getDataFeedSlice(payload, offset, filters, cacheDir)
69
+ }
70
+ }
71
+
72
+ async function getAvailableMinutesCount(
73
+ payload: WorkerJobPayload,
74
+ minutesCountToFetch: number,
75
+ waitOffsetMS: number,
76
+ millisecondsInMinute: number
77
+ ) {
78
+ const waitWhenDataIsNotAvailable = payload.waitWhenDataNotYetAvailable && payload.toDate.valueOf() > new Date().valueOf() - waitOffsetMS
79
+ if (!waitWhenDataIsNotAvailable) {
80
+ return minutesCountToFetch
81
+ }
82
+
83
+ let timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
84
+
85
+ // in case when even initial from date is not yet available wait until it is
86
+ if (timestampForLastAvailableData < payload.fromDate.valueOf()) {
87
+ const initialWaitTime = payload.fromDate.valueOf() - timestampForLastAvailableData
88
+ if (initialWaitTime > 0) {
89
+ await wait(initialWaitTime)
94
90
  }
91
+ }
95
92
 
96
- // it both begining and end date of the range is accessible fetch all remaning slices concurently with CONCURRENCY_LIMIT
97
- await pMap(
98
- sliceOffsets,
99
- async (offset) => {
100
- const requestedSliceSize = Math.min(replaySliceSize, minutesCountToFetch - 1 - offset)
101
- await getDataFeedSlice(payload, offset, filters, cacheDir, requestedSliceSize)
102
- },
103
- { concurrency: CONCURRENCY_LIMIT }
104
- )
93
+ // fetch concurently any data that is already available
94
+ timestampForLastAvailableData = new Date().valueOf() - waitOffsetMS
95
+ const availableMinutesCount = Math.floor((timestampForLastAvailableData - payload.fromDate.valueOf()) / millisecondsInMinute)
96
+ return Math.min(Math.max(availableMinutesCount, 0), minutesCountToFetch)
97
+ }
98
+
99
+ async function getAvailableDataFeedSlices(
100
+ payload: WorkerJobPayload,
101
+ filters: object[],
102
+ cacheDir: string,
103
+ minutesCountToFetch: number,
104
+ concurrencyLimit: number
105
+ ) {
106
+ if (minutesCountToFetch <= 0) {
107
+ return
105
108
  }
109
+
110
+ // fetch last slice - it will tell us if user has access to the end of requested date range and data is available
111
+ // also fetch it from API to get current suggested slice size headers
112
+ const lastSlice = await getDataFeedSlice(payload, minutesCountToFetch - 1, filters, cacheDir, DEFAULT_DATA_FEED_SLICE_SIZE, false)
113
+
114
+ // fetch first slice - it will tell us if user has access to the beginning of requested date range
115
+ const firstSlice =
116
+ minutesCountToFetch === 1 ? lastSlice : await getDataFeedSlice(payload, 0, filters, cacheDir, DEFAULT_DATA_FEED_SLICE_SIZE, false)
117
+
118
+ const replaySliceSize =
119
+ filters.length === 0 ? DEFAULT_DATA_FEED_SLICE_SIZE : Math.max(firstSlice.suggestedSliceSize, lastSlice.suggestedSliceSize)
120
+ const sliceOffsets: number[] = []
121
+ for (let offset = 1; offset < minutesCountToFetch - 1; offset += replaySliceSize) {
122
+ sliceOffsets.push(offset)
123
+ }
124
+
125
+ // it both begining and end date of the range is accessible fetch all remaning slices concurently with CONCURRENCY_LIMIT
126
+ await pMap(
127
+ sliceOffsets,
128
+ async (offset) => {
129
+ const requestedSliceSize = Math.min(replaySliceSize, minutesCountToFetch - 1 - offset)
130
+ await getDataFeedSlice(payload, offset, filters, cacheDir, requestedSliceSize)
131
+ },
132
+ { concurrency: concurrencyLimit }
133
+ )
106
134
  }
107
135
 
108
136
  async function getDataFeedSlice(