dukascopy-node-plus 1.1.0 → 1.1.1

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.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -13706,158 +13706,168 @@ var import_debug = __toESM(require("debug"));
13706
13706
  var import_stream = require("stream");
13707
13707
  var import_promises = require("stream/promises");
13708
13708
  var DEBUG_NAMESPACE = "dukascopy-node";
13709
- async function getHistoricalRatesToStream(config) {
13709
+ function getHistoricalRatesToStream(config) {
13710
13710
  const stream = new import_stream.Readable({
13711
13711
  objectMode: true,
13712
13712
  async read(_size) {
13713
- try {
13714
- const { input, isValid, validationErrors } = validateConfigNode(config);
13715
- (0, import_debug.default)(`${DEBUG_NAMESPACE}:config`)("%O", {
13716
- input,
13717
- isValid,
13718
- validationErrors
13719
- });
13720
- if (!isValid) {
13721
- this.emit("error", { validationErrors });
13722
- this.push(null);
13723
- return;
13724
- }
13725
- const {
13726
- instrument,
13727
- dates: { from, to },
13728
- timeframe,
13729
- priceType,
13730
- volumes,
13731
- volumeUnits,
13732
- utcOffset,
13733
- ignoreFlats,
13734
- format,
13735
- batchSize,
13736
- pauseBetweenBatchesMs,
13737
- useCache,
13738
- cacheFolderPath,
13739
- retryCount,
13740
- pauseBetweenRetriesMs,
13741
- retryOnEmpty
13742
- } = input;
13743
- const [startDate, endDate] = normaliseDates({
13744
- instrument,
13745
- startDate: from,
13746
- endDate: to,
13747
- timeframe,
13748
- utcOffset
13749
- });
13750
- const [startDateMs, endDateMs] = [+startDate, +endDate];
13751
- const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
13752
- (0, import_debug.default)(`${DEBUG_NAMESPACE}:fetcher`)(
13713
+ }
13714
+ });
13715
+ try {
13716
+ const { input, isValid, validationErrors } = validateConfigNode(config);
13717
+ (0, import_debug.default)(`${DEBUG_NAMESPACE}:config`)("%O", {
13718
+ input,
13719
+ isValid,
13720
+ validationErrors
13721
+ });
13722
+ if (!isValid) {
13723
+ stream.emit("error", { validationErrors });
13724
+ stream.push(null);
13725
+ return stream;
13726
+ }
13727
+ const {
13728
+ instrument,
13729
+ dates: { from, to },
13730
+ timeframe,
13731
+ priceType,
13732
+ volumes,
13733
+ volumeUnits,
13734
+ utcOffset,
13735
+ ignoreFlats,
13736
+ format,
13737
+ batchSize,
13738
+ pauseBetweenBatchesMs,
13739
+ useCache,
13740
+ cacheFolderPath,
13741
+ retryCount,
13742
+ pauseBetweenRetriesMs,
13743
+ retryOnEmpty
13744
+ } = input;
13745
+ const [startDate, endDate] = normaliseDates({
13746
+ instrument,
13747
+ startDate: from,
13748
+ endDate: to,
13749
+ timeframe,
13750
+ utcOffset
13751
+ });
13752
+ const [startDateMs, endDateMs] = [+startDate, +endDate];
13753
+ const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
13754
+ (0, import_debug.default)(`${DEBUG_NAMESPACE}:fetcher`)(
13755
+ url,
13756
+ `| ${formatBytes(buffer.length)} |`,
13757
+ `${isCacheHit ? "cache" : "network"}`
13758
+ );
13759
+ } : void 0;
13760
+ const bufferFetcher = new BufferFetcher({
13761
+ batchSize,
13762
+ pauseBetweenBatchesMs,
13763
+ cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
13764
+ retryCount,
13765
+ pauseBetweenRetriesMs,
13766
+ onItemFetch,
13767
+ retryOnEmpty
13768
+ });
13769
+ const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
13770
+ let firstLine = true;
13771
+ let urlsProcessed = 0;
13772
+ const urlsforFetchingData = generateUrls({
13773
+ instrument: input.instrument,
13774
+ timeframe: input.timeframe,
13775
+ priceType: input.priceType,
13776
+ startDate,
13777
+ endDate
13778
+ });
13779
+ (0, import_promises.pipeline)(
13780
+ import_stream.Readable.from(urlsforFetchingData),
13781
+ new import_stream.Transform({
13782
+ objectMode: true,
13783
+ transform: async (url, _, callback) => {
13784
+ const bufferObject = {
13753
13785
  url,
13754
- `| ${formatBytes(buffer.length)} |`,
13755
- `${isCacheHit ? "cache" : "network"}`
13756
- );
13757
- } : void 0;
13758
- const bufferFetcher = new BufferFetcher({
13759
- batchSize,
13760
- pauseBetweenBatchesMs,
13761
- cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
13762
- retryCount,
13763
- pauseBetweenRetriesMs,
13764
- onItemFetch,
13765
- retryOnEmpty
13766
- });
13767
- let firstLine = true;
13768
- let urlsProcessed = 0;
13769
- const urlsforFetchingData = generateUrls({
13770
- instrument: input.instrument,
13771
- timeframe: input.timeframe,
13772
- priceType: input.priceType,
13773
- startDate,
13774
- endDate
13775
- });
13776
- await (0, import_promises.pipeline)(
13777
- import_stream.Readable.from(urlsforFetchingData),
13778
- new import_stream.Transform({
13779
- objectMode: true,
13780
- transform: async (url, _, callback) => {
13781
- const bufferObject = {
13782
- url,
13783
- buffer: await bufferFetcher.fetchBuffer(url),
13784
- isCacheHit: useCache
13785
- };
13786
- try {
13787
- const processedData = processData({
13788
- instrument: input.instrument,
13789
- requestedTimeframe: input.timeframe,
13790
- bufferObjects: [bufferObject],
13791
- priceType: input.priceType,
13792
- volumes: input.volumes,
13793
- volumeUnits: input.volumeUnits,
13794
- ignoreFlats: input.ignoreFlats
13795
- });
13796
- processedData.forEach((item) => {
13797
- const [timestamp] = item;
13798
- if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
13799
- if (input.format === "array" /* array */) {
13800
- this.push(item);
13801
- } else {
13802
- const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
13803
- if (format === "json" /* json */) {
13804
- const data = item.reduce((all, item2, i) => {
13805
- const name = bodyHeaders[i];
13806
- all[name] = item2;
13807
- return all;
13808
- }, {});
13809
- this.push(data);
13810
- } else if (format === "csv" /* csv */) {
13811
- if (firstLine) {
13812
- const csvHeaders = bodyHeaders.join(",");
13813
- this.push(csvHeaders);
13814
- firstLine = false;
13815
- }
13816
- this.push(item.join(","));
13817
- }
13818
- }
13786
+ buffer: await bufferFetcher.fetchBuffer(url),
13787
+ isCacheHit: useCache
13788
+ };
13789
+ try {
13790
+ const processedData = processData({
13791
+ instrument: input.instrument,
13792
+ requestedTimeframe: input.timeframe,
13793
+ bufferObjects: [bufferObject],
13794
+ priceType: input.priceType,
13795
+ volumes: input.volumes,
13796
+ volumeUnits: input.volumeUnits,
13797
+ ignoreFlats: input.ignoreFlats
13798
+ });
13799
+ processedData.forEach((item) => {
13800
+ const [timestamp] = item;
13801
+ if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
13802
+ if (input.format === "array" /* array */) {
13803
+ stream.push(item);
13804
+ } else if (format === "json" /* json */) {
13805
+ const data = item.reduce((all, item2, i) => {
13806
+ const name = bodyHeaders[i];
13807
+ all[name] = item2;
13808
+ return all;
13809
+ }, {});
13810
+ stream.push(data);
13811
+ } else if (format === "csv" /* csv */) {
13812
+ if (firstLine) {
13813
+ const csvHeaders = bodyHeaders.join(",");
13814
+ stream.push(csvHeaders);
13815
+ firstLine = false;
13819
13816
  }
13820
- });
13821
- callback();
13822
- } catch (err) {
13823
- callback(err);
13817
+ stream.push(`
13818
+ ${item.join(",")}`);
13819
+ }
13824
13820
  }
13821
+ });
13822
+ if (++urlsProcessed === urlsforFetchingData.length) {
13823
+ stream.push(null);
13825
13824
  }
13826
- })
13827
- ).then(() => {
13828
- if (++urlsProcessed === urlsforFetchingData.length) {
13829
- this.push(null);
13825
+ callback();
13826
+ } catch (err) {
13827
+ callback(err);
13830
13828
  }
13831
- }).catch((err) => {
13832
- this.emit("error", err);
13833
- this.push(null);
13834
- });
13835
- } catch (err) {
13836
- this.emit("error", err);
13837
- this.push(null);
13838
- }
13839
- }
13840
- });
13829
+ }
13830
+ })
13831
+ ).catch((err) => {
13832
+ stream.emit("error", err);
13833
+ stream.push(null);
13834
+ });
13835
+ } catch (err) {
13836
+ stream.emit("error", err);
13837
+ stream.push(null);
13838
+ }
13841
13839
  return stream;
