Skip to content

Conversation

p2arthur
Copy link

Fix Dual Package Hazard with Symbol.hasInstance (Draft)

Status: Draft — currently updating utils-ts

Problem

When a package is loaded as both CommonJS and ESM, instanceof checks can fail across boundaries because the same class is created twice (one per loader). This can make instanceof return false for valid instances.

Solution

Add a unique instance marker property and a static Symbol.hasInstance method to each class so instanceof works regardless of how the class was loaded.

Pattern example:

export class SomeClass {
  // unique marker on instances
  private readonly _isSomeClass = true;

  // cross-module instanceof check
  static [Symbol.hasInstance](instance: unknown): boolean {
    return !!(instance && (instance as any)._isSomeClass === true);
  }
}

After applying the pattern to a file, change [] to [x].


Files to Update (tick as you go)

  • ./types/account.ts:20MultisigAccount
  • ./types/account.ts:79SigningAccount (implements Account)
  • [] ./types/app-arc56.ts:23Arc56Method (extends algosdk.ABIMethod)
  • [] ./types/app-client.ts:478AppClient
  • [] ./types/app-client.ts:1794ApplicationClient
  • [] ./types/app-manager.ts:98AppManager
  • [] ./types/account-manager.ts:46AccountManager
  • [] ./types/algorand-client-transaction-sender.ts:36AlgorandClientTransactionSender
  • ./types/app-deployer.ts:112AppDeployer
  • [] ./types/logic-error.ts:22LogicError (extends Error)
  • [] ./types/client-manager.ts:48ClientManager
  • [] ./types/algorand-client.ts:18AlgorandClient
  • [] ./types/async-event-emitter.ts:5AsyncEventEmitter
  • [] ./types/kmd-account-manager.ts:10KmdAccountManager
  • [] ./types/algorand-client-transaction-creator.ts:8AlgorandClientTransactionCreator
  • ./types/composer.ts:547TransactionComposer
  • [] ./types/algo-http-client-with-retry.ts:6AlgoHttpClientWithRetry (extends URLTokenBaseHTTPClient)
  • [] ./types/dispenser-client.ts:72TestNetDispenserApiClient
  • [] ./types/config.ts:28UpdatableConfig (implements Readonly<Config>)
  • [] ./types/amount.ts:4AlgoAmount
  • [] ./types/asset-manager.ts:138AssetManager
  • [] ./types/app-factory.ts:170AppFactory
  • ./testing/test-logger.ts:8TestLogger (implements Logger)
  • [] ./testing/transaction-logger.ts:12TransactionLogger
  • [] ./util.ts:25UnsafeConversionError (extends Error)

Testing

  • tests/11.DualPackageHazard.ts verifies cross-module instanceof for both CJS and ESM.
  • Optional manual check: import the same class via CJS and ESM and confirm instanceof returns true across boundaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant