crux-api 2.0.0 → 3.0.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.
package/package.json CHANGED
@@ -1,45 +1,38 @@
1
1
  {
2
2
  "name": "crux-api",
3
- "version": "2.0.0",
4
- "description": "A Chrome UX Report API wrapper wrapper that handles errors and provides types",
3
+ "version": "3.0.0",
4
+ "description": "A tiny CrUX API wrapper that supports record & history API, handles errors, and provides types.",
5
5
  "repository": "https://github.com/treosh/crux-api",
6
6
  "bugs": "https://github.com/treosh/crux-api/issues",
7
7
  "license": "MIT",
8
+ "type": "module",
8
9
  "source": "src/index.js",
9
- "module": "src/index.js",
10
- "types": "dist/crux-api.d.ts",
11
- "main": "dist/crux-api.js",
10
+ "types": "types/index.d.ts",
12
11
  "files": [
13
- "dist",
14
- "src"
12
+ "src",
13
+ "types"
15
14
  ],
16
15
  "scripts": {
17
- "build": "run-s build:*",
18
- "build:src": "microbundle build --no-sourcemap --format=cjs",
19
- "build:src-ts": "tsc --declaration --noEmit false --outDir dist/ --allowJs src/index.js && rm dist/index.js && mv dist/index.d.ts dist/crux-api.d.ts",
20
- "test": "ava -v && prettier -c src test script README.md && yarn build && tsc -p . && size-limit",
21
- "prepack": "yarn build"
16
+ "types": "tsc --declaration --emitDeclarationOnly --noEmit false --outDir types/ --allowJs src/index.js",
17
+ "test": "yarn types && ava -v test/index.js && prettier -c src test script README.md && tsc -p . && size-limit"
22
18
  },
23
19
  "devDependencies": {
24
- "@size-limit/preset-small-lib": "^4.11.0",
25
- "@types/node-fetch": "^2.5.10",
26
- "ava": "^3.15.0",
27
- "esm": "^3.2.25",
28
- "microbundle": "^0.13.1",
29
- "node-fetch": "^2.6.1",
30
- "npm-run-all": "^4.1.5",
31
- "prettier": "^2.3.1",
32
- "size-limit": "^4.11.0",
33
- "typescript": "^4.3.2"
20
+ "@size-limit/preset-small-lib": "^9.0.0",
21
+ "@types/node": "^20.8.6",
22
+ "ava": "^5.3.1",
23
+ "node-fetch": "^3.3.2",
24
+ "prettier": "^3.0.3",
25
+ "size-limit": "^9.0.0",
26
+ "typescript": "^5.2.2"
34
27
  },
35
28
  "keywords": [
36
29
  "CrUX",
37
30
  "CrUX API",
31
+ "CrUX History API",
38
32
  "Chrome User Experience Report",
39
33
  "Chrome UX Report",
40
34
  "Core Web Vitals",
41
35
  "Web Performance",
42
- "records.queryRecord",
43
36
  "FCP",
44
37
  "First Contentful Paint",
45
38
  "LCP",
@@ -47,20 +40,16 @@
47
40
  "FID",
48
41
  "First Input Delay",
49
42
  "CLS",
50
- "Cumulative Layout Shift"
43
+ "Cumulative Layout Shift",
44
+ "INP",
45
+ "Interation to Next Paint",
46
+ "TTFB",
47
+ "Time to First Byte"
51
48
  ],
52
49
  "size-limit": [
53
50
  {
54
- "limit": "450B",
51
+ "limit": "510B",
55
52
  "path": "./src/index.js"
56
53
  }
57
- ],
58
- "ava": {
59
- "require": [
60
- "esm"
61
- ],
62
- "files": [
63
- "test/*.js"
64
- ]
65
- }
54
+ ]
66
55
  }
package/src/index.js CHANGED
@@ -7,7 +7,8 @@ const maxRetryTimeout = 60 * 1000 // 60s
7
7
  * @typedef {'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET'} FormFactor
8
8
  * @typedef {'4G' | '3G' | '2G' | 'slow-2G' | 'offline'} Connection
9
9
  * @typedef {{ histogram: { start: number | string, end: number | string, density: number }[], percentiles: { p75: number | string } }} MetricValue
