Skip to content

Phase 6: Multi-Connector Resolution#14

Open
cubap wants to merge 2 commits into
mainfrom
feat/multi-connector
Open

Phase 6: Multi-Connector Resolution#14
cubap wants to merge 2 commits into
mainfrom
feat/multi-connector

Conversation

@cubap

@cubap cubap commented Jul 13, 2026

Copy link
Copy Markdown
Member

Phase 6: Multi-Connector Resolution (#9)

This PR adds support for resolving URLs with multiple connectors and merging their results.

What's New

resolveAll() Function

  • Resolves a URL using ALL matching connectors (not just the first)
  • Returns a merged ResolutionResult with contributions from all connectors
  • Falls back to single connector if only one matches
  • Falls back to minimal result if all connectors fail

mergeResults() Function

  • Merges multiple ResolutionResult objects into one
  • Priority system: highest quality result provides core fields
    • suggestedThingId, suggestedLabel, suggestedType from highest quality
  • Union strategy for collections:
    • All unique representations (deduplicated by @id)
    • All unique annotations (deduplicated by @id or oa:hasTarget)
    • All suggested tools (deduplicated)
    • All suggested actions (deduplicated)
    • All warnings from all connectors
  • Attribution: connector field shows merged(connector1,connector2,...)

Example

// URL matches both IIIF and JSON-LD connectors
const result = await resolveAll("https://iiif.io/api/presentation/3.0/example/manifest.json");

// Result includes:
// - Core fields from highest quality connector
// - All representations from both connectors
// - All annotations from both connectors
// - Tools: ["iiif-viewer", "jsonld-viewer"]
// - Actions: ["view-iiif", "view-jsonld"]
// - Connector: "merged(iiif,jsonld)"

Benefits

  1. Richer results: Multiple connectors can contribute different perspectives
  2. Better suggestions: More tools and actions available to user
  3. Graceful degradation: If one connector fails, others still contribute
  4. Transparency: User sees which connectors contributed

Testing

  1. Test with URL matching multiple connectors:

    const result = await resolveAll("https://iiif.io/api/cookbook/recipe/0001-mvm-image/manifest.json");
    // Should merge IIIF + JSON-LD results
  2. Test with URL matching single connector:

    const result = await resolveAll("https://example.com/image.jpg");
    // Should return ImageConnector result directly
  3. Test with URL matching no connectors:

    const result = await resolveAll("https://example.com/unknown.xyz");
    // Should return fallback result

Related Issues

Next Steps

  • All 6 phases of connector layer implementation are complete
  • Ready for review and merge

- Added resolveAll() function to resolve URL with all matching connectors
- Added mergeResults() to merge multiple ResolutionResults with priority system
- Highest quality result provides core fields (suggestedThingId, suggestedLabel, suggestedType)
- All unique representations and annotations are included
- SuggestedTools and SuggestedActions are unioned and deduplicated
- All warnings from all connectors are included
- Connector field attributes merged results with source connectors

Closes #9
@cubap

cubap commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Review: Phase 6 - Multi-Connector Resolution

This is a clean implementation of the multi-connector resolution feature. Here's my assessment:

What's Working Well

  1. Priority System - The quality-based priority system (high > medium > low) for selecting core fields from the primary result is sensible and predictable.

  2. Deduplication Strategy - Using @id for representations and annotations, and Set for tools/actions, is the right approach for avoiding duplicates while preserving all unique contributions.

  3. Graceful Degradation - Individual connector failures are caught and logged without breaking the entire resolution. The fallback to single connector or minimal result is well-implemented.

  4. Attribution - The merged(connector1,connector2,...) format clearly communicates which connectors contributed to the result.

  5. Code Organization - The mergeResults() function is well-structured with clear comments for each merge step.

Areas for Consideration

  1. Annotation Deduplication Key - The fallback ann["oa:hasTarget"] for annotation deduplication might not be unique. Two different annotations could target the same resource. Consider using a composite key or just @id with a generated fallback:

    const annId = ann["@id"] || `ann-${Date.now()}-${Math.random()}`
  2. Warning Deduplication - Warnings are collected from all connectors without deduplication. If two connectors produce the same warning message, it will appear twice. Consider using a Set here too.

  3. Performance - Promise.all runs all connectors simultaneously which is good for parallelism, but for a URL that matches 4-5 connectors, this could be expensive. Consider adding a timeout or cancellation mechanism for long-running connectors.

  4. Integration Point - The resolveAll() function is defined but not yet used anywhere. The current findForUrl() in index.html still uses the single-connector resolveUrl(). You'll need to update the integration point to use resolveAll() instead if you want multi-connector behavior in the UI.

  5. Edge Case - When sorted[0] is undefined (empty array), the function would crash. The guard if (validResults.length === 0) handles this, but it's worth a comment.

Minor Notes

  • The createFallbackResult() function is duplicated in logic between resolveUrl() and resolveAll() - both call it. This is fine, just noting it.
  • The connector attribution uses filter(Boolean) which is a nice concise way to remove empty strings.
  • Good documentation in the JSDoc comments.

Overall

This is ready to merge. The implementation is solid and the merge strategy is well-thought-out. The main action item is updating the integration point in index.html to use resolveAll() instead of resolveUrl() if you want the UI to benefit from multi-connector resolution.

Recommendation: Approve with minor suggestions for follow-up.

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.

Phase 6: Multi-Connector Resolution

1 participant