feat: add project plugin management (#501)

This commit is contained in:
Wassim SAMAD
2026-07-16 10:26:59 -04:00
committed by GitHub
parent 4f0aa7f7b6
commit 9ca3eaa7fe
88 changed files with 684 additions and 3100 deletions
@@ -1,6 +1,12 @@
'use client'
import { type AnyNode, nodeRegistry, type RendererSource, useScene } from '@pascal-app/core'
import {
type AnyNode,
isNodeKindEnabled,
nodeRegistry,
type RendererSource,
useScene,
} from '@pascal-app/core'
import { type ComponentType, lazy, Suspense } from 'react'
import { ParametricNodeRenderer } from './parametric-node-renderer'
@@ -23,7 +29,9 @@ export function getRegistryRenderer(
export const NodeRenderer = ({ nodeId }: { nodeId: AnyNode['id'] }) => {
const node = useScene((state) => state.nodes[nodeId])
const installedPlugins = useScene((state) => state.installedPlugins)
if (!node) return null
if (!isNodeKindEnabled(node.type, installedPlugins)) return null
const def = nodeRegistry.get(node.type)
if (!def) return null
// Two-checkbox dispatch (see wiki/architecture/node-definitions.md):
@@ -3,6 +3,7 @@
import {
type AnyNode,
bakePolicyOf,
isNodeKindEnabled,
nodeRegistry,
type RendererSource,
type SceneGraph,
@@ -30,6 +31,7 @@ export function buildGlbReferenceNodes(
const out: AnyNode[] = []
for (const raw of Object.values(nodes)) {
const node = raw as AnyNode
if (!isNodeKindEnabled(node.type, sceneGraph?.installedPlugins)) continue
if (bakePolicyOf(node.type) !== 'strip') continue
if (node.type === 'scan' && !allow.scans) continue
if (node.type === 'guide' && !allow.guides) continue
@@ -52,6 +54,7 @@ export function buildGlbReplaceNodes(sceneGraph: SceneGraph | null | undefined):
const out: AnyNode[] = []
for (const raw of Object.values(nodes)) {
const node = raw as AnyNode
if (!isNodeKindEnabled(node.type, sceneGraph?.installedPlugins)) continue
if (bakePolicyOf(node.type) === 'replace') out.push(node)
}
return out
@@ -1,6 +1,12 @@
'use client'
import { type AnyNodeDefinition, createSceneApi, nodeRegistry, useScene } from '@pascal-app/core'
import {
type AnyNodeDefinition,
createSceneApi,
isNodeKindEnabled,
nodeRegistry,
useScene,
} from '@pascal-app/core'
import { type ComponentType, lazy, Suspense, useMemo } from 'react'
const DEFAULT_PRIORITY = 5
@@ -34,6 +40,7 @@ function loadSystem(def: AnyNodeDefinition): ComponentType<RegisteredSystemProps
*/
export function RegisteredSystems() {
const sceneApi = useMemo(() => createSceneApi(useScene), [])
const installedPlugins = useScene((state) => state.installedPlugins)
const entries = useMemo(() => {
return Array.from(nodeRegistry.entries())
.filter(([, def]) => def.system != null)
@@ -49,6 +56,7 @@ export function RegisteredSystems() {
return (
<Suspense fallback={null}>
{entries.map(([kind, def]) => {
if (!isNodeKindEnabled(kind, installedPlugins)) return null
const Comp = loadSystem(def)
if (!Comp) return null
return <Comp key={`registered-system:${kind}`} sceneApi={sceneApi} />