Skip to content

Add FileResolver and PkgResolver implementations for Go#10

Merged
rjrodger merged 3 commits into
mainfrom
claude/youthful-bardeen-kdfw7s
Jun 8, 2026
Merged

Add FileResolver and PkgResolver implementations for Go#10
rjrodger merged 3 commits into
mainfrom
claude/youthful-bardeen-kdfw7s

Conversation

@rjrodger

@rjrodger rjrodger commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds two new resolver implementations to the Go port of @jsonic/multisource: MakeFileResolver for loading sources from the filesystem and MakePkgResolver for resolving references from node_modules directories. These mirror the canonical TypeScript implementations and complete the resolver API parity between the two language ports.

Key Changes

  • Added MakeFileResolver (go/resolver.go):

    • Resolves references to absolute filesystem paths
    • Supports implicit file extensions (e.g., @aa.jsonic)
    • Supports index files (e.g., @modmod/index.jsonic)
    • Supports folder-specific index files (e.g., foo/index.foo.jsonic)
    • Includes FileResolverOptions for custom path transformation (PathFinder) and preloaded content (Preload)
  • Added MakePkgResolver (go/resolver.go):

    • Resolves references inside node_modules directories
    • Walks up the directory tree from specified paths (or current working directory)
    • Honours package.json "main" field for bare package references
    • Supports implicit extensions and index files
    • Includes PkgResolverOptions to specify search root paths
  • Comprehensive test coverage (go/resolver_test.go):

    • 13 new tests covering file resolution with explicit/implicit extensions, index files, preloading, path transformation, and error cases
    • 6 new tests covering package resolution with subpaths, package.json main, index files, ancestor directory walking, and error cases
  • Updated documentation (doc/multisource-go.md):

    • Added how-to guides for both resolvers with usage examples
    • Updated API reference with FileResolverOptions and PkgResolverOptions signatures
    • Clarified that MakePkgResolver implements the portable subset of Node's module resolution
  • Updated CLAUDE.md:

    • Added guidance document for repository maintenance
    • Documented the TypeScript-as-canonical principle
    • Listed known Go ↔ TS differences and resolver/processor parity table
  • Minor updates:

    • Enhanced buildPotentials in go/multisource.go with folder-specific index file support
    • Updated version constant to 0.1.4
    • Updated test assertions to verify new index file variants

Implementation Details

  • Both resolvers follow the TypeScript semantics closely while adapting to Go idioms (e.g., variadic options instead of optional parameters)
  • MakePkgResolver is a portable subset: it does not implement Node's full require.resolve algorithm (e.g., conditional "exports")
  • File resolution uses the OS filesystem directly (no virtual filesystem abstraction like the TS version's ctx.meta.fs)
  • Search paths are tracked in Resolution.Search for debugging/transparency

https://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv

claude added 2 commits June 8, 2026 17:49
Dependencies (all otherwise already at latest):
- npm: bump memfs 4.57.2 -> 4.57.6
- go: confirmed jsonic/directive/path go modules at latest (no change)

Resolver parity (TS is canonical and ships resolver/{mem,file,pkg};
the Go port previously shipped only MakeMemResolver):
- Add MakeFileResolver (filesystem) with FileResolverOptions
  (PathFinder, Preload), mirroring src/resolver/file.ts
- Add MakePkgResolver (node_modules) with PkgResolverOptions (Paths),
  the portable subset of src/resolver/pkg.ts: walks node_modules,
  honours package.json "main", tries implicit extensions/index files
- buildPotentials now also tries the folder-name index variant
  (foo/index.foo.jsonic), matching the TS resolver
- 12 new Go resolver tests (go/resolver_test.go)

Docs:
- CLAUDE.md: note TS is canonical, build/test commands, resolver/
  processor parity map, and known Go<->TS differences
- doc/multisource-go.md: document file/pkg resolvers; fix stale Version

Tests: TS 32/32 pass, Go 29/29 pass; gofmt and go vet clean.

https://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b630b7345

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread go/resolver.go
func resolveInPkgDir(nodeModules, ref string, exts []string, search *[]string) (full, src string, found bool) {
target := filepath.Join(nodeModules, filepath.FromSlash(ref))

for _, p := range buildPotentials(target, exts) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor package.json main before index files

For a bare package that contains both package.json with a main field and an index.jsonic, this loop tries target/index.* before the code below ever reads package.json, so MakePkgResolver returns the index file and ignores the declared main entry. That contradicts the documented/canonical package resolution where package.json main wins for bare package references, and it will load the wrong source for packages that keep an index alongside their real main file.

Useful? React with 👍 / 👎.

TestFileResolverFolderIndex failed on Windows: the file resolver
resolves to an absolute path via filepath.Abs, which uses backslash
separators on Windows. buildPotentials extracted the folder name with
path.Base, but the `path` package only splits on '/', so on Windows it
returned the entire path instead of the final segment, corrupting the
foo/index.foo.jsonic potential.

Extract the final path segment with strings.LastIndexAny over both '/'
and '\\', and take the extension from that segment. This also fixes a
latent bug where a '.' in a Windows ancestor directory could wrongly
suppress implicit extensions. The plain index and implicit-extension
variants already worked because Windows tolerates mixed separators in
os.ReadFile.

Add a backslash-path assertion to TestBuildPotentials so the regression
is covered on every platform, not just Windows.

https://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv
@rjrodger rjrodger merged commit 4e04f34 into main Jun 8, 2026
8 checks passed
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