-
-
Notifications
You must be signed in to change notification settings - Fork 683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: .extend performance #2328
fix: .extend performance #2328
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,7 +54,7 @@ jobs: | |
timeout-minutes: 5 | ||
strategy: | ||
matrix: | ||
typescript-version: ['5.3.2', 'latest'] | ||
version: ['5.0.4', '5.1.6', '5.2.2', '5.3.3', '5.4.5'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. test against more ts versions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wonder if it's worth the work to fix the types that are incompatible with older versions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indeed. on it! |
||
|
||
steps: | ||
- name: Clone repository | ||
|
@@ -65,7 +65,7 @@ jobs: | |
- name: Install dependencies | ||
uses: ./.github/actions/install-dependencies | ||
|
||
- run: bun i -d typescript@${{ matrix.typescript-version }} | ||
- run: bun i -d typescript@${{ matrix.version }} | ||
|
||
- name: Build contracts | ||
shell: bash | ||
|
@@ -74,10 +74,15 @@ jobs: | |
- name: Check types | ||
run: bun run typecheck | ||
|
||
- name: Test types | ||
run: bun run test:typecheck | ||
env: | ||
VITE_ANVIL_BLOCK_NUMBER: ${{ vars.VITE_ANVIL_BLOCK_NUMBER }} | ||
- name: Bench types | ||
run: bun run typebench | ||
|
||
# Redundant with `pnpm typecheck` | ||
# If Vitest adds special features in the future, e.g. type coverage, can add this back! | ||
# - name: Test types | ||
# run: bun run test:typecheck | ||
# env: | ||
# VITE_ANVIL_BLOCK_NUMBER: ${{ vars.VITE_ANVIL_BLOCK_NUMBER }} | ||
|
||
test: | ||
name: Test | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ _esm | |
_types | ||
*.local | ||
.DS_Store | ||
.attest | ||
.eslintcache | ||
.next | ||
bench | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these type benchmarking tests make sure the types don't blow up too much |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { bench } from '@arktype/attest' | ||
|
||
import { createClient } from './createClient.js' | ||
import { createPublicClient } from './createPublicClient.js' | ||
import { publicActions } from './decorators/public.js' | ||
import { http } from './transports/http.js' | ||
|
||
bench('createPublicClient', () => { | ||
const client = createPublicClient({ transport: http() }) | ||
return {} as typeof client | ||
}).types([13470, 'instantiations']) | ||
|
||
bench('createClient.extend + publicActions', () => { | ||
const client = createClient({ transport: http() }).extend(publicActions) | ||
return {} as typeof client | ||
}).types([246356, 'instantiations']) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { bench } from '@arktype/attest' | ||
|
||
import { createClient } from './createClient.js' | ||
import { createWalletClient } from './createWalletClient.js' | ||
import { walletActions } from './decorators/wallet.js' | ||
import { http } from './transports/http.js' | ||
|
||
bench('createWalletClient', () => { | ||
const client = createWalletClient({ transport: http() }) | ||
return {} as typeof client | ||
}).types([1384, 'instantiations']) | ||
|
||
bench('createClient.extend + walletActions', () => { | ||
const client = createClient({ transport: http() }).extend(walletActions) | ||
return {} as typeof client | ||
}).types([193153, 'instantiations']) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,17 @@ | ||
import type { AbiStateMutability, Narrow } from 'abitype' | ||
import type { Abi, AbiStateMutability, Address, Narrow } from 'abitype' | ||
|
||
import type { Client } from '../../../clients/createClient.js' | ||
import type { Transport } from '../../../clients/transports/createTransport.js' | ||
import type { ErrorType } from '../../../errors/utils.js' | ||
import type { Account, GetAccountParameter } from '../../../types/account.js' | ||
import type { Chain, GetChainParameter } from '../../../types/chain.js' | ||
import type { ContractFunctionParameters } from '../../../types/contract.js' | ||
import type { | ||
ContractFunctionArgs, | ||
ContractFunctionName, | ||
GetValue, | ||
UnionWiden, | ||
Widen, | ||
} from '../../../types/contract.js' | ||
import type { MulticallContracts } from '../../../types/multicall.js' | ||
import { | ||
type EncodeFunctionDataErrorType, | ||
|
@@ -19,7 +25,8 @@ import { | |
} from './sendCalls.js' | ||
|
||
export type WriteContractsParameters< | ||
contracts extends readonly unknown[] = readonly ContractFunctionParameters[], | ||
contracts extends | ||
readonly unknown[] = readonly WriteContractFunctionParameters[], | ||
chain extends Chain | undefined = Chain | undefined, | ||
account extends Account | undefined = Account | undefined, | ||
chainOverride extends Chain | undefined = Chain | undefined, | ||
|
@@ -98,7 +105,7 @@ export async function writeContracts< | |
chainOverride | ||
>, | ||
): Promise<WriteContractsReturnType> { | ||
const contracts = parameters.contracts as ContractFunctionParameters[] | ||
const contracts = parameters.contracts as WriteContractFunctionParameters[] | ||
const calls = contracts.map((contract) => { | ||
const { address, abi, functionName, args, value } = contract | ||
return { | ||
|
@@ -113,3 +120,30 @@ export async function writeContracts< | |
}) | ||
return sendCalls(client, { ...parameters, calls } as SendCallsParameters) | ||
} | ||
|
||
export type WriteContractFunctionParameters< | ||
abi extends Abi | readonly unknown[] = Abi, | ||
mutability extends AbiStateMutability = AbiStateMutability, | ||
functionName extends ContractFunctionName< | ||
abi, | ||
mutability | ||
> = ContractFunctionName<abi, mutability>, | ||
args extends ContractFunctionArgs< | ||
abi, | ||
mutability, | ||
functionName | ||
> = ContractFunctionArgs<abi, mutability, functionName>, | ||
/// | ||
allFunctionNames = ContractFunctionName<abi, mutability>, | ||
allArgs = ContractFunctionArgs<abi, mutability, functionName>, | ||
// when `args` is inferred to `readonly []` ("inputs": []) or `never` (`abi` declared as `Abi` or not inferrable), allow `args` to be optional. | ||
// important that both branches return same structural type | ||
> = { | ||
address: Address | ||
abi: abi | ||
functionName: | ||
| allFunctionNames // show all options | ||
| (functionName extends allFunctionNames ? functionName : never) // infer value | ||
args?: (abi extends Abi ? UnionWiden<args> : never) | allArgs | undefined | ||
} & (readonly [] extends allArgs ? {} : { args: Widen<args> }) & | ||
GetValue<abi, functionName> | ||
Comment on lines
+124
to
+149
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. duplicated this type here for now. will address during some more extensive cleanup. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -209,9 +209,7 @@ export type ContractFunctionParameters< | |
| allFunctionNames // show all options | ||
| (functionName extends allFunctionNames ? functionName : never) // infer value | ||
args?: (abi extends Abi ? UnionWiden<args> : never) | allArgs | undefined | ||
} & (readonly [] extends allArgs ? {} : { args: Widen<args> }) & | ||
// TODO: Remove `GetValue` from here (should be applied to top-level type as separate utility) | ||
GetValue<abi, functionName> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} & (readonly [] extends allArgs ? {} : { args: Widen<args> }) | ||
|
||
export type ContractFunctionReturnType< | ||
abi extends Abi | readonly unknown[] = Abi, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { globby } from 'globby' | ||
import { tsImport } from 'tsx/esm/api' | ||
|
||
const paths = await globby(['src/**/*.bench-d.ts']) | ||
for (const path of paths) { | ||
await tsImport(`../${path}`, import.meta.url) | ||
} |
tmm marked this conversation as resolved.
Show resolved
Hide resolved
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for this lol