@aptos-labs/ts-sdk 0.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/LICENSE +201 -0
- package/README.md +144 -0
- package/dist/browser/index.global.js +410 -0
- package/dist/browser/index.global.js.map +1 -0
- package/dist/cjs/index.d.ts +4965 -0
- package/dist/cjs/index.js +4762 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.d.ts +4965 -0
- package/dist/esm/index.mjs +4645 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/types/index.d.ts +1247 -0
- package/dist/types/index.js +151 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +79 -0
- package/src/api/account.ts +360 -0
- package/src/api/aptos.ts +103 -0
- package/src/api/aptosConfig.ts +77 -0
- package/src/api/coin.ts +39 -0
- package/src/api/digitalAsset.ts +192 -0
- package/src/api/event.ts +78 -0
- package/src/api/faucet.ts +30 -0
- package/src/api/fungibleAsset.ts +82 -0
- package/src/api/general.ts +188 -0
- package/src/api/index.ts +5 -0
- package/src/api/staking.ts +58 -0
- package/src/api/transaction.ts +135 -0
- package/src/api/transactionSubmission.ts +168 -0
- package/src/bcs/consts.ts +12 -0
- package/src/bcs/deserializer.ts +248 -0
- package/src/bcs/index.ts +9 -0
- package/src/bcs/serializable/entryFunctionBytes.ts +61 -0
- package/src/bcs/serializable/fixedBytes.ts +65 -0
- package/src/bcs/serializable/movePrimitives.ts +211 -0
- package/src/bcs/serializable/moveStructs.ts +462 -0
- package/src/bcs/serializer.ts +353 -0
- package/src/client/core.ts +106 -0
- package/src/client/get.ts +109 -0
- package/src/client/index.ts +7 -0
- package/src/client/post.ts +90 -0
- package/src/client/types.ts +58 -0
- package/src/core/account.ts +180 -0
- package/src/core/accountAddress.ts +407 -0
- package/src/core/authenticationKey.ts +102 -0
- package/src/core/common.ts +40 -0
- package/src/core/crypto/asymmetricCrypto.ts +77 -0
- package/src/core/crypto/ed25519.ts +224 -0
- package/src/core/crypto/index.ts +7 -0
- package/src/core/crypto/multiEd25519.ts +251 -0
- package/src/core/crypto/secp256k1.ts +227 -0
- package/src/core/hex.ts +177 -0
- package/src/core/index.ts +9 -0
- package/src/index.ts +12 -0
- package/src/internal/account.ts +484 -0
- package/src/internal/coin.ts +32 -0
- package/src/internal/digitalAsset.ts +302 -0
- package/src/internal/event.ts +88 -0
- package/src/internal/faucet.ts +41 -0
- package/src/internal/fungibleAsset.ts +114 -0
- package/src/internal/general.ts +160 -0
- package/src/internal/queries/TokenActivitiesFieldsFragment.graphql +17 -0
- package/src/internal/queries/currentTokenOwnershipFieldsFragment.graphql +45 -0
- package/src/internal/queries/getAccountCoinCount.graphql +7 -0
- package/src/internal/queries/getAccountCoinsData.graphql +32 -0
- package/src/internal/queries/getAccountCollectionsWithOwnedTokens.graphql +33 -0
- package/src/internal/queries/getAccountOwnedObjects.graphql +16 -0
- package/src/internal/queries/getAccountOwnedTokens.graphql +11 -0
- package/src/internal/queries/getAccountOwnedTokensByTokenData.graphql +11 -0
- package/src/internal/queries/getAccountOwnedTokensFromCollectionAddress.graphql +11 -0
- package/src/internal/queries/getAccountTokensCount.graphql +7 -0
- package/src/internal/queries/getAccountTransactionsCount.graphql +7 -0
- package/src/internal/queries/getChainTopUserTransactions.graphql +5 -0
- package/src/internal/queries/getCollectionData.graphql +20 -0
- package/src/internal/queries/getCurrentFungibleAssetBalances.graphql +17 -0
- package/src/internal/queries/getDelegatedStakingActivities.graphql +12 -0
- package/src/internal/queries/getEvents.graphql +12 -0
- package/src/internal/queries/getFungibleAssetActivities.graphql +20 -0
- package/src/internal/queries/getFungibleAssetMetadata.graphql +16 -0
- package/src/internal/queries/getNumberOfDelegatorsQuery.graphql +9 -0
- package/src/internal/queries/getProcessorStatus.graphql +7 -0
- package/src/internal/queries/getTokenActivity.graphql +11 -0
- package/src/internal/queries/getTokenCurrentOwner.graphql +11 -0
- package/src/internal/queries/getTokenData.graphql +38 -0
- package/src/internal/staking.ts +68 -0
- package/src/internal/transaction.ts +245 -0
- package/src/internal/transactionSubmission.ts +162 -0
- package/src/transactions/authenticator/account.ts +121 -0
- package/src/transactions/authenticator/transaction.ts +222 -0
- package/src/transactions/instances/chainId.ts +26 -0
- package/src/transactions/instances/identifier.ts +28 -0
- package/src/transactions/instances/index.ts +9 -0
- package/src/transactions/instances/moduleId.ts +53 -0
- package/src/transactions/instances/rawTransaction.ts +199 -0
- package/src/transactions/instances/signedTransaction.ts +43 -0
- package/src/transactions/instances/transactionArgument.ts +37 -0
- package/src/transactions/instances/transactionPayload.ts +407 -0
- package/src/transactions/transaction_builder/transaction_builder.ts +541 -0
- package/src/transactions/typeTag/typeTag.ts +487 -0
- package/src/transactions/types.ts +262 -0
- package/src/types/codegen.yaml +33 -0
- package/src/types/generated/operations.ts +623 -0
- package/src/types/generated/queries.ts +737 -0
- package/src/types/generated/types.ts +10387 -0
- package/src/types/index.ts +944 -0
- package/src/types/indexer.ts +93 -0
- package/src/utils/apiEndpoints.ts +36 -0
- package/src/utils/const.ts +51 -0
- package/src/utils/hdKey.ts +113 -0
- package/src/utils/helpers.ts +12 -0
- package/src/utils/memoize.ts +68 -0
- package/src/version.ts +9 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GENERATED QUERY TYPES FROM GRAPHQL SCHEMA
|
|
6
|
+
*
|
|
7
|
+
* generated types we generate from graphql schema that match the structure of the
|
|
8
|
+
* response type when querying from Hasura schema.
|
|
9
|
+
*
|
|
10
|
+
* These types are used as the return type when making the actual request (usually
|
|
11
|
+
* under the /internal/ folder)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
GetAccountCoinsDataQuery,
|
|
16
|
+
GetAccountOwnedObjectsQuery,
|
|
17
|
+
GetAccountOwnedTokensQuery,
|
|
18
|
+
GetAccountOwnedTokensFromCollectionQuery,
|
|
19
|
+
GetAccountCollectionsWithOwnedTokensQuery,
|
|
20
|
+
GetDelegatedStakingActivitiesQuery,
|
|
21
|
+
GetNumberOfDelegatorsQuery,
|
|
22
|
+
GetCollectionDataQuery,
|
|
23
|
+
GetChainTopUserTransactionsQuery,
|
|
24
|
+
GetEventsQuery,
|
|
25
|
+
GetTokenDataQuery,
|
|
26
|
+
GetProcessorStatusQuery,
|
|
27
|
+
GetFungibleAssetMetadataQuery,
|
|
28
|
+
GetFungibleAssetActivitiesQuery,
|
|
29
|
+
GetCurrentFungibleAssetBalancesQuery,
|
|
30
|
+
GetTokenActivityQuery,
|
|
31
|
+
GetCurrentTokenOwnershipQuery,
|
|
32
|
+
} from "./generated/operations";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* CUSTOM RESPONSE TYPES FOR THE END USER
|
|
36
|
+
*
|
|
37
|
+
* To provide a good dev exp, we build custom types derived from the
|
|
38
|
+
* query types to be the response type the end developer/user will
|
|
39
|
+
* work with.
|
|
40
|
+
*
|
|
41
|
+
* These types are used as the return type when calling a sdk api function
|
|
42
|
+
* that calls the function that queries the server (usually under the /api/ folder)
|
|
43
|
+
*/
|
|
44
|
+
export type GetAccountOwnedObjectsResponse = GetAccountOwnedObjectsQuery["current_objects"];
|
|
45
|
+
|
|
46
|
+
export type GetAccountOwnedTokensQueryResponse = GetAccountOwnedTokensQuery["current_token_ownerships_v2"];
|
|
47
|
+
|
|
48
|
+
export type GetAccountOwnedTokensFromCollectionResponse =
|
|
49
|
+
GetAccountOwnedTokensFromCollectionQuery["current_token_ownerships_v2"];
|
|
50
|
+
export type GetAccountCollectionsWithOwnedTokenResponse =
|
|
51
|
+
GetAccountCollectionsWithOwnedTokensQuery["current_collection_ownership_v2_view"];
|
|
52
|
+
export type GetAccountCoinsDataResponse = GetAccountCoinsDataQuery["current_fungible_asset_balances"];
|
|
53
|
+
export type GetChainTopUserTransactionsResponse = GetChainTopUserTransactionsQuery["user_transactions"];
|
|
54
|
+
export type GetEventsResponse = GetEventsQuery["events"];
|
|
55
|
+
|
|
56
|
+
export type GetNumberOfDelegatorsResponse = GetNumberOfDelegatorsQuery["num_active_delegator_per_pool"];
|
|
57
|
+
export type GetDelegatedStakingActivitiesResponse = GetDelegatedStakingActivitiesQuery["delegated_staking_activities"];
|
|
58
|
+
export type GetCollectionDataResponse = GetCollectionDataQuery["current_collections_v2"][0];
|
|
59
|
+
export type GetTokenDataResponse = GetTokenDataQuery["current_token_datas_v2"][0];
|
|
60
|
+
export type GetProcessorStatusResponse = GetProcessorStatusQuery["processor_status"];
|
|
61
|
+
export type GetFungibleAssetMetadataResponse = GetFungibleAssetMetadataQuery["fungible_asset_metadata"];
|
|
62
|
+
export type GetFungibleAssetActivitiesResponse = GetFungibleAssetActivitiesQuery["fungible_asset_activities"];
|
|
63
|
+
export type GetCurrentFungibleAssetBalancesResponse =
|
|
64
|
+
GetCurrentFungibleAssetBalancesQuery["current_fungible_asset_balances"];
|
|
65
|
+
export type GetTokenActivityResponse = GetTokenActivityQuery["token_activities_v2"];
|
|
66
|
+
export type GetCurrentTokenOwnershipResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"][0];
|
|
67
|
+
export type GetOwnedTokensResponse = GetCurrentTokenOwnershipQuery["current_token_ownerships_v2"];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A generic type that being passed by each function and holds an
|
|
71
|
+
* array of properties we can sort the query by
|
|
72
|
+
*/
|
|
73
|
+
export type OrderBy<T> = Array<{ [K in keyof T]?: OrderByValue }>;
|
|
74
|
+
export type OrderByValue =
|
|
75
|
+
| "asc"
|
|
76
|
+
| "asc_nulls_first"
|
|
77
|
+
| "asc_nulls_last"
|
|
78
|
+
| "desc"
|
|
79
|
+
| "desc_nulls_first"
|
|
80
|
+
| "desc_nulls_last";
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Refers to the token standard we want to query for
|
|
84
|
+
*/
|
|
85
|
+
export type TokenStandard = "v1" | "v2";
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The graphql query type to pass into the `queryIndexer` function
|
|
89
|
+
*/
|
|
90
|
+
export type GraphqlQuery = {
|
|
91
|
+
query: string;
|
|
92
|
+
variables?: {};
|
|
93
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export const NetworkToIndexerAPI: Record<string, string> = {
|
|
5
|
+
mainnet: "https://indexer.mainnet.aptoslabs.com/v1/graphql",
|
|
6
|
+
testnet: "https://indexer-testnet.staging.gcp.aptosdev.com/v1/graphql",
|
|
7
|
+
devnet: "https://indexer-devnet.staging.gcp.aptosdev.com/v1/graphql",
|
|
8
|
+
local: "http://127.0.0.1:8090/v1/graphql",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const NetworkToNodeAPI: Record<string, string> = {
|
|
12
|
+
mainnet: "https://fullnode.mainnet.aptoslabs.com/v1",
|
|
13
|
+
testnet: "https://fullnode.testnet.aptoslabs.com/v1",
|
|
14
|
+
devnet: "https://fullnode.devnet.aptoslabs.com/v1",
|
|
15
|
+
local: "http://127.0.0.1:8080/v1",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const NetworkToFaucetAPI: Record<string, string> = {
|
|
19
|
+
mainnet: "https://faucet.mainnet.aptoslabs.com",
|
|
20
|
+
testnet: "https://faucet.testnet.aptoslabs.com",
|
|
21
|
+
devnet: "https://faucet.devnet.aptoslabs.com",
|
|
22
|
+
local: "http://127.0.0.1:8081",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export enum Network {
|
|
26
|
+
MAINNET = "mainnet",
|
|
27
|
+
TESTNET = "testnet",
|
|
28
|
+
DEVNET = "devnet",
|
|
29
|
+
LOCAL = "local",
|
|
30
|
+
CUSTOM = "custom",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const NetworkToChainId: Record<string, number> = {
|
|
34
|
+
mainnet: 1,
|
|
35
|
+
testnet: 2,
|
|
36
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { Network } from "./apiEndpoints";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Type of API endpoint for request routing
|
|
8
|
+
*/
|
|
9
|
+
export enum AptosApiType {
|
|
10
|
+
FULLNODE,
|
|
11
|
+
INDEXER,
|
|
12
|
+
FAUCET,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_NETWORK = Network.DEVNET;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The default max gas amount when none is given.
|
|
19
|
+
*
|
|
20
|
+
* This is the maximum number of gas units that will be used by a transaction before being rejected.
|
|
21
|
+
*
|
|
22
|
+
* Note that max gas amount varies based on the transaction. A larger transaction will go over this
|
|
23
|
+
* default gas amount, and the value will need to be changed for the specific transaction.
|
|
24
|
+
*/
|
|
25
|
+
export const DEFAULT_MAX_GAS_AMOUNT = 200000;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The default transaction expiration seconds from now.
|
|
29
|
+
*
|
|
30
|
+
* This time is how long until the blockchain nodes will reject the transaction.
|
|
31
|
+
*
|
|
32
|
+
* Note that the transaction expiration time varies based on network connection and network load. It may need to be
|
|
33
|
+
* increased for the transaction to be processed.
|
|
34
|
+
*/
|
|
35
|
+
export const DEFAULT_TXN_EXP_SEC_FROM_NOW = 20;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The default number of seconds to wait for a transaction to be processed.
|
|
39
|
+
*
|
|
40
|
+
* This time is the amount of time that the SDK will wait for a transaction to be processed when waiting for
|
|
41
|
+
* the results of the transaction. It may take longer based on network connection and network load.
|
|
42
|
+
*/
|
|
43
|
+
export const DEFAULT_TXN_TIMEOUT_SEC = 20;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The default gas currency for the network.
|
|
47
|
+
*/
|
|
48
|
+
export const APTOS_COIN = "0x1::aptos_coin::AptosCoin";
|
|
49
|
+
|
|
50
|
+
export const RAW_TRANSACTION_SALT = "APTOS::RawTransaction";
|
|
51
|
+
export const RAW_TRANSACTION_WITH_DATA_SALT = "APTOS::RawTransactionWithData";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { hmac } from "@noble/hashes/hmac";
|
|
5
|
+
import { sha512 } from "@noble/hashes/sha512";
|
|
6
|
+
import * as bip39 from "@scure/bip39";
|
|
7
|
+
|
|
8
|
+
export type DerivedKeys = {
|
|
9
|
+
key: Uint8Array;
|
|
10
|
+
chainCode: Uint8Array;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Aptos derive path is 637
|
|
15
|
+
*
|
|
16
|
+
* See https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
|
17
|
+
*/
|
|
18
|
+
export const APTOS_PATH_REGEX = /^m\/44'\/637'\/[0-9]+'\/[0-9]+'\/[0-9]+'?$/;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A list of supported key types and associated seeds
|
|
22
|
+
*/
|
|
23
|
+
export enum KeyType {
|
|
24
|
+
ED25519 = "ed25519 seed",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const HARDENED_OFFSET = 0x80000000;
|
|
28
|
+
|
|
29
|
+
const deriveKey = (hashSeed: Uint8Array | string, data: Uint8Array | string): DerivedKeys => {
|
|
30
|
+
const digest = hmac.create(sha512, hashSeed).update(data).digest();
|
|
31
|
+
return {
|
|
32
|
+
key: digest.slice(0, 32),
|
|
33
|
+
chainCode: digest.slice(32),
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Derive a child key from the private key
|
|
39
|
+
* @param key
|
|
40
|
+
* @param chainCode
|
|
41
|
+
* @param index
|
|
42
|
+
* @constructor
|
|
43
|
+
*/
|
|
44
|
+
const CKDPriv = ({ key, chainCode }: DerivedKeys, index: number): DerivedKeys => {
|
|
45
|
+
const buffer = new ArrayBuffer(4);
|
|
46
|
+
new DataView(buffer).setUint32(0, index);
|
|
47
|
+
const indexBytes = new Uint8Array(buffer);
|
|
48
|
+
const zero = new Uint8Array([0]);
|
|
49
|
+
const data = new Uint8Array([...zero, ...key, ...indexBytes]);
|
|
50
|
+
|
|
51
|
+
return deriveKey(chainCode, data);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const removeApostrophes = (val: string): string => val.replace("'", "");
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Splits derive path into segments
|
|
58
|
+
* @param path
|
|
59
|
+
*/
|
|
60
|
+
const splitPath = (path: string): Array<string> => path.split("/").slice(1).map(removeApostrophes);
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Checks if the BIP44 path is valid for Aptos
|
|
64
|
+
* @param path the BIP44 path
|
|
65
|
+
*
|
|
66
|
+
* @returns true if the path is a valid Aptos path
|
|
67
|
+
*/
|
|
68
|
+
export const isValidPath = (path: string): boolean => {
|
|
69
|
+
if (!APTOS_PATH_REGEX.test(path)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return !splitPath(path).some(Number.isNaN as any);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Normalizes the mnemonic by removing extra whitespace and making it lowercase
|
|
77
|
+
* @param mnemonic the mnemonic seed phrase
|
|
78
|
+
*/
|
|
79
|
+
const mnemonicToSeed = (mnemonic: string): Uint8Array => {
|
|
80
|
+
const normalizedMnemonic = mnemonic
|
|
81
|
+
.trim()
|
|
82
|
+
.split(/\s+/)
|
|
83
|
+
.map((part) => part.toLowerCase())
|
|
84
|
+
.join(" ");
|
|
85
|
+
return bip39.mnemonicToSeedSync(normalizedMnemonic);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Derives a private key from a mnemonic seed phrase.
|
|
90
|
+
*
|
|
91
|
+
* To derive multiple keys from the same phrase, change the path
|
|
92
|
+
* @param keyType the key type seed used to derive keys
|
|
93
|
+
* @param path the BIP44 path
|
|
94
|
+
* @param seedPhrase the mnemonic seed phrase
|
|
95
|
+
* @param offset the offset used for key derivation, defaults to [HARDENED_OFFSET]
|
|
96
|
+
*/
|
|
97
|
+
export const derivePrivateKeyFromMnemonic = (
|
|
98
|
+
keyType: KeyType,
|
|
99
|
+
path: string,
|
|
100
|
+
seedPhrase: string,
|
|
101
|
+
offset = HARDENED_OFFSET,
|
|
102
|
+
): DerivedKeys => {
|
|
103
|
+
if (!isValidPath(path)) {
|
|
104
|
+
throw new Error("Invalid derivation path");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Derive the master key from the mnemonic
|
|
108
|
+
const { key, chainCode } = deriveKey(keyType, mnemonicToSeed(seedPhrase));
|
|
109
|
+
const segments = splitPath(path).map((el) => parseInt(el, 10));
|
|
110
|
+
|
|
111
|
+
// Derive the child key based on the path
|
|
112
|
+
return segments.reduce((parentKeys, segment) => CKDPriv(parentKeys, segment + offset), { key, chainCode });
|
|
113
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sleep the current thread for the given amount of time
|
|
6
|
+
* @param timeMs time in milliseconds to sleep
|
|
7
|
+
*/
|
|
8
|
+
export async function sleep(timeMs: number): Promise<null> {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
setTimeout(resolve, timeMs);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Copyright © Aptos Foundation
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The global cache Map shared across all functions. Must keep care to ensure that the
|
|
6
|
+
* cache keys are unique across all functions.
|
|
7
|
+
*/
|
|
8
|
+
const cache = new Map<string, { value: any; timestamp: number }>();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A memoize high order function to cache async function response
|
|
12
|
+
*
|
|
13
|
+
* @param func An async function to cache the result of
|
|
14
|
+
* @param key The provided cache key
|
|
15
|
+
* @param ttlMs time-to-live in milliseconds for cached data
|
|
16
|
+
* @returns the cached or latest result
|
|
17
|
+
*/
|
|
18
|
+
export function memoizeAsync<T>(
|
|
19
|
+
func: (...args: any[]) => Promise<T>,
|
|
20
|
+
key: string,
|
|
21
|
+
ttlMs?: number,
|
|
22
|
+
): (...args: any[]) => Promise<T> {
|
|
23
|
+
return async (...args: any[]) => {
|
|
24
|
+
// Check if the cached result exists and is within TTL
|
|
25
|
+
if (cache.has(key)) {
|
|
26
|
+
const { value, timestamp } = cache.get(key)!;
|
|
27
|
+
if (ttlMs === undefined || Date.now() - timestamp <= ttlMs) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If not cached or TTL expired, compute the result
|
|
33
|
+
const result = await func(...args);
|
|
34
|
+
|
|
35
|
+
// Cache the result with a timestamp
|
|
36
|
+
cache.set(key, { value: result, timestamp: Date.now() });
|
|
37
|
+
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A memoize high order function to cache function response
|
|
44
|
+
*
|
|
45
|
+
* @param func A function to cache the result of
|
|
46
|
+
* @param key The provided cache key
|
|
47
|
+
* @param ttlMs time-to-live in milliseconds for cached data
|
|
48
|
+
* @returns the cached or latest result
|
|
49
|
+
*/
|
|
50
|
+
export function memoize<T>(func: (...args: any[]) => T, key: string, ttlMs?: number): (...args: any[]) => T {
|
|
51
|
+
return (...args: any[]) => {
|
|
52
|
+
// Check if the cached result exists and is within TTL
|
|
53
|
+
if (cache.has(key)) {
|
|
54
|
+
const { value, timestamp } = cache.get(key)!;
|
|
55
|
+
if (ttlMs === undefined || Date.now() - timestamp <= ttlMs) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If not cached or TTL expired, compute the result
|
|
61
|
+
const result = func(...args);
|
|
62
|
+
|
|
63
|
+
// Cache the result with a timestamp
|
|
64
|
+
cache.set(key, { value: result, timestamp: Date.now() });
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
}
|