Skip to content

feat: schemasEqualStructurally & schemasEqualNominally - #3209

Open
iwoplaza wants to merge 1 commit into
mainfrom
feat/schemas-equal-structurally-nominally
Open

iwoplaza wants to merge 1 commit into
mainfrom
feat/schemas-equal-structurally-nominally

Conversation

@iwoplaza

@iwoplaza iwoplaza commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI balanced review requested due to automatic review settings October 16, 2026 12:44
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@0cd07292e9d18f88c72f49201ad4c632da156683
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/react@0cd07292e9d18f88c72f49201ad4c632da156683

benchmark
view benchmark

commit
view commit

@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch from 77eb7a9 to d0d1927 Compare October 16, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Nominal comparison accepts distinct, incompatible struct schemas, undermining accessor validation.

0 open findings

What changed in this PR

Introduces explicit structural and nominal schema comparisons in TypeGPU, with nominal matching for accessor validation.

Changes:

  • Adds both comparison APIs and retains deepEqual as a deprecated alias.
  • Migrates serialization tests and React schema stabilization to structural comparison.
  • Adds nominal identity tests and renames existing comparison tests.
File Description
packages/​typegpu/​tests/​serializeDataSchema.test.ts Uses structural comparison for round trips.
packages/​typegpu/​tests/​serial.test.ts Updates resource schema comparisons.
packages/​typegpu/​tests/​internal/​schemasEqualStructurally.test.ts Checks structural pointer comparison.
packages/​typegpu/​tests/​internal/​schemasEqualNominally.test.ts Checks nominal pointer comparison.
packages/​typegpu/​tests/​internal/​deepEqual.test.ts Removes replaced pointer tests.
packages/​typegpu/​tests/​data/​schemasEqualStructurally.test.ts Preserves structural comparison coverage.
packages/​typegpu/​tests/​data/​schemasEqualNominally.test.ts Adds nominal identity coverage.
packages/​typegpu/​tests/​data/​deepEqual.test.ts Removes replaced structural tests.
packages/​typegpu/​src/​data/​schemasEqual.ts Implements both comparison modes.
packages/​typegpu/​src/​data/​index.ts Exports APIs and deprecated alias.
packages/​typegpu/​src/​core/​slot/​accessor.ts Switches validation to nominal comparison.
packages/​typegpu-react/​src/​core/​helper-hooks.ts Uses structural schema stabilization.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 2.37%) ❔ Unknown
0 343 6 2

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Test tsdown
d_deepEqual.ts 2.62 kB ($${\color{red}+2.4\%}$$)
d_schemasEqualNominally.ts 2.62 kB
d_schemasEqualStructurally.ts 2.62 kB

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.72, 1.45, 3.10, 5.10, 6.09, 9.61, 19.14, 17.43]
  line [0.65, 1.40, 3.16, 5.04, 6.01, 8.61, 18.04, 18.93]
  line [0.72, 1.40, 2.97, 4.92, 5.58, 9.82, 18.28, 20.56]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.24, 0.41, 0.53, 0.61, 0.80, 0.86, 1.00, 1.18]
  line [0.23, 0.38, 0.52, 0.61, 0.82, 0.86, 1.00, 1.10]
  line [0.27, 0.41, 0.55, 0.65, 0.85, 0.86, 1.03, 1.14]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.59, 1.57, 2.97, 5.56, 9.55, 19.11, 41.14, 84.83]
  line [0.66, 1.63, 3.06, 5.56, 9.48, 19.40, 41.41, 85.73]
  line [0.72, 1.68, 2.94, 5.13, 9.62, 19.75, 42.23, 85.41]
Loading

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

schemasEqualNominally does not compare structs/unstructs at all: it reports two distinct structs as equal. The PR's own nominal suite fails 8 assertions, and pnpm test:style also fails on schemasEqual.ts.

Reviewed changes

Reviewed the full diff introducing schemasEqualStructurally/schemasEqualNominally and the call-site migrations.

  • New comparison API — packages/typegpu/src/data/deepEqual.ts becomes schemasEqual.ts, with structural/nominal exports over a shared schemasEqual(a, b, structural); deepEqual is kept as a deprecated alias of the structural variant.
  • Call-site migration — react's useStableSchema and the serial/serialize tests use the structural function; packages/typegpu/src/core/slot/accessor.ts matchesSchema uses the nominal one.
  • Test reorganization — the old deepEqual suites are removed and split into structural/nominal suites (plus internal implicit-pointer tests).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/data/schemasEqual.ts Outdated
Comment thread packages/typegpu/src/data/schemasEqual.ts Outdated
Comment thread packages/typegpu/src/data/schemasEqual.ts Outdated
Comment thread packages/typegpu/src/core/slot/accessor.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ The new commit is a formatting pass only; it resolves the oxfmt nit from the previous review. The remaining findings there are still open.

Reviewed changes

Re-reviewed only the delta between 77eb7a9 and d0d1927.

  • Formatting — oxfmt applied across schemasEqual.ts, the two new comparison suites, serial.test.ts, and serializeDataSchema.test.ts; the extra blank line between the two exports is gone, and npx oxfmt --check now passes on those files.
  • No logic changes — packages/typegpu/src/data/schemasEqual.ts:58 still gates the struct branch on structural, so the 8 schemasEqualNominally failures reproduced against the previous commit still reproduce here (npx vitest run --project=!browser packages/typegpu/tests/data/schemasEqualNominally.test.ts → 8 failed).

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch 2 times, most recently from c47790e to 02acc88 Compare October 16, 2026 17:48

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

The nominal fix activates a regression at the matchesSchema call site. Now that schemasEqualNominally actually compares structs by identity, two existing accessor tests fail: pnpm test:unit reports 2 failed / 2918 passed (tests/accessor.test.ts > can provide parts of a bind group layout and > can provide a runtime-sized array).

Reviewed changes

Re-reviewed the delta since the prior pullfrog review (c47790e → 02acc88), which is confined to packages/typegpu/src/data/schemasEqual.ts.

  • Fixed the nominal struct skip — the isWgslStruct/isUnstruct branch is no longer gated on structural; in nominal mode it now returns a === b, so two distinct struct instances are no longer reported equal. The 8 previously-failing schemasEqualNominally assertions now pass.
  • Doc reflow — the @example/import block in the schemasEqualNominally doc comment was moved.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/core/slot/accessor.ts Outdated
Comment thread packages/typegpu/src/data/schemasEqual.ts Outdated
@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch from 02acc88 to 75e4e70 Compare October 18, 2026 10:18
@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch from 75e4e70 to 4fe1864 Compare October 18, 2026 10:42
@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch from 4fe1864 to ea51187 Compare October 19, 2026 11:39
@iwoplaza
iwoplaza added this pull request to stack #3222 October 19, 2026 11:39

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No critical issues — the accessor regression is fixed. One description mismatch noted inline.

Reviewed changes

Re-reviewed the delta since the prior pullfrog review (4fe1864 → ea51187), which touches only packages/typegpu/src/core/slot/accessor.ts.

  • Accessor switched back to structural comparison — matchesSchema uses schemasEqualStructurally instead of schemasEqualNominally, restoring the historical acceptance of structurally-equal but distinct structs. The two previously failing accessor tests now pass (verified: accessor + both equality suites, 88 passed).
  • No other authored delta — the branch was squashed/force-pushed, but the full diff still contains just the schema-equality API, call-site migrations, and test reorganization.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/core/slot/accessor.ts
@iwoplaza
iwoplaza force-pushed the feat/schemas-equal-structurally-nominally branch from ea51187 to 0cd0729 Compare October 19, 2026 12:38

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No new issues — the delta is a behavior-neutral clarity fix that addresses prior feedback.

Reviewed changes

Re-reviewed the delta since the prior pullfrog review (ea51187 → 0cd0729), which touches only packages/typegpu/src/data/schemasEqual.ts.

  • Explicit nominal struct return — the !structural struct branch now returns false instead of a === b. Identity is already handled by the a === b early return at the top of schemasEqual, so the two are equivalent; the change makes the intent explicit and the inline comment was reworded to read correctly.
  • JSDoc reflow — the @param/@returns block in the schemasEqualNominally doc comment was repositioned.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

This branch has not been deployed

No deployments
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.

2 participants