fix: reference root block objects by name at every nested position (v5 backport)#2995
fix: reference root block objects by name at every nested position (v5 backport)#2995christianhg wants to merge 1 commit into
Conversation
Backport of the same fix on `main` to the last Sanity-v5-compatible
bridge line (3.1.1; 3.1.2 and later depend on `@sanity/types` v6).
The combinatorial-blow-up fix made conversion time linear by building
shared `OfDefinition` objects, a DAG. But each named type's single
expansion still inlined the expansions of every type not on its
first-visit ancestor path, so the emitted definition was factorial in
the number of mutually-embedding types AS A TREE, which is the shape
every consumer walks: schema compilation, React reconciliation, any
clone or serialization. Studios with wide mutually recursive schemas
froze and ran out of memory on document open.
`sanityOfMemberToOfDefinition` now emits a bare `{type: name}`
reference whenever the member is one of the root block-object
instances, at every position, not just on ancestor cycles. The root
`blockObjects` entry materializes the fields exactly once. The check
is keyed by canonical instance rather than name, so an inline
declaration that merely shares a name with a root type keeps its own
inline shape. The mutually-embedding benchmark now also bounds
`JSON.stringify(schema).length`, the assertion whose absence let the
factorial output ship green.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
📦 Bundle Stats —
|
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 775.3 KB | - |
| Internal (gzip) | 148.1 KB | - |
| Bundled (raw) | 1.38 MB | - |
| Bundled (gzip) | 310.0 KB | - |
| Import time | 73ms | -2ms, -3.1% |
@portabletext/editor/behaviors
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 467 B | - |
| Internal (gzip) | 207 B | - |
| Bundled (raw) | 424 B | - |
| Bundled (gzip) | 171 B | - |
| Import time | 1ms | -0ms, -1.2% |
@portabletext/editor/plugins
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 2.7 KB | - |
| Internal (gzip) | 894 B | - |
| Bundled (raw) | 2.5 KB | - |
| Bundled (gzip) | 827 B | - |
| Import time | 5ms | -0ms, -1.0% |
@portabletext/editor/selectors
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 79.3 KB | - |
| Internal (gzip) | 14.5 KB | - |
| Bundled (raw) | 74.8 KB | - |
| Bundled (gzip) | 13.4 KB | - |
| Import time | 6ms | +0ms, +0.3% |
@portabletext/editor/traversal
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 25.4 KB | - |
| Internal (gzip) | 5.0 KB | - |
| Bundled (raw) | 25.4 KB | - |
| Bundled (gzip) | 5.0 KB | - |
| Import time | 4ms | +0ms, +1.1% |
@portabletext/editor/utils
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 28.7 KB | - |
| Internal (gzip) | 6.0 KB | - |
| Bundled (raw) | 26.7 KB | - |
| Bundled (gzip) | 5.7 KB | - |
| Import time | 4ms | +0ms, +0.1% |
🗺️ . · ./behaviors · ./plugins · ./selectors · ./traversal · ./utils · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @portabletext/markdown
Compared against bridge-v5-lts (24e2efd5)
| Metric | Value | vs bridge-v5-lts (24e2efd) |
|---|---|---|
| Internal (raw) | 53.0 KB | - |
| Internal (gzip) | 9.6 KB | - |
| Bundled (raw) | 347.6 KB | - |
| Bundled (gzip) | 96.0 KB | - |
| Import time | 29ms | -2ms, -5.5% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
Backport of #2993 to the last Sanity-v5-compatible bridge line. Bridge 3.1.2 and later depend on
@sanity/typesv6, so v5 studios top out at 3.1.1, which carries the factorial definition-tree blow-up: conversion is fast (the memoized walk builds a shared DAG), but the emitted definition inlines each type's expansion at every position not covered by an ancestor cycle, and everything downstream walks it as a tree. Wide mutually recursive schemas freeze and OOM on document open, the same failure #2976 reports against the 3.2.x line.Same fix as
main: members that are root block objects emit a bare{type: name}reference at every position, keyed by canonical instance so same-named inline declarations keep their own shape. The era's own test suite passes unchanged, and the mutually-embedding benchmark gains the output-size bound, red on the unfixed converter (the size assertion fails), green with the fix.Targets the
bridge-v5-ltsbranch (cut from the@portabletext/sanity-bridge@3.1.1tag), notmain. Publishing is a hand-publish from this branch after merge, changesets doesn't manage the old line. The version number needs a decision:3.1.7slots after the Sanity-6-only 3.1.2-3.1.6 and risks tilde-range floats mixing dependency majors, while an exact-pinned prerelease-style version (e.g.3.1.2-v5-lts.1) can never be range-matched and requires Studio v5 to pin it exactly, which is also the safer shape for Studio v5's own range (its current^3.1.0floats into the Sanity-6-only versions today).