Selection: registry-driven, drop spawn flag, restore green color
Two concerns from the spike:
1) Selection / floating-action-menu had hardcoded kind lists scattered
across 4 files. Adding 'shelf' to each one per migration was the
wrong abstraction — the user's question "did you make it generic
from the noderegistry?" was the right one. Done now.
Added to @pascal-app/core/registry:
- getSelectableKinds(): string[] — returns all registered kinds
whose definition declares `capabilities.selectable`.
- isRegistrySelectable(kind): boolean — predicate for OR-chains.
Refactored hardcoded sites to merge registry kinds at runtime,
keeping legacy hardcoded lists intact so existing kinds keep
working unchanged:
- editor SelectionManager: 4 subscription loops (enter/leave/click)
+ structure.isValid + getSelectionTarget — all augment with
registry kinds. Phase 6 deletes the hardcoded lists.
- viewer SelectionManager: subscription loop + SelectableNodeType
broadened with `(string & {})` to accept registry kinds.
- floating-action-menu: ALLOWED_TYPES OR'd with isRegistrySelectable.
- Removed the manually-added 'shelf' entries from previous commit
857ddd4; they were redundant once the registry-driven path landed.
Future built-in nodes that declare `capabilities.selectable` get
click-selection + hover + the floating action menu (move/delete
icons) for free, no editing of these 4 files.
2) Spawn parity is signed off. Drop the
NEXT_PUBLIC_USE_REGISTRY_FOR_SPAWN flag entirely; spawn registers
unconditionally in builtinPlugin.nodes. Restored SPAWN_COLOR to
the original #22c55e green (was #ef4444 red as a Phase 2
verification marker).
Pre-existing typecheck errors in editor (ceiling/fence/slab tree-node,
scene.ts buildingId) are unchanged.
630 tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
857ddd4d95
commit
6d97a87547
@@ -1,4 +1,10 @@
|
||||
export { loadPlugin, nodeRegistry, registerNode } from './registry'
|
||||
export {
|
||||
getSelectableKinds,
|
||||
isRegistrySelectable,
|
||||
loadPlugin,
|
||||
nodeRegistry,
|
||||
registerNode,
|
||||
} from './registry'
|
||||
export {
|
||||
type CascadeContext,
|
||||
type ChildQuery,
|
||||
|
||||
@@ -57,6 +57,34 @@ export function registerNode(def: AnyNodeDefinition): void {
|
||||
nodeRegistry._register(def)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of registered kinds whose definition declares the
|
||||
* `selectable` capability. Callers that maintain hardcoded "selectable kinds"
|
||||
* lists (SelectionManager, FloatingActionMenu) should concat this with their
|
||||
* legacy entries instead of editing the hardcoded list per migration.
|
||||
*
|
||||
* Phase 6 deletes the hardcoded lists entirely and uses this function as the
|
||||
* single source of truth. For now it's additive over the legacy lists so the
|
||||
* existing kinds keep working unchanged.
|
||||
*/
|
||||
export function getSelectableKinds(): string[] {
|
||||
const result: string[] = []
|
||||
for (const [kind, def] of nodeRegistry.entries()) {
|
||||
if (def.capabilities.selectable !== undefined) {
|
||||
result.push(kind)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when the kind is declared selectable in the registry. Use
|
||||
* in expression chains like `if (node.type === 'wall' || isRegistrySelectable(node.type))`.
|
||||
*/
|
||||
export function isRegistrySelectable(kind: string): boolean {
|
||||
return nodeRegistry.get(kind)?.capabilities.selectable !== undefined
|
||||
}
|
||||
|
||||
export async function loadPlugin(plugin: Plugin): Promise<void> {
|
||||
if (plugin.apiVersion !== HOST_API_VERSION) {
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user