Add node registry primitives (PR 0.1 of node-registry plan)

Introduces the @pascal-app/core/registry surface that future node-bundle
packages (and external plugins) will use to register node kinds with the
host. No runtime behavior changes — registry is empty until subsequent
PRs populate it.

- types.ts: NodeDefinition, Capabilities, Relations, DragAction, Plugin,
  ParametricDescriptor, Affordance, SceneApi, NodeRegistry. Capability
  configs accept an override escape hatch; additive-only after v1.
- registry.ts: nodeRegistry singleton, registerNode, async loadPlugin.
  Validates kind, schemaVersion, apiVersion; rejects duplicate kinds.
- scene-api.ts: createSceneApi factory wrapping the scene store with
  copy-on-write snapshot semantics for pauseHistory/restore/resumeHistory.
- index.ts: barrel re-exporting the public surface.
- core/index.ts + package.json: export * from registry and add the
  ./registry subpath so consumers can import either way.

Tests (27 cases, all bun:test): registry registration / validation /
plugin loading; SceneApi read/write/dirty/history; lazy snapshot capture
with update/upsert/delete reversal via restore and restoreAll.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Wassim SAMAD
2026-05-14 11:18:29 -04:00
co-authored by Claude Opus 4.7
parent c50a4df8e1
commit fb91713374
8 changed files with 784 additions and 3 deletions
+4 -3
View File
@@ -44,10 +44,10 @@ export {
} from './lib/door-operation'
export { getRenderableSlabPolygon } from './lib/slab-polygon'
export {
type AutoSlabSyncPlan,
detectSpacesForLevel,
initSpaceDetectionSync,
planAutoSlabsForLevel,
type AutoSlabSyncPlan,
type Space,
wallTouchesOthers,
} from './lib/space-detection'
@@ -63,6 +63,7 @@ export {
type MaterialCategory,
toLibraryMaterialRef,
} from './material-library'
export * from './registry'
export * from './schema'
export {
getSceneHistoryPauseDepth,
@@ -89,6 +90,7 @@ export { default as useLiveTransforms, type LiveTransform } from './store/use-li
export { clearSceneHistory, default as useScene } from './store/use-scene'
export { resolveElevatorDispatchTarget } from './systems/elevator/elevator-dispatch'
export {
type ElevatorDoorSide,
getElevatorCabCenterZ,
getElevatorCabDepth,
getElevatorCabWidth,
@@ -101,7 +103,6 @@ export {
getResolvedElevatorDoorPanelStyle,
getResolvedElevatorDoorStyle,
getResolvedElevatorShaftStyle,
type ElevatorDoorSide,
} from './systems/elevator/elevator-geometry'
export { syncAutoElevatorOpenings } from './systems/elevator/elevator-opening-sync'
export { ElevatorOpeningSystem } from './systems/elevator/elevator-opening-system'
@@ -157,8 +158,8 @@ export {
constrainWallMoveDeltaToAxis,
getPerpendicularWallMoveAxis,
planWallMoveJunctions,
type WallMoveBridgePlan,
type WallMoveAxis,
type WallMoveBridgePlan,
type WallMoveJunctionPlan,
type WallPlanPoint,
} from './systems/wall/wall-move'