diff --git a/packages/nodes/package.json b/packages/nodes/package.json new file mode 100644 index 00000000..a485a275 --- /dev/null +++ b/packages/nodes/package.json @@ -0,0 +1,54 @@ +{ + "name": "@pascal-app/nodes", + "version": "0.1.0", + "description": "Built-in node bundles for the Pascal 3D editor — one folder per kind, exported as `builtinPlugin`", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "files": [ + "dist", + "README.md" + ], + "scripts": { + "build": "tsc --build", + "dev": "tsc --build --watch", + "test": "bun test", + "prepublishOnly": "bun run build && bun test" + }, + "peerDependencies": { + "@pascal-app/core": "^0.8.0", + "@react-three/drei": "^10", + "@react-three/fiber": "^9", + "react": "^18 || ^19", + "three": "^0.184" + }, + "devDependencies": { + "@pascal-app/core": "^0.8.0", + "@pascal/typescript-config": "*", + "@types/bun": "^1.3.0", + "@types/react": "^19.2.2", + "@types/three": "^0.184.0", + "typescript": "6.0.2" + }, + "keywords": [ + "pascal", + "3d", + "editor", + "node-registry" + ], + "repository": { + "type": "git", + "url": "https://github.com/pascalorg/editor.git", + "directory": "packages/nodes" + }, + "license": "MIT", + "homepage": "https://github.com/pascalorg/editor/tree/main/packages/nodes#readme", + "bugs": "https://github.com/pascalorg/editor/issues" +} diff --git a/packages/nodes/src/index.test.ts b/packages/nodes/src/index.test.ts new file mode 100644 index 00000000..f358a5a5 --- /dev/null +++ b/packages/nodes/src/index.test.ts @@ -0,0 +1,20 @@ +import { beforeEach, describe, expect, test } from 'bun:test' +import { loadPlugin, nodeRegistry } from '@pascal-app/core' +import { builtinPlugin } from './index' + +describe('builtinPlugin', () => { + beforeEach(() => { + nodeRegistry._reset() + }) + + test('has the expected manifest shape', () => { + expect(builtinPlugin.id).toBe('pascal:core') + expect(builtinPlugin.apiVersion).toBe(1) + expect(Array.isArray(builtinPlugin.nodes)).toBe(true) + }) + + test('loads with zero kinds today (Phase 0 — registry empty)', async () => { + await loadPlugin(builtinPlugin) + expect(nodeRegistry.size).toBe(0) + }) +}) diff --git a/packages/nodes/src/index.ts b/packages/nodes/src/index.ts new file mode 100644 index 00000000..3539615b --- /dev/null +++ b/packages/nodes/src/index.ts @@ -0,0 +1,18 @@ +import type { Plugin } from '@pascal-app/core' + +/** + * Built-in plugin bundling every node kind shipped with the Pascal editor. + * + * Apps load this once at bootstrap (`loadPlugin(builtinPlugin)`) before + * mounting the viewer. New built-in nodes are added by creating a folder + * here under `src//` and appending its `NodeDefinition` to `nodes`. + * + * External plugins follow the exact same shape — same `Plugin` type, same + * `loadPlugin` call path. This is intentional: the API is stress-tested + * by built-ins before any third-party plugin lands. + */ +export const builtinPlugin: Plugin = { + id: 'pascal:core', + apiVersion: 1, + nodes: [], +} diff --git a/packages/nodes/tsconfig.json b/packages/nodes/tsconfig.json new file mode 100644 index 00000000..523aa369 --- /dev/null +++ b/packages/nodes/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "@pascal/typescript-config/base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "noEmit": false, + "composite": true, + "incremental": true, + "jsx": "react-jsx", + "lib": ["DOM", "ES2022"] + }, + "include": ["src"], + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"], + "references": [{ "path": "../core" }] +}