8000 fix: use `toString` and `prototype` instead of `constructor` for type checking by JounQin · Pull Request #9 · un-ts/stable-hash-x · GitHub
[go: up one dir, main page]

Skip to content

fix: use toString and prototype instead of constructor for type checking #9

8000
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

Merged
merged 1 commit into from
Jun 25, 2025

Conversation

JounQin
Copy link
Member
@JounQin JounQin commented Jun 25, 2025

close shuding/stable-hash#22


Important

Replace constructor with toString and prototype for type checking in stable-hash-x, adding cross-realm support and updating documentation and configurations.

  • Behavior:
    • Replace constructor with toString and prototype for type checking in src/index.ts.
    • Add test for cross-realm object hashing in unit.spec.ts.
  • Documentation:
    • Update size in README.md to 540B to reflect new functionality.
  • Configuration:
    • Update size limit in .size-limit.json to 540B.
    • Add /public/site.webmanifest to .prettierignore.

This description was created by Ellipsis for 381208a. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features

    • Improved support for hashing objects across JavaScript realms, ensuring consistent hashes for equivalent objects from different contexts.
  • Bug Fixes

    • Enhanced type detection for objects, dates, and regular expressions, increasing reliability in hashing.
  • Documentation

    • Updated README to reflect increased library size and new cross-realm support.
  • Chores

    • Updated formatting ignore rules and increased allowed bundle size limit.

@JounQin JounQin self-assigned this Jun 25, 2025
@Copilot Copilot AI review requested due to automatic review settings June 25, 2025 07:13
@JounQin JounQin added the bug Something isn't working label Jun 25, 2025
Copy link
changeset-bot bot commented Jun 25, 2025

🦋 Changeset detected

Latest commit: 381208a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
stable-hash-x Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%) 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (13da38b) 45 45 100.00%
Head commit (600adfa) 54 (+9) 54 (+9) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#9) 14 14 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Copy link
coderabbitai bot commented Jun 25, 2025

Walkthrough

This update replaces direct constructor comparisons with type checks using Object.prototype.toString and prototype inspection in the hashing logic, enabling accurate type detection across JavaScript realms. The test suite is expanded to verify consistent hashing for objects from different realms. Documentation and configuration files are also updated accordingly.

Changes

File(s) Change Summary
src/index.ts Replaced constructor checks with isType and isPlainObject for cross-realm type detection.
tests/unit.spec.ts Added a test to ensure stable hashes for objects from different realms (using Node.js vm).
README.md Updated library size and noted support for cross-realm objects.
.size-limit.json Increased allowed bundle size from 460 to 540 bytes.
.prettierignore Added /public/site.webmanifest to Prettier ignore list.
.changeset/easy-boxes-shine.md Added a changeset entry describing the patch and its rationale.

Sequence Diagram(s)

sequenceDiagram
    participant Test
    participant VM
    participant Hash

    Test->>Hash: hash(obj1)
    Test->>VM: runInNewContext
    VM->>Hash: hash(obj2)
    Hash->>Hash: isType/isPlainObject checks (toString/prototype)
    Hash-->>Test: return hash for obj1 and obj2
    Test->>Test: assert hash(obj1) === hash(obj2)