10
- * @typedef {'first_contentful_paint' | 'largest_contentful_paint' | 'first_input_delay' | 'cumulative_layout_shift'} MetricName
10
+ * @typedef {{ year: number, month: number, day: number }} MetricDate
11
+ * @typedef {{ firstDate: MetricDate, lastDate: MetricDate }} CollectionPeriod
11
12
  * @typedef {{ error: { code: number, message: string, status: string } }} ErrorResponse
12
13
  * @typedef {{
13
14
  * record: {
@@ -22,34 +23,78 @@ const maxRetryTimeout = 60 * 1000 // 60s
22
23
  * largest_contentful_paint?: MetricValue,
23
24
  * first_input_delay?: MetricValue,
24
25
  * cumulative_layout_shift?: MetricValue,
25
- * }
26
+ * interaction_to_next_paint?: MetricValue,
27
+ * experimental_time_to_first_byte?: MetricValue,
28
+ * },
29
+ * collectionPeriod: CollectionPeriod
26
30
  * },
27
31
  * urlNormalizationDetails?: {
28
32
  * originalUrl: string,
29
33
  * normalizedUrl: string
30
34
  * }
31
35
  * }} SuccessResponse
36
+ *
37
+ * @typedef {(?number | string)[]} PercentileValues
38
+ * @typedef {{ start: number, end?: number, densities: (number | 'NaN')[] }} HistorgramTimeserie
39
+ * @typedef {{
40
+ * histogramTimeseries: HistorgramTimeserie[],
41
+ * percentilesTimeseries: { p75s: PercentileValues }
42
+ * }} HistoryValue
43
+ *
44
+ * @typedef {{
45
+ * record: {
46
+ * key: {
47
+ * url?: string,
48
+ * origin?: string,
49
+ * formFactor?: FormFactor
50
+ * },
51
+ * metrics: {
52
+ * first_input_delay?: HistoryValue,
53
+ * first_contentful_paint?: HistoryValue,
54
+ * largest_contentful_paint?: HistoryValue,
55
+ * cumulative_layout_shift?: HistoryValue,
56
+ * interaction_to_next_paint?: HistoryValue,
57
+ * experimental_time_to_first_byte?: HistoryValue,
58
+ * }
59
+ * collectionPeriods: CollectionPeriod[]
60
+ * },
61
+ * urlNormalizationDetails?: {
62
+ * originalUrl: string,
63
+ * normalizedUrl: string
64
+ * },
65
+ * }} HistoryResponse
32
66
  */
33
67
 
68
+ /** @param {CreateOptions} createOptions @return {function(QueryRecordOptions): Promise<SuccessResponse | null>} */
69
+ export function createQueryRecord(createOptions) {
70
+ return createQueryCruxApi({ ...createOptions, api: 'record' })
71
+ }
72
+
73
+ /** @param {CreateOptions} createOptions @return {function(QueryRecordOptions): Promise<HistoryResponse | null>} */
74
+ export function createQueryHistoryRecord(createOptions) {
75
+ return createQueryCruxApi({ ...createOptions, api: 'history' })
76
+ }
77
+
34
78
  /**
35
79
  * Fetch CrUX API and handles 4xx errors.
36
80
  * Inspired by: https://github.com/GoogleChrome/CrUX/blob/master/js/crux-api-util.js
37
81
  *
38
- * @param {CreateOptions} createOptions
82
+ * @param {CreateOptions & { api: 'history' | 'record' }} createOptions
39
83
  */
40
84
 
41
- export function createQueryRecord(createOptions) {
85
+ function createQueryCruxApi(createOptions) {
42
86
  const key = createOptions.key
43
87
  const fetch = createOptions.fetch || window.fetch
44
- return queryRecord
88
+ const apiMethod = createOptions.api === 'history' ? 'queryHistoryRecord' : 'queryRecord'
89
+ return queryCruxApi
45
90
 
46
91
  /**
47
92
  * @param {QueryRecordOptions} queryOptions
48
- * @return {Promise<SuccessResponse | null>}
93
+ * @return {Promise<any | null>}
49
94
  */
50
95
 
51
- async function queryRecord(queryOptions, retryCounter = 1) {
52
- const apiEndpoint = `https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=${key}`
96
+ async function queryCruxApi(queryOptions, retryCounter = 1) {
97
+ const apiEndpoint = `https://chromeuxreport.googleapis.com/v1/records:${apiMethod}?key=${key}`
53
98
  const res = await fetch(apiEndpoint, { method: 'POST', body: JSON.stringify(queryOptions) })
54
99
  if (res.status >= 500) throw new Error(`Invalid CrUX API status: ${res.status}`)
55
100
 
@@ -57,11 +102,11 @@ export function createQueryRecord(createOptions) {
57
102
  if (json && json.error) {
58
103
  const { error } = /** @type {ErrorResponse} */ (json)
59
104
  if (error.code === 404) return null
60
- if (error.code === 429) return retryAfterTimeout(retryCounter, () => queryRecord(queryOptions, retryCounter + 1))
105
+ if (error.code === 429) return retryAfterTimeout(retryCounter, () => queryCruxApi(queryOptions, retryCounter + 1))
61
106
  throw new Error(JSON.stringify(error))
62
107
  }
63
108
  if (!json || (json && !json.record.key)) throw new Error(`Invalid response: ${JSON.stringify(json)}`)
64
- return /** @type {SuccessResponse} */ (json)
109
+ return json
65
110
  }
66
111
  }
67
112
 
@@ -0,0 +1,176 @@
1
+ /**
2
+ * @typedef {{ key: string, fetch?: function }} CreateOptions
3
+ * @typedef {{ url?: string, origin?: string, formFactor?: FormFactor, effectiveConnectionType?: Connection }} QueryRecordOptions
4
+ * @typedef {'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET'} FormFactor
5
+ * @typedef {'4G' | '3G' | '2G' | 'slow-2G' | 'offline'} Connection
6
+ * @typedef {{ histogram: { start: number | string, end: number | string, density: number }[], percentiles: { p75: number | string } }} MetricValue
7
+ * @typedef {{ year: number, month: number, day: number }} MetricDate
8
+ * @typedef {{ firstDate: MetricDate, lastDate: MetricDate }} CollectionPeriod
9
+ * @typedef {{ error: { code: number, message: string, status: string } }} ErrorResponse
10
+ * @typedef {{
11
+ * record: {
12
+ * key: {
13
+ * url?: string,
14
+ * origin?: string,
15
+ * effectiveConnectionType?: Connection,
16
+ * formFactor?: FormFactor
17
+ * },
18
+ * metrics: {
19
+ * first_contentful_paint?: MetricValue,
20
+ * largest_contentful_paint?: MetricValue,
21
+ * first_input_delay?: MetricValue,
22
+ * cumulative_layout_shift?: MetricValue,
23
+ * interaction_to_next_paint?: MetricValue,
24
+ * experimental_time_to_first_byte?: MetricValue,
25
+ * },
26
+ * collectionPeriod: CollectionPeriod
27
+ * },
28
+ * urlNormalizationDetails?: {
29
+ * originalUrl: string,
30
+ * normalizedUrl: string
31
+ * }
32
+ * }} SuccessResponse
33
+ *
34
+ * @typedef {(?number | string)[]} PercentileValues
35
+ * @typedef {{ start: number, end?: number, densities: (number | 'NaN')[] }} HistorgramTimeserie
36
+ * @typedef {{
37
+ * histogramTimeseries: HistorgramTimeserie[],
38
+ * percentilesTimeseries: { p75s: PercentileValues }
39
+ * }} HistoryValue
40
+ *
41
+ * @typedef {{
42
+ * record: {
43
+ * key: {
44
+ * url?: string,
45
+ * origin?: string,
46
+ * formFactor?: FormFactor
47
+ * },
48
+ * metrics: {
49
+ * first_input_delay?: HistoryValue,
50
+ * first_contentful_paint?: HistoryValue,
51
+ * largest_contentful_paint?: HistoryValue,
52
+ * cumulative_layout_shift?: HistoryValue,
53
+ * interaction_to_next_paint?: HistoryValue,
54
+ * experimental_time_to_first_byte?: HistoryValue,
55
+ * }
56
+ * collectionPeriods: CollectionPeriod[]
57
+ * },
58
+ * urlNormalizationDetails?: {
59
+ * originalUrl: string,
60
+ * normalizedUrl: string
61
+ * },
62
+ * }} HistoryResponse
63
+ */
64
+ /** @param {CreateOptions} createOptions @return {function(QueryRecordOptions): Promise<SuccessResponse | null>} */
65
+ export function createQueryRecord(createOptions: CreateOptions): (arg0: QueryRecordOptions) => Promise<SuccessResponse | null>;
66
+ /** @param {CreateOptions} createOptions @return {function(QueryRecordOptions): Promise<HistoryResponse | null>} */
67
+ export function createQueryHistoryRecord(createOptions: CreateOptions): (arg0: QueryRecordOptions) => Promise<HistoryResponse | null>;
68
+ /**
69
+ * Normalize URL to match CrUX API key.
70
+ *
71
+ * @param {string} url
72
+ */
73
+ export function normalizeUrl(url: string): string;
74
+ /**
75
+ * Random delay from 1ms to `maxRetryTimeout`.
76
+ * Random logic is based on: https://stackoverflow.com/a/29246176
77
+ *
78
+ * @param {number} retryCounter
79
+ * @param {function} request
80
+ */
81
+ export function retryAfterTimeout(retryCounter: number, request: Function): Promise<any>;
82
+ export type CreateOptions = {
83
+ key: string;
84
+ fetch?: Function;
85
+ };
86
+ export type QueryRecordOptions = {
87
+ url?: string;
88
+ origin?: string;
89
+ formFactor?: FormFactor;
90
+ effectiveConnectionType?: Connection;
91
+ };
92
+ export type FormFactor = 'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET';
93
+ export type Connection = '4G' | '3G' | '2G' | 'slow-2G' | 'offline';
94
+ export type MetricValue = {
95
+ histogram: {
96
+ start: number | string;
97
+ end: number | string;
98
+ density: number;
99
+ }[];
100
+ percentiles: {
101
+ p75: number | string;
102
+ };
103
+ };
104
+ export type MetricDate = {
105
+ year: number;
106
+ month: number;
107
+ day: number;
108
+ };
109
+ export type CollectionPeriod = {
110
+ firstDate: MetricDate;
111
+ lastDate: MetricDate;
112
+ };
113
+ export type ErrorResponse = {
114
+ error: {
115
+ code: number;
116
+ message: string;
117
+ status: string;
118
+ };
119
+ };
120
+ export type SuccessResponse = {
121
+ record: {
122
+ key: {
123
+ url?: string;
124
+ origin?: string;
125
+ effectiveConnectionType?: Connection;
126
+ formFactor?: FormFactor;
127
+ };
128
+ metrics: {
129
+ first_contentful_paint?: MetricValue;
130
+ largest_contentful_paint?: MetricValue;
131
+ first_input_delay?: MetricValue;
132
+ cumulative_layout_shift?: MetricValue;
133
+ interaction_to_next_paint?: MetricValue;
134
+ experimental_time_to_first_byte?: MetricValue;
135
+ };
136
+ collectionPeriod: CollectionPeriod;
137
+ };
138
+ urlNormalizationDetails?: {
139
+ originalUrl: string;
140
+ normalizedUrl: string;
141
+ };
142
+ };
143
+ export type PercentileValues = ((number | string) | null)[];
144
+ export type HistorgramTimeserie = {
145
+ start: number;
146
+ end?: number;
147
+ densities: (number | 'NaN')[];
148
+ };
149
+ export type HistoryValue = {
150
+ histogramTimeseries: HistorgramTimeserie[];
151
+ percentilesTimeseries: {
152
+ p75s: (string | number)[];
153
+ };
154
+ };
155
+ export type HistoryResponse = {
156
+ record: {
157
+ key: {
158
+ url?: string;
159
+ origin?: string;
160
+ formFactor?: FormFactor;
161
+ };
162
+ metrics: {
163
+ first_input_delay?: HistoryValue;
164
+ first_contentful_paint?: HistoryValue;
165
+ largest_contentful_paint?: HistoryValue;
166
+ cumulative_layout_shift?: HistoryValue;
167
+ interaction_to_next_paint?: HistoryValue;
168
+ experimental_time_to_first_byte?: HistoryValue;
169
+ };
170
+ collectionPeriods: CollectionPeriod[];
171
+ };
172
+ urlNormalizationDetails?: {
173
+ originalUrl: string;
174
+ normalizedUrl: string;
175
+ };
176
+ };
@@ -1,17 +0,0 @@
1
- /**
2
- * Create batch interface for CrUX API.
3
- * https://developers.google.com/web/tools/chrome-user-experience-report/api/guides/batch
4
- *
5
- * @typedef {{ options: import('../..').QueryRecordOptions, result: import('../..').SuccessResponse | null | undefined }[]} BatchValues
6
- *
7
- * @param {import('../..').CreateOptions} createOptions
8
- */
9
- export function createBatch(createOptions: import('../..').CreateOptions): (batchOptions: import('../..').BatchOptions) => Promise<import("../..").BatchResponse>;
10
- /**
11
- * Create batch interface for CrUX API.
12
- * https://developers.google.com/web/tools/chrome-user-experience-report/api/guides/batch
13
- */
14
- export type BatchValues = {
15
- options: import('../..').QueryRecordOptions;
16
- result: import('../..').SuccessResponse | null | undefined;
17
- }[];
@@ -1,100 +0,0 @@
1
- /**
2
- * @typedef {{ key: string, fetch?: function }} CreateOptions
3
- * @typedef {{ url?: string, origin?: string, formFactor?: FormFactor, effectiveConnectionType?: Connection }} QueryRecordOptions
4
- * @typedef {'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET'} FormFactor
5
- * @typedef {'4G' | '3G' | '2G' | 'slow-2G' | 'offline'} Connection
6
- * @typedef {{ histogram: { start: number | string, end: number | string, density: number }[], percentiles: { p75: number | string } }} MetricValue
7
- * @typedef {'first_contentful_paint' | 'largest_contentful_paint' | 'first_input_delay' | 'cumulative_layout_shift'} MetricName
8
- * @typedef {{ error: { code: number, message: string, status: string } }} ErrorResponse
9
- * @typedef {{
10
- * record: {
11
- * key: {
12
- * url?: string,
13
- * origin?: string,
14
- * effectiveConnectionType?: Connection,
15
- * formFactor?: FormFactor
16
- * },
17
- * metrics: {
18
- * first_contentful_paint?: MetricValue,
19
- * largest_contentful_paint?: MetricValue,
20
- * first_input_delay?: MetricValue,
21
- * cumulative_layout_shift?: MetricValue,
22
- * }
23
- * },
24
- * urlNormalizationDetails?: {
25
- * originalUrl: string,
26
- * normalizedUrl: string
27
- * }
28
- * }} SuccessResponse
29
- */
30
- /**
31
- * Fetch CrUX API and handles 4xx errors.
32
- * Inspired by: https://github.com/GoogleChrome/CrUX/blob/master/js/crux-api-util.js
33
- *
34
- * @param {CreateOptions} createOptions
35
- */
36
- export function createQueryRecord(createOptions: CreateOptions): (queryOptions: QueryRecordOptions, retryCounter?: number) => Promise<SuccessResponse | null>;
37
- /**
38
- * Normalize URL to match CrUX API key.
39
- *
40
- * @param {string} url
41
- */
42
- export function normalizeUrl(url: string): string;
43
- /**
44
- * Random delay from 1ms to `maxRetryTimeout`.
45
- * Random logic is based on: https://stackoverflow.com/a/29246176
46
- *
47
- * @param {number} retryCounter
48
- * @param {function} request
49
- */
50
- export function retryAfterTimeout(retryCounter: number, request: Function): Promise<any>;
51
- export type CreateOptions = {
52
- key: string;
53
- fetch?: Function;
54
- };
55
- export type QueryRecordOptions = {
56
- url?: string;
57
- origin?: string;
58
- formFactor?: FormFactor;
59
- effectiveConnectionType?: Connection;
60
- };
61
- export type FormFactor = 'ALL_FORM_FACTORS' | 'PHONE' | 'DESKTOP' | 'TABLET';
62
- export type Connection = '4G' | '3G' | '2G' | 'slow-2G' | 'offline';
63
- export type MetricValue = {
64
- histogram: {
65
- start: number | string;
66
- end: number | string;
67
- density: number;
68
- }[];
69
- percentiles: {
70
- p75: number | string;
71
- };
72
- };
73
- export type MetricName = 'first_contentful_paint' | 'largest_contentful_paint' | 'first_input_delay' | 'cumulative_layout_shift';
74
- export type ErrorResponse = {
75
- error: {
76
- code: number;
77
- message: string;
78
- status: string;
79
- };
80
- };
81
- export type SuccessResponse = {
82
- record: {
83
- key: {
84
- url?: string;
85
- origin?: string;
86
- effectiveConnectionType?: Connection;
87
- formFactor?: FormFactor;
88
- };
89
- metrics: {
90
- first_contentful_paint?: MetricValue;
91
- largest_contentful_paint?: MetricValue;
92
- first_input_delay?: MetricValue;
93
- cumulative_layout_shift?: MetricValue;
94
- };
95
- };
96
- urlNormalizationDetails?: {
97
- originalUrl: string;
98
- normalizedUrl: string;
99
- };
100
- };
package/dist/crux-api.js DELETED
@@ -1 +0,0 @@
1
- var r=function(r,o){try{if(r<=e){var n=Math.floor(Math.random()*t)+1;return Promise.resolve(new Promise(function(r){return setTimeout(r,n)})).then(function(){return o()})}throw new Error("Max retries reached")}catch(r){return Promise.reject(r)}},e=10,t=6e4;exports.createQueryRecord=function(e){var t=e.key,o=e.fetch||window.fetch;return function e(n,i){void 0===i&&(i=1);try{return Promise.resolve(o("https://chromeuxreport.googleapis.com/v1/records:queryRecord?key="+t,{method:"POST",body:JSON.stringify(n)})).then(function(t){if(t.status>=500)throw new Error("Invalid CrUX API status: "+t.status);return Promise.resolve(t.json()).then(function(t){if(t&&t.error){var o=t.error;if(404===o.code)return null;if(429===o.code)return r(i,function(){return e(n,i+1)});throw new Error(JSON.stringify(o))}if(!t||t&&!t.record.key)throw new Error("Invalid response: "+JSON.stringify(t));return t})})}catch(r){return Promise.reject(r)}}},exports.normalizeUrl=function(r){var e=new URL(r);return e.origin+e.pathname},exports.retryAfterTimeout=r;
package/dist/keys.d.ts DELETED
@@ -1,7 +0,0 @@
1
- /**
2
- * Create keys rotating function.
3
- *
4
- * @param {string[]} [keys]
5
- * @param {string} [key]
6
- */
7
- export function createGetKey(keys?: string[], key?: string): () => string;
package/dist/keys.js DELETED
@@ -1,21 +0,0 @@
1
- "use strict";
2
- /**
3
- * Create keys rotating function.
4
- *
5
- * @param {string[]} [keys]
6
- * @param {string} [key]
7
- */
8
- exports.__esModule = true;
9
- exports.createGetKey = void 0;
10
- function createGetKey(keys, key) {
11
- var allKeys = /** @type {string[]} */ (keys || [key]).filter(Boolean);
12
- var totalKeys = allKeys.length;
13
- if (totalKeys === 0)
14
- throw new Error('No API keys');
15
- var keysStart = Math.floor(Math.random() * totalKeys); // random between 0 and totalKeys https://stackoverflow.com/a/7228322/893744
16
- return function getKey() {
17
- keysStart = keysStart < totalKeys - 1 ? keysStart + 1 : 0;
18
- return allKeys[keysStart];
19
- };
20
- }
21
- exports.createGetKey = createGetKey;
package/dist/retry.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * Random delay from 1ms to `maxRetryTimeout`.
3
- * Random logic is based on: https://stackoverflow.com/a/29246176
4
- *
5
- * @param {number} retryCounter
6
- * @param {function} request
7
- */
8
- export function retryAfterTimeout(retryCounter: number, request: Function): Promise<any>;
package/dist/retry.js DELETED
@@ -1,66 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- exports.__esModule = true;
39
- exports.retryAfterTimeout = void 0;
40
- var maxRetries = 10;
41
- var maxRetryTimeout = 100 * 1000; // 100s
42
- /**
43
- * Random delay from 1ms to `maxRetryTimeout`.
44
- * Random logic is based on: https://stackoverflow.com/a/29246176
45
- *
46
- * @param {number} retryCounter
47
- * @param {function} request
48
- */
49
- function retryAfterTimeout(retryCounter, request) {
50
- return __awaiter(this, void 0, void 0, function () {
51
- var timeout_1;
52
- return __generator(this, function (_a) {
53
- switch (_a.label) {
54
- case 0:
55
- if (!(retryCounter <= maxRetries)) return [3 /*break*/, 2];
56
- timeout_1 = Math.floor(Math.random() * maxRetryTimeout) + 1;
57
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, timeout_1); })];
58
- case 1:
59
- _a.sent();
60
- return [2 /*return*/, request()];
61
- case 2: throw new Error('Max retries reached');
62
- }
63
- });
64
- });
65
- }
66
- exports.retryAfterTimeout = retryAfterTimeout;
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};