13842
13840
  }
13843
13841
 
13844
- // src/index.example.ts
13842
+ // src/index.example.stream.ts
13843
+ var printMemory = () => {
13844
+ const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
13845
+ const memoryData = process.memoryUsage();
13846
+ const memoryUsage = {
13847
+ rss: `${formatMemoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated for the process execution`,
13848
+ heapTotal: `${formatMemoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`,
13849
+ heapUsed: `${formatMemoryUsage(memoryData.heapUsed)} -> actual memory used during the execution`,
13850
+ external: `${formatMemoryUsage(memoryData.external)} -> V8 external memory`
13851
+ };
13852
+ console.log(memoryUsage);
13853
+ };
13845
13854
  (async () => {
13846
13855
  try {
13856
+ printMemory();
13847
13857
  const data = await getHistoricalRatesToStream({
13848
13858
  instrument: "eurusd",
13849
13859
  dates: {
13850
13860
  from: /* @__PURE__ */ new Date("2021-02-01"),
13851
- to: /* @__PURE__ */ new Date("2021-03-01")
13861
+ to: /* @__PURE__ */ new Date("2021-02-03")
13852
13862
  },
13853
- timeframe: "d1",
13863
+ timeframe: "m1",
13854
13864
  format: "csv"
13855
13865
  });
13856
- data.on("data", (chunk) => {
13857
- console.log(chunk);
13866
+ data.on("data", (_chunk) => {
13867
+ process.stdout.write(_chunk);
13858
13868
  });
13859
13869
  data.on("end", () => {
13860
- console.log("end");
13870
+ printMemory();
13861
13871
  });
13862
13872
  } catch (error) {
13863
13873
  console.log("error", error);
package/dist/index.js CHANGED
@@ -13767,7 +13767,7 @@ function formatBytes(bytes, decimals = 2) {
13767
13767
  }
13768
13768
 
13769
13769
  // package.json
13770
- var version = "1.1.0";
13770
+ var version = "1.1.1";
13771
13771
 
13772
13772
  // src/getHistoricalRates.ts
13773
13773
  var import_debug = __toESM(require("debug"));
@@ -13990,138 +13990,136 @@ var import_debug2 = __toESM(require("debug"));
13990
13990
  var import_stream = require("stream");
13991
13991
  var import_promises = require("stream/promises");
13992
13992
  var DEBUG_NAMESPACE2 = "dukascopy-node";
13993
- async function getHistoricalRatesToStream(config) {
13993
+ function getHistoricalRatesToStream(config) {
13994
13994
  const stream = new import_stream.Readable({
13995
13995
  objectMode: true,
13996
13996
  async read(_size) {
13997
- try {
13998
- const { input, isValid, validationErrors } = validateConfigNode(config);
13999
- (0, import_debug2.default)(`${DEBUG_NAMESPACE2}:config`)("%O", {
14000
- input,
14001
- isValid,
14002
- validationErrors
14003
- });
14004
- if (!isValid) {
14005
- this.emit("error", { validationErrors });
14006
- this.push(null);
14007
- return;
14008
- }
14009
- const {
14010
- instrument,
14011
- dates: { from, to },
14012
- timeframe,
14013
- priceType,
14014
- volumes,
14015
- volumeUnits,
14016
- utcOffset,
14017
- ignoreFlats,
14018
- format,
14019
- batchSize,
14020
- pauseBetweenBatchesMs,
14021
- useCache,
14022
- cacheFolderPath,
14023
- retryCount,
14024
- pauseBetweenRetriesMs,
14025
- retryOnEmpty
14026
- } = input;
14027
- const [startDate, endDate] = normaliseDates({
14028
- instrument,
14029
- startDate: from,
14030
- endDate: to,
14031
- timeframe,
14032
- utcOffset
14033
- });
14034
- const [startDateMs, endDateMs] = [+startDate, +endDate];
14035
- const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
14036
- (0, import_debug2.default)(`${DEBUG_NAMESPACE2}:fetcher`)(
13997
+ }
13998
+ });
13999
+ try {
14000
+ const { input, isValid, validationErrors } = validateConfigNode(config);
14001
+ (0, import_debug2.default)(`${DEBUG_NAMESPACE2}:config`)("%O", {
14002
+ input,
14003
+ isValid,
14004
+ validationErrors
14005
+ });
14006
+ if (!isValid) {
14007
+ stream.emit("error", { validationErrors });
14008
+ stream.push(null);
14009
+ return stream;
14010
+ }
14011
+ const {
14012
+ instrument,
14013
+ dates: { from, to },
14014
+ timeframe,
14015
+ priceType,
14016
+ volumes,
14017
+ volumeUnits,
14018
+ utcOffset,
14019
+ ignoreFlats,
14020
+ format,
14021
+ batchSize,
14022
+ pauseBetweenBatchesMs,
14023
+ useCache,
14024
+ cacheFolderPath,
14025
+ retryCount,
14026
+ pauseBetweenRetriesMs,
14027
+ retryOnEmpty
14028
+ } = input;
14029
+ const [startDate, endDate] = normaliseDates({
14030
+ instrument,
14031
+ startDate: from,
14032
+ endDate: to,
14033
+ timeframe,
14034
+ utcOffset
14035
+ });
14036
+ const [startDateMs, endDateMs] = [+startDate, +endDate];
14037
+ const onItemFetch = process.env.DEBUG ? (url, buffer, isCacheHit) => {
14038
+ (0, import_debug2.default)(`${DEBUG_NAMESPACE2}:fetcher`)(
14039
+ url,
14040
+ `| ${formatBytes(buffer.length)} |`,
14041
+ `${isCacheHit ? "cache" : "network"}`
14042
+ );
14043
+ } : void 0;
14044
+ const bufferFetcher = new BufferFetcher({
14045
+ batchSize,
14046
+ pauseBetweenBatchesMs,
14047
+ cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
14048
+ retryCount,
14049
+ pauseBetweenRetriesMs,
14050
+ onItemFetch,
14051
+ retryOnEmpty
14052
+ });
14053
+ const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
14054
+ let firstLine = true;
14055
+ let urlsProcessed = 0;
14056
+ const urlsforFetchingData = generateUrls({
14057
+ instrument: input.instrument,
14058
+ timeframe: input.timeframe,
14059
+ priceType: input.priceType,
14060
+ startDate,
14061
+ endDate
14062
+ });
14063
+ (0, import_promises.pipeline)(
14064
+ import_stream.Readable.from(urlsforFetchingData),
14065
+ new import_stream.Transform({
14066
+ objectMode: true,
14067
+ transform: async (url, _, callback) => {
14068
+ const bufferObject = {
14037
14069
  url,
14038
- `| ${formatBytes(buffer.length)} |`,
14039
- `${isCacheHit ? "cache" : "network"}`
14040
- );
14041
- } : void 0;
14042
- const bufferFetcher = new BufferFetcher({
14043
- batchSize,
14044
- pauseBetweenBatchesMs,
14045
- cacheManager: useCache ? new CacheManager({ cacheFolderPath }) : void 0,
14046
- retryCount,
14047
- pauseBetweenRetriesMs,
14048
- onItemFetch,
14049
- retryOnEmpty
14050
- });
14051
- let firstLine = true;
14052
- let urlsProcessed = 0;
14053
- const urlsforFetchingData = generateUrls({
14054
- instrument: input.instrument,
14055
- timeframe: input.timeframe,
14056
- priceType: input.priceType,
14057
- startDate,
14058
- endDate
14059
- });
14060
- await (0, import_promises.pipeline)(
14061
- import_stream.Readable.from(urlsforFetchingData),
14062
- new import_stream.Transform({
14063
- objectMode: true,
14064
- transform: async (url, _, callback) => {
14065
- const bufferObject = {
14066
- url,
14067
- buffer: await bufferFetcher.fetchBuffer(url),
14068
- isCacheHit: useCache
14069
- };
14070
- try {
14071
- const processedData = processData({
14072
- instrument: input.instrument,
14073
- requestedTimeframe: input.timeframe,
14074
- bufferObjects: [bufferObject],
14075
- priceType: input.priceType,
14076
- volumes: input.volumes,
14077
- volumeUnits: input.volumeUnits,
14078
- ignoreFlats: input.ignoreFlats
14079
- });
14080
- processedData.forEach((item) => {
14081
- const [timestamp] = item;
14082
- if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
14083
- if (input.format === "array" /* array */) {
14084
- this.push(item);
14085
- } else {
14086
- const bodyHeaders = timeframe === "tick" /* tick */ ? tickHeaders : candleHeaders;
14087
- if (format === "json" /* json */) {
14088
- const data = item.reduce((all, item2, i) => {
14089
- const name = bodyHeaders[i];
14090
- all[name] = item2;
14091
- return all;
14092
- }, {});
14093
- this.push(data);
14094
- } else if (format === "csv" /* csv */) {
14095
- if (firstLine) {
14096
- const csvHeaders = bodyHeaders.join(",");
14097
- this.push(csvHeaders);
14098
- firstLine = false;
14099
- }
14100
- this.push(item.join(","));
14101
- }
14102
- }
14070
+ buffer: await bufferFetcher.fetchBuffer(url),
14071
+ isCacheHit: useCache
14072
+ };
14073
+ try {
14074
+ const processedData = processData({
14075
+ instrument: input.instrument,
14076
+ requestedTimeframe: input.timeframe,
14077
+ bufferObjects: [bufferObject],
14078
+ priceType: input.priceType,
14079
+ volumes: input.volumes,
14080
+ volumeUnits: input.volumeUnits,
14081
+ ignoreFlats: input.ignoreFlats
14082
+ });
14083
+ processedData.forEach((item) => {
14084
+ const [timestamp] = item;
14085
+ if (timestamp && timestamp >= startDateMs && timestamp < endDateMs) {
14086
+ if (input.format === "array" /* array */) {
14087
+ stream.push(item);
14088
+ } else if (format === "json" /* json */) {
14089
+ const data = item.reduce((all, item2, i) => {
14090
+ const name = bodyHeaders[i];
14091
+ all[name] = item2;
14092
+ return all;
14093
+ }, {});
14094
+ stream.push(data);
14095
+ } else if (format === "csv" /* csv */) {
14096
+ if (firstLine) {
14097
+ const csvHeaders = bodyHeaders.join(",");
14098
+ stream.push(csvHeaders);
14099
+ firstLine = false;
14103
14100
  }
14104
- });
14105
- callback();
14106
- } catch (err) {
14107
- callback(err);
14101
+ stream.push(`
14102
+ ${item.join(",")}`);
14103
+ }
14108
14104
  }
14105
+ });
14106
+ if (++urlsProcessed === urlsforFetchingData.length) {
14107
+ stream.push(null);
14109
14108
  }
14110
- })
14111
- ).then(() => {
14112
- if (++urlsProcessed === urlsforFetchingData.length) {
14113
- this.push(null);
14109
+ callback();
14110
+ } catch (err) {
14111
+ callback(err);
14114
14112
  }
14115
- }).catch((err) => {
14116
- this.emit("error", err);
14117
- this.push(null);
14118
- });
14119
- } catch (err) {
14120
- this.emit("error", err);
14121
- this.push(null);
14122
- }
14123
- }
14124
- });
14113
+ }
14114
+ })
14115
+ ).catch((err) => {
14116
+ stream.emit("error", err);
14117
+ stream.push(null);
14118
+ });
14119
+ } catch (err) {
14120
+ stream.emit("error", err);
14121
+ stream.push(null);
14122
+ }
14125
14123
  return stream;
14126
14124
  }
14127
14125
  // Annotate the CommonJS export names for ESM import in node:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dukascopy-node-plus",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Node.js library for downloading historical market tick data for for Crypto, Stocks, ETFs, CFDs, Forex",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -13,7 +13,7 @@
13
13
  "dukascopy-node": "./dist/cli/index.js"
14
14
  },
15
15
  "scripts": {
16
- "build": "rm -rf dist && tsup-node src/index.ts src/cli/index.ts src/index.example.ts --format esm,cjs --dts --legacy-output",
16
+ "build": "rm -rf dist && tsup-node src/index.ts src/cli/index.ts src/index.example.stream.ts src/index.example.nostream.ts --format esm,cjs --dts --legacy-output",
17
17
  "test": "vitest run",
18
18
  "coverage": "vitest run --coverage",
19
19
  "format": "prettier --config .prettierrc 'src/**/*.ts' --write",