import type { Artifact } from "../types/artifact.js"; import type { AccountRuntimeValue, AddressResolvableFuture, ArgumentType, ContractAtFuture, ContractDeploymentFuture, LibraryDeploymentFuture, ContractFuture, Future, IgnitionModule, IgnitionModuleResult, ModuleParameterRuntimeValue, ModuleParameterType, NamedArtifactContractAtFuture, ContractCallFuture, NamedArtifactContractDeploymentFuture, NamedArtifactLibraryDeploymentFuture, StaticCallFuture, ReadEventArgumentFuture, SendDataFuture, EncodeFunctionCallFuture, } from "../types/module.js"; import { FutureType, RuntimeValueType } from "../types/module.js"; const CUSTOM_INSPECT_SYMBOL: symbol = Symbol.for("nodejs.util.inspect.custom"); abstract class BaseFutureImplementation { public readonly dependencies: Set = new Set(); constructor( public readonly id: string, public readonly type: FutureTypeT, public readonly module: IgnitionModuleImplementation, ) { Object.defineProperty(this, CUSTOM_INSPECT_SYMBOL, { value: ( _depth: number, { inspect }: { inspect: (arg: {}) => string }, ) => { const padding = " ".repeat(2); return `Future ${this.id} { Type: ${FutureType[this.type]} Module: ${this.module.id} Dependencies: ${inspect( Array.from(this.dependencies).map((f) => f.id), ).replace(/\n/g, `\n${padding}`)} }`; }, writable: false, enumerable: false, configurable: true, }); } } export class NamedContractDeploymentFutureImplementation< ContractNameT extends string, > extends BaseFutureImplementation implements NamedArtifactContractDeploymentFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: ContractNameT, public readonly constructorArgs: ArgumentType[], public readonly libraries: Record>, public readonly value: | bigint | ModuleParameterRuntimeValue | StaticCallFuture | ReadEventArgumentFuture, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT, module); } } export class ArtifactContractDeploymentFutureImplementation< ContractNameT extends string, > extends BaseFutureImplementation implements ContractDeploymentFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: ContractNameT, public readonly constructorArgs: ArgumentType[], public readonly artifact: Artifact, public readonly libraries: Record>, public readonly value: | bigint | ModuleParameterRuntimeValue | StaticCallFuture | ReadEventArgumentFuture, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.CONTRACT_DEPLOYMENT, module); } } export class NamedLibraryDeploymentFutureImplementation< LibraryNameT extends string, > extends BaseFutureImplementation implements NamedArtifactLibraryDeploymentFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: LibraryNameT, public readonly libraries: Record>, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT, module); } } export class ArtifactLibraryDeploymentFutureImplementation< LibraryNameT extends string, > extends BaseFutureImplementation implements LibraryDeploymentFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: LibraryNameT, public readonly artifact: Artifact, public readonly libraries: Record>, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.LIBRARY_DEPLOYMENT, module); } } export class NamedContractCallFutureImplementation< ContractNameT extends string, FunctionNameT extends string, > extends BaseFutureImplementation implements ContractCallFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly functionName: FunctionNameT, public readonly contract: ContractFuture, public readonly args: ArgumentType[], public readonly value: | bigint | ModuleParameterRuntimeValue | StaticCallFuture | ReadEventArgumentFuture, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.CONTRACT_CALL, module); } } export class NamedStaticCallFutureImplementation< ContractNameT extends string, FunctionNameT extends string, > extends BaseFutureImplementation implements StaticCallFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly functionName: FunctionNameT, public readonly contract: ContractFuture, public readonly args: ArgumentType[], public readonly nameOrIndex: string | number, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.STATIC_CALL, module); } } export class NamedEncodeFunctionCallFutureImplementation< ContractNameT extends string, FunctionNameT extends string, > extends BaseFutureImplementation implements EncodeFunctionCallFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly functionName: FunctionNameT, public readonly contract: ContractFuture, public readonly args: ArgumentType[], ) { super(id, FutureType.ENCODE_FUNCTION_CALL, module); } } export class NamedContractAtFutureImplementation extends BaseFutureImplementation implements NamedArtifactContractAtFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: ContractNameT, public readonly address: | string | AddressResolvableFuture | ModuleParameterRuntimeValue, ) { super(id, FutureType.NAMED_ARTIFACT_CONTRACT_AT, module); } } export class ArtifactContractAtFutureImplementation extends BaseFutureImplementation implements ContractAtFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly contractName: string, public readonly address: | string | AddressResolvableFuture | ModuleParameterRuntimeValue, public readonly artifact: Artifact, ) { super(id, FutureType.CONTRACT_AT, module); } } export class ReadEventArgumentFutureImplementation extends BaseFutureImplementation implements ReadEventArgumentFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly futureToReadFrom: | NamedArtifactContractDeploymentFuture | ContractDeploymentFuture | SendDataFuture | ContractCallFuture, public readonly eventName: string, public readonly nameOrIndex: string | number, public readonly emitter: ContractFuture, public readonly eventIndex: number, ) { super(id, FutureType.READ_EVENT_ARGUMENT, module); } } export class SendDataFutureImplementation extends BaseFutureImplementation implements SendDataFuture { constructor( public override readonly id: string, public override readonly module: IgnitionModuleImplementation, public readonly to: | string | AddressResolvableFuture | ModuleParameterRuntimeValue | AccountRuntimeValue, public readonly value: bigint | ModuleParameterRuntimeValue, public readonly data: | string | EncodeFunctionCallFuture | undefined, public readonly from: string | AccountRuntimeValue | undefined, ) { super(id, FutureType.SEND_DATA, module); } } export class IgnitionModuleImplementation< ModuleIdT extends string = string, ContractNameT extends string = string, IgnitionModuleResultsT extends IgnitionModuleResult = IgnitionModuleResult, > implements IgnitionModule { public readonly futures: Set = new Set(); public readonly submodules: Set = new Set(); constructor( public readonly id: ModuleIdT, public readonly results: IgnitionModuleResultsT, ) { Object.defineProperty(this, CUSTOM_INSPECT_SYMBOL, { value: ( _depth: number, { inspect }: { inspect: (arg: {}) => string }, ) => { const padding = " ".repeat(2); return `IgnitionModule ${this.id} { Futures: ${inspect(this.futures).replace(/\n/g, `\n${padding}`)} Results: ${inspect(this.results).replace(/\n/g, `\n${padding}`)} Submodules: ${inspect( Array.from(this.submodules).map((m) => m.id), ).replace(/\n/g, `\n${padding}`)} }`; }, writable: false, enumerable: false, configurable: true, }); } } export class AccountRuntimeValueImplementation implements AccountRuntimeValue { public readonly type: RuntimeValueType.ACCOUNT = RuntimeValueType.ACCOUNT; constructor(public readonly accountIndex: number) { Object.defineProperty(this, CUSTOM_INSPECT_SYMBOL, { value: ( _depth: number, _inspectOptions: { inspect: (arg: {}) => string }, ) => { return `Account RuntimeValue { accountIndex: ${this.accountIndex} }`; }, writable: false, enumerable: false, configurable: true, }); } } export class ModuleParameterRuntimeValueImplementation< ParamTypeT extends ModuleParameterType, > implements ModuleParameterRuntimeValue { public readonly type: RuntimeValueType.MODULE_PARAMETER = RuntimeValueType.MODULE_PARAMETER; constructor( public readonly moduleId: string, public readonly name: string, public readonly defaultValue: ParamTypeT | undefined, ) { Object.defineProperty(this, CUSTOM_INSPECT_SYMBOL, { value: ( _depth: number, { inspect }: { inspect: (arg: {}) => string }, ) => { return `Module Parameter RuntimeValue { name: ${this.name}${ this.defaultValue !== undefined ? ` default value: ${inspect(this.defaultValue)}` : "" } }`; }, writable: false, enumerable: false, configurable: true, }); } }