Loading

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Use Object.prototype.toString for type checking across vm/iframe contexts (#22)

Suggested labels

internal, documentation

Poem

A hash that works from realm to realm,
No constructor tricks at the helm.
With toString keen, and prototypes too,
The hashes match—across each view!
Now objects from VM or frame,
Are hashed as one—always the same.
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/index.ts

Oops! Something went wrong! :(

ESLint: 9.29.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@1stg/eslint-config' imported from /eslint.config.js
at Object.getPackageJSONURL (node:internal/modules/package_json_reader:255:9)
at packageResolve (node:internal/modules/esm/resolve:767:81)
at moduleResolve (node:internal/modules/esm/resolve:853:18)
at defaultResolve (node:internal/modules/esm/resolve:983:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:801:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:725:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:708:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:309:38)
at #link (node:internal/modules/esm/module_job:201:49)

tests/unit.spec.ts

Oops! Something went wrong! :(

ESLint: 9.29.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@1stg/eslint-config' imported from /eslint.config.js
at Object.getPackageJSONURL (node:internal/modules/package_json_reader:255:9)
at packageResolve (node:internal/modules/esm/resolve:767:81)
at moduleResolve (node:internal/modules/esm/resolve:853:18)
at defaultResolve (node:internal/modules/esm/resolve:983:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:801:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:725:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:708:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:309:38)
at #link (node:internal/modules/esm/module_job:201:49)

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
codesandbox-ci bot commented Jun 25, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link
codecov bot commented Jun 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (13da38b) to head (381208a).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main        #9   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            1         1           
  Lines           48        59   +11     
  Branches        15        19    +4     
=========================================
+ Hits            48        59   +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces constructor-based type checks with Object.prototype.toString for more reliable type detection, adds a helper to recognize plain objects, and includes a cross-realm hashing test to ensure consistent behavior across VM contexts. It also updates documentation and bundle-size limits to account for these changes.

  • Introduce isType and isPlainObject helpers and update stableHash to use them
  • Add a unit test for hashing objects across realms
  • Update README and size-limit to reflect cross-realm support and new bundle size

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/index.ts Replace constructor checks with isType and isPlainObject helpers
tests/unit.spec.ts Add across realms test using runInNewContext
README.md Note cross-realm support and update bundle size
.size-limit.json Bump size limit from 460B to 540B
Comments suppressed due to low confidence (4)

src/index.ts:16

  • Consider adding a unit test for plain objects with a null prototype (e.g., Object.create(null)) to ensure isPlainObject handles this case correctly.
const isPlainObject = (val: object) => {

tests/unit.spec.ts:368

  • Add a cross-realm RegExp hashing test to verify that regular expressions from different contexts produce consistent hashes.
  test('across realms', () => {

src/index.ts:12

  • Add a brief JSDoc comment above isType explaining that it checks the internal [[Class]] tag of an object for more reliable type detection.
const isType = (arg: unknown, type: string): boolean =>

src/index.ts:12

  • [nitpick] The helper name isType is quite generic; consider renaming it to something more descriptive like hasTypeTag or isObjectTypeTag for clarity.
const isType = (arg: unknown, type: string): boolean =>

Copy link
pkg-pr-new bot commented Jun 25, 2025

Open in StackBlitz

npm i https://pkg.pr.new/stable-hash-x@9

commit: 381208a

Copy link
Contributor
github-actions bot commented Jun 25, 2025

size-limit report 📦

Path Size
lib/index.js 533 B (+15.87% 🔺)

Copy link
codacy-production bot commented Jun 25, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+0.00% (target: -1.00%) 100.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (13da38b) 45 45 100.00%
Head commit (381208a) 54 (+9) 54 (+9) 100.00% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#9) 14 14 100.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Copy link
Contributor
@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 600adfa in 50 seconds. Click for details.
  • Reviewed 129 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 9 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. .size-limit.json:4
  • Draft comment:
    Updated bundle size limit to 540B to reflect the increased bundle size from added cross‐realm support.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. README.md:16
  • Draft comment:
    Documentation updated to show the new size (540B) and mention cross‐realm support.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. src/index.ts:10
  • Draft comment:
    Destructuring Object.prototype.toString ensures robust type checking, even if a user overrides toString.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
4. src/index.ts:12
  • Draft comment:
    Introducing the isType helper provides consistent type checking (via Object.prototype.toString) across realms.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
5. src/index.ts:36
  • Draft comment:
    Replacing the constructor-based Date check with isType improves cross-realm compatibility.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
6. src/index.ts:38
  • Draft comment:
    Using '!isType(arg, "RegExp")' instead of a constructor check makes the RegExp detection more robust across different realms.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
7. src/index.ts:52
  • Draft comment:
    Switching to Array.isArray for array detection is a best practice compared to constructor checks.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
8. src/index.ts:60
  • Draft comment:
    Replacing the constructor check for plain objects with the isPlainObject helper boosts robustness, especially for cross-realm objects.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
9. tests/unit.spec.ts:368
  • Draft comment:
    Added a cross‐realm test to verify that hashing yields consistent results across different VM contexts.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_G8iK9LHlGSdx9ZNC

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor
github-actions bot commented Jun 25, 2025

Deploy preview for stable-hash-x ready!

✅ Preview
https://stable-hash-32qrc7jzs-1stg.vercel.app

Built with commit 381208a.
This pull request is being automatically deployed with vercel-action

Copy link
Contributor
github-actions bot commented Jun 25, 2025

📊 Package size report   3%↑

File Before After
lib/index.cjs 1.2 kB 18%↑1.4 kB
lib/index.js 1.2 kB 18%↑1.4 kB
README.md 10.3 kB 0.3%↑10.3 kB
Total (Includes all files) 17.0 kB 3%↑17.5 kB
Tarball size 5.7 kB 2%↑5.8 kB
Unchanged files
File Size
lib/index.d.cts 131 B
lib/index.d.ts 131 B
LICENSE 1.1 kB
package.json 3.1 kB

🤖 This report was automatically generated by pkg-size-action

Copy link
Contributor
@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed 381208a in 1 minute and 0 seconds. Click for details.
  • Reviewed 147 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 9 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. .prettierignore:2
  • Draft comment:
    Ensure that ignoring '/public/site.webmanifest' is intentional.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
2. .size-limit.json:4
  • Draft comment:
    Bump to 540B: verify that the new size limit accurately reflects the updated output.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
3. README.md:16
  • Draft comment:
    Documentation now shows 540b and mentions cross‐realm support. Confirm that this accurately reflects the library's behavior.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
4. src/index.ts:12
  • Draft comment:
    Good use of Object.prototype.toString via the isType helper for robust type checking across different realms.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
5. src/index.ts:36
  • Draft comment:
    Replacing constructor-based checks with isType for Date and RegExp improves cross-realm compatibility.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
6. src/index.ts:52
  • Draft comment:
    Using Array.isArray instead of a constructor check is a best practice for array detection.
  • Reason this comment was not posted:
    Confidence changes req 8000 uired: 0% <= threshold 50% None
7. src/index.ts:60
  • Draft comment:
    Using isPlainObject for plain object detection is a solid improvement over direct constructor comparison.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
8. src/index.ts:65
  • Draft comment:
    Iterating over sorted keys by popping from the array works but may be less intuitive; consider a forward iteration for clarity.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
9. tests/unit.spec.ts:368
  • Draft comment:
    Nice addition: the 'across realms' test effectively validates that cross-realm objects produce the same hash.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_rojaKbcPWV74bSEj

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
.prettierignore (1)

2-2: Consider if this change belongs in this PR.

Adding /public/site.webmanifest to the ignore list seems unrelated to the main PR objective of cross-realm object support. While harmless, consider whether this should be in a separate commit or PR focused on project configuration.

src/index.ts (1)

9-10: Address variable shadowing warning.

The static analysis tool correctly identifies that extracting toString shadows the global property. Consider renaming to avoid confusion.

Apply this diff to address the shadowing:

-// eslint-disable-next-line @typescript-eslint/unbound-method
-const { toString } = Object.prototype // type-coverage:ignore-line
+// eslint-disable-next-line @typescript-eslint/unbound-method
+const { toString: objectToString } = Object.prototype // type-coverage:ignore-line

Then update the usage in the isType function:

 const isType = (arg: unknown, type: string): boolean =>
-  toString.call(arg) === `[object ${type}]`
+  objectToString.call(arg) === `[object ${type}]`
README.md (1)

16-16: LGTM! Documentation accurately reflects the improvements.

The updated description correctly mentions both the new size (540B) and the added cross-realm object support, which aligns perfectly with the technical changes implemented.

Optional style improvement based on static analysis:

-A tiny and fast (540b <sup>[unpkg](https://unpkg.com/stable-hash-x@latest/lib/index.js)</sup>) lib for "stably hashing" a JavaScript value, works with cross-realm objects. Originally created for [SWR](https://github.com/vercel/swr) by [Shu Ding][] at [`stable-hash`](https://github.com/shuding/stable-hash), we forked it because the original one is a bit out of maintenance for a long time.
+A tiny and fast (540b <sup>[unpkg](https://unpkg.com/stable-hash-x@latest/lib/index.js)</sup>) lib for "stably hashing" a JavaScript value, works with cross-realm objects. Created for [SWR](https://github.com/vercel/swr) by [Shu Ding][] at [`stable-hash`](https://github.com/shuding/stable-hash), we forked it because the original one is a bit out of maintenance for a long time.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13da38b and 381208a.

📒 Files selected for processing (6)
  • .changeset/easy-boxes-shine.md (1 hunks)
  • .prettierignore (1 hunks)
  • .size-limit.json (1 hunks)
  • README.md (1 hunks)
  • src/index.ts (4 hunks)
  • tests/unit.spec.ts (2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[style] ~16-~16: This phrase is redundant. Consider writing “created”.
Context: ... value, works with cross-realm objects. Originally created for [SWR](https://github.com/vercel/swr...

(ORIGINALLY_CREATED)

🪛 Biome (1.9.4)
src/index.ts

[error] 10-10: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Lint and Test with Node.js 20 on macos-latest
  • GitHub Check: Lint and Test with Node.js 22 on macos-latest
  • GitHub Check: Lint and Test with Node.js 20 on windows-latest
  • GitHub Check: Lint and Test with Node.js 18 on windows-latest
  • GitHub Check: Lint and Test with Node.js 22 on windows-latest
  • GitHub Check: Lint and Test with Node.js 24 on macos-latest
  • GitHub Check: Lint and Test with Node.js 18 on macos-latest
  • GitHub Check: Lint and Test with Node.js 24 on windows-latest
🔇 Additional comments (8)
.size-limit.json (1)

4-4: LGTM! Size increase reflects added cross-realm functionality.

The 80-byte increase (from 460B to 540B) is reasonable for the added cross-realm object support implemented through the new isType and isPlainObject utility functions.

src/index.ts (4)

12-13: LGTM! Excellent cross-realm type detection.

The isType function using Object.prototype.toString.call() is the correct approach for cross-realm type detection. This will consistently return type strings like "[object Date]" regardless of the JavaScript realm.


15-23: LGTM! Robust plain object detection.

The isPlainObject implementation correctly handles cross-realm scenarios by checking prototype chains rather than constructors. The logic properly identifies:

  • Objects with null prototype (Object.create(null))
  • Objects with Object.prototype as prototype
  • Objects whose prototype's prototype is null (e.g., Object.create(Object.prototype))

This approach works consistently across JavaScript realms.


36-38: LGTM! Proper replacement of constructor-based checks.

The replacement of constructor-based date and regex checks with isType calls ensures consistent behavior across JavaScript realms. The logic correctly excludes dates and regexes from the object hashing path.


52-60: LGTM! Array and plain object detection improved.

Replacing Array.isArray() and constructor-based object checks with the new utility functions ensures consistent behavior across realms. The isPlainObject check properly identifies objects that should have their keys sorted for stable hashing.

.changeset/easy-boxes-shine.md (1)

1-6: LGTM! Properly documented changeset.

The changeset correctly categorizes this as a patch-level fix and accurately describes the core change from constructor-based to toString/prototype-based type checking.

tests/unit.spec.ts (2)

3-3: Good use of modern Node.js import syntax.

The import uses the recommended node: prefix for built-in modules, which is a best practice for modern Node.js applications.


368-383: Excellent test coverage for cross-realm functionality.

This test effectively validates the core improvement described in the PR objectives. The test design is comprehensive:

  • Tests multiple object types (number, Date, RegExp, Symbol) across realms
  • Correctly verifies that objects from different realms are not strictly equal
  • Validates that the new hashing implementation produces consistent hashes across realms

The Symbol handling is particularly noteworthy - even though Symbol('test') creates different symbol instances in each realm, the test expects consistent hashing, which suggests the implementation now hashes symbols by their description rather than identity.

@JounQin JounQin merged commit 8dcd38d into main Jun 25, 2025
43 checks passed
@JounQin JounQin deleted the fix/toString branch June 25, 2025 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Should use Object.prototype.toString to check constructor for vm/iframe, etc
1 participant
0