feat: add synchronous dereferenceSync and bundleSync methods#425
Open
vanhumbeecka wants to merge 1 commit into
Open
feat: add synchronous dereferenceSync and bundleSync methods#425vanhumbeecka wants to merge 1 commit into
vanhumbeecka wants to merge 1 commit into
Conversation
Adds a synchronous API for schema objects whose $ref pointers can all be resolved in memory. dereferenceSync() and bundleSync() accept a schema object (not a file path or URL) and reuse the existing, already-synchronous dereference/bundle engine, so behavior is identical to the async methods. External references that would require I/O throw a JSONParserError up front, with a message pointing to the asynchronous API. References to embedded schema resources (compound documents with their own $id) remain fully supported. Since no I/O is performed, both methods work identically in Node.js and browsers. Closes the long-standing request in APIDevTools#82 / APIDevTools#14. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vanhumbeecka
marked this pull request as ready for review
July 22, 2026 07:19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR is AI-generated — it was written by Claude (model: Fable 5, Anthropic) via Claude Code, under the direction and review of @vanhumbeecka.
Summary
Adds a synchronous API for the common case where the schema is already a JavaScript object and all of its
$refpointers can be resolved in memory:dereferenceSync(schema, [options])bundleSync(schema, [options])Both are available as instance methods, static methods, and named exports, mirroring the async API.
Usage
Compound documents (embedded schema resources with their own
$id) work, including external-looking refs that resolve in memory:References that would require I/O fail fast with a clear error:
Motivation
A synchronous API has been requested since 2015 (#14, 34 comments; #82 closed as its duplicate). #14 was closed pointing to json-schema-reader as the successor with a planned sync option, but that project stalled. Meanwhile users resort to the workaround from that thread — importing
lib/dereferencedirectly and hand-building the$refsmap — or to event-loop-blocking wrappers that don't work in browsers.The core engine (
lib/dereference.ts,lib/bundle.ts, and all pointer/ref logic) is already fully synchronous; only the public API plumbing and the resolver I/O are async. When a schema object with only in-memory-resolvable refs is passed, the async path never touches a resolver — so a sync API requires no changes to the engine at all.Scope and design
Strictly limited to in-memory schemas — deliberately. This PR does not add sync file reading or any sync resolver plumbing; that boundary is what kept previous attempts from converging.
Errorpointing to the async API.$refs that would require I/O throw aJSONParserErrorup front. The check (assertNoUnresolvedExternalRefsinlib/resolve-external.ts) mirrors the$id-scope resolution rules of the async crawler, so compound documents — external-looking refs into embedded schema resources with their own$id— work fully.dereference.ts,bundle.ts, or any pointer/ref logic. No new dependencies. The async path is untouched.Testing
test/specs/sync/sync.spec.ts(14 tests, written test-first): internal refs with reference equality, circular refs +$refs.circularflag, compound documents, sync/async output-parity tests for both methods, and both error guards.tsc --noEmitandeslint libclean.Docs
docs/ref-parser.md; feature bullet + example inREADME.md.Closes #14
Closes #82
🤖 Generated with Claude Code