Skip to content

feat!: adopt plugin API v2 - #2

Closed
thecuriographer wants to merge 1 commit into
pascalorg:mainfrom
thecuriographer:feat/plugin-api-v2
Closed

feat!: adopt plugin API v2#2
thecuriographer wants to merge 1 commit into
pascalorg:mainfrom
thecuriographer:feat/plugin-api-v2

Conversation

@thecuriographer

Copy link
Copy Markdown

Adopts the three-manifest plugin contract (apiVersion: 2) that Pascal is
introducing, replacing the single NodeDefinition per kind.

What changes

Each of the three kinds now exports its parts separately:

Manifest Owns
treesCoreManifest schema, schemaVersion, defaults, semantic capabilities, relations
treesViewerManifest geometry, renderers, instanced systems, bake policy
treesEditorManifest parametrics, placement tools, plan symbols, palette entries

treesPlugin is gone; a host loads the three manifests with
loadCoreManifest, loadViewerManifest and loadEditorManifest. Core
registers the kind; the presentation manifests attach to it by kind and are
rejected if no base definition exists.

Why

NodeDefinition transitively named React and Three.js types, which is what
forced @pascal-app/core to re-export renderer types it does not own. With
those types gone from the contract, a plugin imports each concept from its
actual owner — sceneRegistry and useRegistry from @pascal-app/viewer,
GridEvent and ParametricDescriptor from @pascal-app/editor. That is not a
new dependency: this package already peer-depends on all three.

The split here is authored rather than derived. index.test.ts asserts it in
both directions — no semantic field (schema, defaults, capabilities, …)
appears in a presentation manifest, and no presentation field (renderer,
system, parametrics, floorplan, …) appears in a base definition — so a
field added to the wrong half fails the suite rather than silently working.

Compatibility

Breaking: needs a host on plugin API v2. Peer ranges move to >=1.0.0-beta.4.
Nothing in the authored scene format changes — schemas, schemaVersion and
node types are untouched, so existing scenes containing trees:tree,
trees:flower and trees:grass load unchanged.

Verification

bun test (17 tests) and tsc --noEmit both pass against Pascal's
plugin-api-v2 branch, with no type assertions anywhere in the manifests —
that last part was the acceptance bar for the contract itself, and it caught a
real flaw in the first draft of v2 (the manifest element types fixed the schema
generic, forcing a cast per kind; Pascal now erases it).

Splits each kind's single `NodeDefinition` into the three manifests v2
defines, so every concept is imported from the package that owns it:

- `treesCoreManifest` — schema, defaults, semantic capabilities, relations
- `treesViewerManifest` — geometry, renderers, instanced systems
- `treesEditorManifest` — parametrics, placement tools, plan symbols

`NodeDefinition` and `AnyNodeDefinition` no longer appear anywhere in this
package. That is the point of the change: those types transitively named
React and Three.js, which forced `@pascal-app/core` to re-export renderer
types it does not own. Reaching for `sceneRegistry`, `useRegistry` and
`GridEvent` from `@pascal-app/viewer` and `@pascal-app/editor` instead of
core adds no dependency — this package already peer-depends on all three.

The split is authored, not derived. Each definition file exports its three
parts separately, and `index.test.ts` asserts in both directions that no
semantic field appears in a presentation manifest and no presentation
field appears in a base definition.

BREAKING CHANGE: requires a host on plugin API v2. Peer ranges move to
>=1.0.0-beta.4; `treesPlugin` is replaced by the three manifests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant