@solana/web3.js 1.68.1 → 1.70.0-pr-29130
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/README.md +0 -13
- package/lib/index.browser.cjs.js +48 -11
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +48 -11
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +2821 -221
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +247 -234
- package/lib/index.esm.js +2814 -219
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +48 -11
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +2 -2
- package/lib/index.iife.min.js.map +1 -1
- package/lib/index.native.js +48 -11
- package/lib/index.native.js.map +1 -1
- package/package.json +7 -5
- package/src/connection.ts +123 -35
- package/src/epoch-schedule.ts +1 -1
- package/src/utils/send-and-confirm-transaction.ts +14 -1
- package/src/agent-manager.ts +0 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/web3.js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.70.0-pr-29130",
|
|
4
4
|
"description": "Solana Javascript API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"pretty": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
|
|
52
52
|
"pretty:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
|
|
53
53
|
"re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
|
|
54
|
-
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'",
|
|
54
|
+
"test": "cross-env NODE_ENV=test TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'",
|
|
55
55
|
"test:cover": "nyc --reporter=lcov npm run test",
|
|
56
56
|
"test:live": "TEST_LIVE=1 npm run test",
|
|
57
57
|
"test:live-with-test-validator": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health test:live"
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@noble/hashes": "^1.1.2",
|
|
63
63
|
"@noble/secp256k1": "^1.6.3",
|
|
64
64
|
"@solana/buffer-layout": "^4.0.0",
|
|
65
|
+
"agentkeepalive": "^4.2.1",
|
|
65
66
|
"bigint-buffer": "^1.1.5",
|
|
66
67
|
"bn.js": "^5.0.0",
|
|
67
68
|
"borsh": "^0.7.0",
|
|
@@ -95,7 +96,7 @@
|
|
|
95
96
|
"@types/express-serve-static-core": "^4.17.21",
|
|
96
97
|
"@types/mocha": "^10.0.0",
|
|
97
98
|
"@types/mz": "^2.7.3",
|
|
98
|
-
"@types/node": "^
|
|
99
|
+
"@types/node": "^18.11.10",
|
|
99
100
|
"@types/node-fetch": "2",
|
|
100
101
|
"@types/sinon": "^10.0.0",
|
|
101
102
|
"@types/sinon-chai": "^3.2.8",
|
|
@@ -114,6 +115,7 @@
|
|
|
114
115
|
"mocha": "^10.1.0",
|
|
115
116
|
"mockttp": "^2.0.1",
|
|
116
117
|
"mz": "^2.7.0",
|
|
118
|
+
"node-abort-controller": "^3.0.1",
|
|
117
119
|
"npm-run-all": "^4.1.5",
|
|
118
120
|
"nyc": "^15.1.0",
|
|
119
121
|
"prettier": "^2.3.0",
|
|
@@ -129,8 +131,8 @@
|
|
|
129
131
|
"ts-mocha": "^10.0.0",
|
|
130
132
|
"ts-node": "^10.0.0",
|
|
131
133
|
"tslib": "^2.1.0",
|
|
132
|
-
"typedoc": "^0.
|
|
133
|
-
"typescript": "^4.
|
|
134
|
+
"typedoc": "^0.23",
|
|
135
|
+
"typescript": "^4.9"
|
|
134
136
|
},
|
|
135
137
|
"engines": {
|
|
136
138
|
"node": ">=12.20.0"
|
package/src/connection.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import Agent from 'agentkeepalive';
|
|
1
2
|
import bs58 from 'bs58';
|
|
2
3
|
import {Buffer} from 'buffer';
|
|
3
4
|
// @ts-ignore
|
|
4
5
|
import fastStableStringify from 'fast-stable-stringify';
|
|
6
|
+
import type {Agent as HttpAgent} from 'http';
|
|
7
|
+
import {Agent as HttpsAgent} from 'https';
|
|
5
8
|
import {
|
|
6
9
|
type as pick,
|
|
7
10
|
number,
|
|
@@ -25,7 +28,6 @@ import {Client as RpcWebSocketClient} from 'rpc-websockets';
|
|
|
25
28
|
import RpcClient from 'jayson/lib/client/browser';
|
|
26
29
|
import {JSONRPCError} from 'jayson';
|
|
27
30
|
|
|
28
|
-
import {AgentManager} from './agent-manager';
|
|
29
31
|
import {EpochSchedule} from './epoch-schedule';
|
|
30
32
|
import {SendTransactionError, SolanaJSONRPCError} from './errors';
|
|
31
33
|
import fetchImpl, {Response} from './fetch-impl';
|
|
@@ -311,9 +313,39 @@ export type BlockhashWithExpiryBlockHeight = Readonly<{
|
|
|
311
313
|
* A strategy for confirming transactions that uses the last valid
|
|
312
314
|
* block height for a given blockhash to check for transaction expiration.
|
|
313
315
|
*/
|
|
314
|
-
export type BlockheightBasedTransactionConfirmationStrategy =
|
|
316
|
+
export type BlockheightBasedTransactionConfirmationStrategy =
|
|
317
|
+
BaseTransactionConfirmationStrategy & BlockhashWithExpiryBlockHeight;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* A strategy for confirming durable nonce transactions.
|
|
321
|
+
*/
|
|
322
|
+
export type DurableNonceTransactionConfirmationStrategy =
|
|
323
|
+
BaseTransactionConfirmationStrategy & {
|
|
324
|
+
/**
|
|
325
|
+
* The lowest slot at which to fetch the nonce value from the
|
|
326
|
+
* nonce account. This should be no lower than the slot at
|
|
327
|
+
* which the last-known value of the nonce was fetched.
|
|
328
|
+
*/
|
|
329
|
+
minContextSlot: number;
|
|
330
|
+
/**
|
|
331
|
+
* The account where the current value of the nonce is stored.
|
|
332
|
+
*/
|
|
333
|
+
nonceAccountPubkey: PublicKey;
|
|
334
|
+
/**
|
|
335
|
+
* The nonce value that was used to sign the transaction
|
|
336
|
+
* for which confirmation is being sought.
|
|
337
|
+
*/
|
|
338
|
+
nonceValue: DurableNonce;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Properties shared by all transaction confirmation strategies
|
|
343
|
+
*/
|
|
344
|
+
export type BaseTransactionConfirmationStrategy = Readonly<{
|
|
345
|
+
/** A signal that, when aborted, cancels any outstanding transaction confirmation operations */
|
|
346
|
+
abortSignal?: AbortSignal;
|
|
315
347
|
signature: TransactionSignature;
|
|
316
|
-
}
|
|
348
|
+
}>;
|
|
317
349
|
|
|
318
350
|
/* @internal */
|
|
319
351
|
function assertEndpointUrl(putativeUrl: string) {
|
|
@@ -340,28 +372,6 @@ function extractCommitmentFromConfig<TConfig>(
|
|
|
340
372
|
return {commitment, config};
|
|
341
373
|
}
|
|
342
374
|
|
|
343
|
-
/**
|
|
344
|
-
* A strategy for confirming durable nonce transactions.
|
|
345
|
-
*/
|
|
346
|
-
export type DurableNonceTransactionConfirmationStrategy = {
|
|
347
|
-
/**
|
|
348
|
-
* The lowest slot at which to fetch the nonce value from the
|
|
349
|
-
* nonce account. This should be no lower than the slot at
|
|
350
|
-
* which the last-known value of the nonce was fetched.
|
|
351
|
-
*/
|
|
352
|
-
minContextSlot: number;
|
|
353
|
-
/**
|
|
354
|
-
* The account where the current value of the nonce is stored.
|
|
355
|
-
*/
|
|
356
|
-
nonceAccountPubkey: PublicKey;
|
|
357
|
-
/**
|
|
358
|
-
* The nonce value that was used to sign the transaction
|
|
359
|
-
* for which confirmation is being sought.
|
|
360
|
-
*/
|
|
361
|
-
nonceValue: DurableNonce;
|
|
362
|
-
signature: TransactionSignature;
|
|
363
|
-
};
|
|
364
|
-
|
|
365
375
|
/**
|
|
366
376
|
* @internal
|
|
367
377
|
*/
|
|
@@ -1442,11 +1452,49 @@ function createRpcClient(
|
|
|
1442
1452
|
customFetch?: FetchFn,
|
|
1443
1453
|
fetchMiddleware?: FetchMiddleware,
|
|
1444
1454
|
disableRetryOnRateLimit?: boolean,
|
|
1455
|
+
httpAgent?: HttpAgent | HttpsAgent | false,
|
|
1445
1456
|
): RpcClient {
|
|
1446
1457
|
const fetch = customFetch ? customFetch : fetchImpl;
|
|
1447
|
-
let
|
|
1448
|
-
if (
|
|
1449
|
-
|
|
1458
|
+
let agent: HttpAgent | HttpsAgent | undefined;
|
|
1459
|
+
if (process.env.BROWSER) {
|
|
1460
|
+
if (httpAgent != null) {
|
|
1461
|
+
console.warn(
|
|
1462
|
+
'You have supplied an `httpAgent` when creating a `Connection` in a browser environment.' +
|
|
1463
|
+
'It has been ignored; `httpAgent` is only used in Node environments.',
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
} else {
|
|
1467
|
+
if (httpAgent == null) {
|
|
1468
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
1469
|
+
agent = new Agent({
|
|
1470
|
+
// One second fewer than the Solana RPC's keepalive timeout.
|
|
1471
|
+
// Read more: https://github.com/solana-labs/solana/issues/27859#issuecomment-1340097889
|
|
1472
|
+
freeSocketTimeout: 19000,
|
|
1473
|
+
keepAlive: true,
|
|
1474
|
+
maxSockets: 25,
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
} else {
|
|
1478
|
+
if (httpAgent !== false) {
|
|
1479
|
+
const isHttps = url.startsWith('https:');
|
|
1480
|
+
if (isHttps && !(httpAgent instanceof HttpsAgent)) {
|
|
1481
|
+
throw new Error(
|
|
1482
|
+
'The endpoint `' +
|
|
1483
|
+
url +
|
|
1484
|
+
'` can only be paired with an `https.Agent`. You have, instead, supplied an ' +
|
|
1485
|
+
'`http.Agent` through `httpAgent`.',
|
|
1486
|
+
);
|
|
1487
|
+
} else if (!isHttps && httpAgent instanceof HttpsAgent) {
|
|
1488
|
+
throw new Error(
|
|
1489
|
+
'The endpoint `' +
|
|
1490
|
+
url +
|
|
1491
|
+
'` can only be paired with an `http.Agent`. You have, instead, supplied an ' +
|
|
1492
|
+
'`https.Agent` through `httpAgent`.',
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
agent = httpAgent;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1450
1498
|
}
|
|
1451
1499
|
|
|
1452
1500
|
let fetchWithMiddleware: FetchFn | undefined;
|
|
@@ -1469,7 +1517,6 @@ function createRpcClient(
|
|
|
1469
1517
|
}
|
|
1470
1518
|
|
|
1471
1519
|
const clientBrowser = new RpcClient(async (request, callback) => {
|
|
1472
|
-
const agent = agentManager ? agentManager.requestStart() : undefined;
|
|
1473
1520
|
const options = {
|
|
1474
1521
|
method: 'POST',
|
|
1475
1522
|
body: request,
|
|
@@ -1519,8 +1566,6 @@ function createRpcClient(
|
|
|
1519
1566
|
}
|
|
1520
1567
|
} catch (err) {
|
|
1521
1568
|
if (err instanceof Error) callback(err);
|
|
1522
|
-
} finally {
|
|
1523
|
-
agentManager && agentManager.requestEnd();
|
|
1524
1569
|
}
|
|
1525
1570
|
}, {});
|
|
1526
1571
|
|
|
@@ -2847,6 +2892,12 @@ export type FetchMiddleware = (
|
|
|
2847
2892
|
* Configuration for instantiating a Connection
|
|
2848
2893
|
*/
|
|
2849
2894
|
export type ConnectionConfig = {
|
|
2895
|
+
/**
|
|
2896
|
+
* An `http.Agent` that will be used to manage socket connections (eg. to implement connection
|
|
2897
|
+
* persistence). Set this to `false` to create a connection that uses no agent. This applies to
|
|
2898
|
+
* Node environments only.
|
|
2899
|
+
*/
|
|
2900
|
+
httpAgent?: HttpAgent | HttpsAgent | false;
|
|
2850
2901
|
/** Optional commitment level */
|
|
2851
2902
|
commitment?: Commitment;
|
|
2852
2903
|
/** Optional endpoint URL to the fullnode JSON RPC PubSub WebSocket Endpoint */
|
|
@@ -2964,6 +3015,7 @@ export class Connection {
|
|
|
2964
3015
|
let fetch;
|
|
2965
3016
|
let fetchMiddleware;
|
|
2966
3017
|
let disableRetryOnRateLimit;
|
|
3018
|
+
let httpAgent;
|
|
2967
3019
|
if (commitmentOrConfig && typeof commitmentOrConfig === 'string') {
|
|
2968
3020
|
this._commitment = commitmentOrConfig;
|
|
2969
3021
|
} else if (commitmentOrConfig) {
|
|
@@ -2975,6 +3027,7 @@ export class Connection {
|
|
|
2975
3027
|
fetch = commitmentOrConfig.fetch;
|
|
2976
3028
|
fetchMiddleware = commitmentOrConfig.fetchMiddleware;
|
|
2977
3029
|
disableRetryOnRateLimit = commitmentOrConfig.disableRetryOnRateLimit;
|
|
3030
|
+
httpAgent = commitmentOrConfig.httpAgent;
|
|
2978
3031
|
}
|
|
2979
3032
|
|
|
2980
3033
|
this._rpcEndpoint = assertEndpointUrl(endpoint);
|
|
@@ -2986,6 +3039,7 @@ export class Connection {
|
|
|
2986
3039
|
fetch,
|
|
2987
3040
|
fetchMiddleware,
|
|
2988
3041
|
disableRetryOnRateLimit,
|
|
3042
|
+
httpAgent,
|
|
2989
3043
|
);
|
|
2990
3044
|
this._rpcRequest = createRpcRequest(this._rpcClient);
|
|
2991
3045
|
this._rpcBatchRequest = createRpcBatchRequest(this._rpcClient);
|
|
@@ -3571,6 +3625,9 @@ export class Connection {
|
|
|
3571
3625
|
const config = strategy as
|
|
3572
3626
|
| BlockheightBasedTransactionConfirmationStrategy
|
|
3573
3627
|
| DurableNonceTransactionConfirmationStrategy;
|
|
3628
|
+
if (config.abortSignal?.aborted) {
|
|
3629
|
+
return Promise.reject(config.abortSignal.reason);
|
|
3630
|
+
}
|
|
3574
3631
|
rawSignature = config.signature;
|
|
3575
3632
|
}
|
|
3576
3633
|
|
|
@@ -3602,6 +3659,21 @@ export class Connection {
|
|
|
3602
3659
|
}
|
|
3603
3660
|
}
|
|
3604
3661
|
|
|
3662
|
+
private getCancellationPromise(signal?: AbortSignal): Promise<never> {
|
|
3663
|
+
return new Promise<never>((_, reject) => {
|
|
3664
|
+
if (signal == null) {
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
if (signal.aborted) {
|
|
3668
|
+
reject(signal.reason);
|
|
3669
|
+
} else {
|
|
3670
|
+
signal.addEventListener('abort', () => {
|
|
3671
|
+
reject(signal.reason);
|
|
3672
|
+
});
|
|
3673
|
+
}
|
|
3674
|
+
});
|
|
3675
|
+
}
|
|
3676
|
+
|
|
3605
3677
|
private getTransactionConfirmationPromise({
|
|
3606
3678
|
commitment,
|
|
3607
3679
|
signature,
|
|
@@ -3722,7 +3794,7 @@ export class Connection {
|
|
|
3722
3794
|
|
|
3723
3795
|
private async confirmTransactionUsingBlockHeightExceedanceStrategy({
|
|
3724
3796
|
commitment,
|
|
3725
|
-
strategy: {lastValidBlockHeight, signature},
|
|
3797
|
+
strategy: {abortSignal, lastValidBlockHeight, signature},
|
|
3726
3798
|
}: {
|
|
3727
3799
|
commitment?: Commitment;
|
|
3728
3800
|
strategy: BlockheightBasedTransactionConfirmationStrategy;
|
|
@@ -3753,9 +3825,14 @@ export class Connection {
|
|
|
3753
3825
|
});
|
|
3754
3826
|
const {abortConfirmation, confirmationPromise} =
|
|
3755
3827
|
this.getTransactionConfirmationPromise({commitment, signature});
|
|
3828
|
+
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
|
3756
3829
|
let result: RpcResponseAndContext<SignatureResult>;
|
|
3757
3830
|
try {
|
|
3758
|
-
const outcome = await Promise.race([
|
|
3831
|
+
const outcome = await Promise.race([
|
|
3832
|
+
cancellationPromise,
|
|
3833
|
+
confirmationPromise,
|
|
3834
|
+
expiryPromise,
|
|
3835
|
+
]);
|
|
3759
3836
|
if (outcome.__type === TransactionStatus.PROCESSED) {
|
|
3760
3837
|
result = outcome.response;
|
|
3761
3838
|
} else {
|
|
@@ -3770,7 +3847,13 @@ export class Connection {
|
|
|
3770
3847
|
|
|
3771
3848
|
private async confirmTransactionUsingDurableNonceStrategy({
|
|
3772
3849
|
commitment,
|
|
3773
|
-
strategy: {
|
|
3850
|
+
strategy: {
|
|
3851
|
+
abortSignal,
|
|
3852
|
+
minContextSlot,
|
|
3853
|
+
nonceAccountPubkey,
|
|
3854
|
+
nonceValue,
|
|
3855
|
+
signature,
|
|
3856
|
+
},
|
|
3774
3857
|
}: {
|
|
3775
3858
|
commitment?: Commitment;
|
|
3776
3859
|
strategy: DurableNonceTransactionConfirmationStrategy;
|
|
@@ -3821,9 +3904,14 @@ export class Connection {
|
|
|
3821
3904
|
});
|
|
3822
3905
|
const {abortConfirmation, confirmationPromise} =
|
|
3823
3906
|
this.getTransactionConfirmationPromise({commitment, signature});
|
|
3907
|
+
const cancellationPromise = this.getCancellationPromise(abortSignal);
|
|
3824
3908
|
let result: RpcResponseAndContext<SignatureResult>;
|
|
3825
3909
|
try {
|
|
3826
|
-
const outcome = await Promise.race([
|
|
3910
|
+
const outcome = await Promise.race([
|
|
3911
|
+
cancellationPromise,
|
|
3912
|
+
confirmationPromise,
|
|
3913
|
+
expiryPromise,
|
|
3914
|
+
]);
|
|
3827
3915
|
if (outcome.__type === TransactionStatus.PROCESSED) {
|
|
3828
3916
|
result = outcome.response;
|
|
3829
3917
|
} else {
|
package/src/epoch-schedule.ts
CHANGED
|
@@ -26,7 +26,7 @@ function nextPowerOfTwo(n: number) {
|
|
|
26
26
|
/**
|
|
27
27
|
* Epoch schedule
|
|
28
28
|
* (see https://docs.solana.com/terminology#epoch)
|
|
29
|
-
* Can be retrieved with the {@link
|
|
29
|
+
* Can be retrieved with the {@link Connection.getEpochSchedule} method
|
|
30
30
|
*/
|
|
31
31
|
export class EpochSchedule {
|
|
32
32
|
/** The maximum number of slots in each epoch */
|
|
@@ -19,7 +19,11 @@ export async function sendAndConfirmTransaction(
|
|
|
19
19
|
connection: Connection,
|
|
20
20
|
transaction: Transaction,
|
|
21
21
|
signers: Array<Signer>,
|
|
22
|
-
options?: ConfirmOptions
|
|
22
|
+
options?: ConfirmOptions &
|
|
23
|
+
Readonly<{
|
|
24
|
+
// A signal that, when aborted, cancels any outstanding transaction confirmation operations
|
|
25
|
+
abortSignal?: AbortSignal;
|
|
26
|
+
}>,
|
|
23
27
|
): Promise<TransactionSignature> {
|
|
24
28
|
const sendOptions = options && {
|
|
25
29
|
skipPreflight: options.skipPreflight,
|
|
@@ -42,6 +46,7 @@ export async function sendAndConfirmTransaction(
|
|
|
42
46
|
status = (
|
|
43
47
|
await connection.confirmTransaction(
|
|
44
48
|
{
|
|
49
|
+
abortSignal: options?.abortSignal,
|
|
45
50
|
signature: signature,
|
|
46
51
|
blockhash: transaction.recentBlockhash,
|
|
47
52
|
lastValidBlockHeight: transaction.lastValidBlockHeight,
|
|
@@ -58,6 +63,7 @@ export async function sendAndConfirmTransaction(
|
|
|
58
63
|
status = (
|
|
59
64
|
await connection.confirmTransaction(
|
|
60
65
|
{
|
|
66
|
+
abortSignal: options?.abortSignal,
|
|
61
67
|
minContextSlot: transaction.minNonceContextSlot,
|
|
62
68
|
nonceAccountPubkey,
|
|
63
69
|
nonceValue: transaction.nonceInfo.nonce,
|
|
@@ -67,6 +73,13 @@ export async function sendAndConfirmTransaction(
|
|
|
67
73
|
)
|
|
68
74
|
).value;
|
|
69
75
|
} else {
|
|
76
|
+
if (options?.abortSignal != null) {
|
|
77
|
+
console.warn(
|
|
78
|
+
'sendAndConfirmTransaction(): A transaction with a deprecated confirmation strategy was ' +
|
|
79
|
+
'supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` ' +
|
|
80
|
+
'or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.',
|
|
81
|
+
);
|
|
82
|
+
}
|
|
70
83
|
status = (
|
|
71
84
|
await connection.confirmTransaction(
|
|
72
85
|
signature,
|
package/src/agent-manager.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import http from 'http';
|
|
2
|
-
import https from 'https';
|
|
3
|
-
|
|
4
|
-
export const DESTROY_TIMEOUT_MS = 5000;
|
|
5
|
-
|
|
6
|
-
export class AgentManager {
|
|
7
|
-
_agent: http.Agent | https.Agent;
|
|
8
|
-
_activeRequests = 0;
|
|
9
|
-
_destroyTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
10
|
-
_useHttps: boolean;
|
|
11
|
-
|
|
12
|
-
static _newAgent(useHttps: boolean): http.Agent | https.Agent {
|
|
13
|
-
const options = {keepAlive: true, maxSockets: 25};
|
|
14
|
-
if (useHttps) {
|
|
15
|
-
return new https.Agent(options);
|
|
16
|
-
} else {
|
|
17
|
-
return new http.Agent(options);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
constructor(useHttps?: boolean) {
|
|
22
|
-
this._useHttps = useHttps === true;
|
|
23
|
-
this._agent = AgentManager._newAgent(this._useHttps);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
requestStart(): http.Agent | https.Agent {
|
|
27
|
-
this._activeRequests++;
|
|
28
|
-
if (this._destroyTimeout !== null) {
|
|
29
|
-
clearTimeout(this._destroyTimeout);
|
|
30
|
-
this._destroyTimeout = null;
|
|
31
|
-
}
|
|
32
|
-
return this._agent;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
requestEnd() {
|
|
36
|
-
this._activeRequests--;
|
|
37
|
-
if (this._activeRequests === 0 && this._destroyTimeout === null) {
|
|
38
|
-
this._destroyTimeout = setTimeout(() => {
|
|
39
|
-
this._agent.destroy();
|
|
40
|
-
this._agent = AgentManager._newAgent(this._useHttps);
|
|
41
|
-
}, DESTROY_TIMEOUT_MS);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|