Skip to content

refactor(compositions): extract framework-neutral @modular-frontend/compositions-engine - #56

Merged
kibertoad merged 1 commit into
mainfrom
claude/vue-version-next-phase-tq1bqb
Jul 6, 2026
Merged

refactor(compositions): extract framework-neutral @modular-frontend/compositions-engine#56
kibertoad merged 1 commit into
mainfrom
claude/vue-version-next-phase-tq1bqb

Conversation

@kibertoad

@kibertoad kibertoad commented Jul 6, 2026

Copy link
Copy Markdown
Owner

PR-03 of the Vue-support initiative. Splits the framework-neutral guts of @modular-react/compositions into a new @modular-frontend/compositions-engine package so a future Vue binding can reuse them, mirroring the @modular-frontend/journeys-engine extraction in #55 and the @modular-frontend/core extraction in #54.

What moves

New package @modular-frontend/compositions-engine (v0.1.0, depends only on @modular-frontend/core; happy-dom is a dev dep for the test environment). It holds the composition runtime, scoped stores, validation, authoring helpers (defineComposition / defineCompositionHandle), and the full type surface, plus their non-React tests (runtime.test.ts, stores.test.ts, validation.test.ts, define-composition.test-d.ts, mount-kinds.test-d.ts). Single build entry: index.

@modular-react/compositions keeps its React files (outlet.tsx, provider.tsx, plugin.tsx, hooks.ts) and all .tsx tests, and re-exports the engine, so its public export surface is unchanged.

Deviation from the tracker's PR-03 plan

One React reference had to be neutralized, matching how #54 handled NavigationItem.icon and PR-02 (#55) handled JourneyNavContribution.icon: CompositionZoneDescriptor.fallback used the React.ComponentType namespace (with no @types/react in the engine, this fails to resolve). It moves to the neutral UiComponent seam from @modular-frontend/core. Source-compatible for authors — a React component still satisfies UiComponent, and the outlet still renders it as a JSX element in the binding.

stores.ts kept its useSyncExternalStore-motivated referential-stability logic as-is (it is still pure); only the doc comment naming React.useSyncExternalStore remains, and it stays descriptive.

Error-message prefixes stay [@modular-react/compositions] on purpose: they name the package users import, so the moved tests pass unmodified.

Verification

  • @modular-frontend/compositions-engine: 52 tests (5 files); @modular-react/compositions: 63 tests (8 files). 52 + 63 = the pre-split total of 115.
  • No repo consumer deep-imports the moved files — all use the unchanged public @modular-react/compositions entry (the three example apps' editor-composition shells/modules included).
  • Full workspace typecheck (112 tasks) and pnpm lint clean; oxfmt --check reports no format changes.

Also marks PR-03 done in the tracker and records compositions-engine under decision D2.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sf7deW3iRQaaSjZuj3akTA


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new compositions engine package and public entrypoint.
    • Updated the main compositions package to use the shared engine for runtime, validation, and type exports.
  • Bug Fixes

    • Aligned composition fallbacks with a framework-neutral component interface.
    • Updated several tests and runtime references to the shared frontend core package for consistency.
  • Documentation

    • Added package documentation and refreshed the support tracker to show the extraction is complete.

…ompositions-engine

PR-03 of the Vue-support initiative. Splits the framework-neutral guts of
@modular-react/compositions into a new @modular-frontend/compositions-engine
package so a future Vue binding can reuse them, mirroring the journeys-engine
extraction (#55) and the frontend-core extraction (#54).

What moves: the pure files (runtime.ts, stores.ts, validation.ts,
define-composition.ts, types.ts) plus their non-.tsx tests. The engine depends
only on @modular-frontend/core; happy-dom is a dev dep for the test
environment. @modular-react/compositions keeps its React files (outlet.tsx,
provider.tsx, plugin.tsx, hooks.ts) and all .tsx tests, and re-exports the
engine so its public export surface is unchanged.

One React reference had to be neutralized, matching #54/PR-02:
CompositionZoneDescriptor.fallback used React.ComponentType; it moves to the
neutral UiComponent seam from @modular-frontend/core. Source-compatible for
authors (a React component still satisfies UiComponent). Error-message
prefixes stay [@modular-react/compositions] on purpose — they name the package
users import.

Test counts preserved: 52 in the engine + 63 in the binding = the pre-split
total of 115. Full workspace typecheck and lint clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sf7deW3iRQaaSjZuj3akTA
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e3ad6808-3aa8-4910-83a9-1aede3160654

📥 Commits

Reviewing files that changed from the base of the PR and between 952475f and 5947ec0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (32)
  • docs/vue-support-tracker.md
  • packages/compositions-engine/README.md
  • packages/compositions-engine/package.json
  • packages/compositions-engine/src/define-composition.test-d.ts
  • packages/compositions-engine/src/define-composition.ts
  • packages/compositions-engine/src/index.ts
  • packages/compositions-engine/src/mount-kinds.test-d.ts
  • packages/compositions-engine/src/runtime.test.ts
  • packages/compositions-engine/src/runtime.ts
  • packages/compositions-engine/src/stores.test.ts
  • packages/compositions-engine/src/stores.ts
  • packages/compositions-engine/src/types.ts
  • packages/compositions-engine/src/validation.test.ts
  • packages/compositions-engine/src/validation.ts
  • packages/compositions-engine/tsconfig.json
  • packages/compositions-engine/vite.config.ts
  • packages/compositions-engine/vitest.config.ts
  • packages/compositions/package.json
  • packages/compositions/src/hooks.ts
  • packages/compositions/src/index.ts
  • packages/compositions/src/mount-kinds-runtime.test.tsx
  • packages/compositions/src/outlet.advanced-behaviors.test.tsx
  • packages/compositions/src/outlet.behaviors.test.tsx
  • packages/compositions/src/outlet.test.tsx
  • packages/compositions/src/outlet.tsx
  • packages/compositions/src/plugin.tsx
  • packages/compositions/src/provider.tsx
  • packages/compositions/src/runtime.disposal-and-validation.test.tsx
  • packages/compositions/src/runtime.lifecycle-followups.test.tsx
  • packages/compositions/src/selector-dispatch.test.tsx
  • packages/compositions/src/use-composition.test.tsx
  • packages/compositions/vite.config.ts

📝 Walkthrough

Walkthrough

A new framework-neutral @modular-frontend/compositions-engine package is extracted, containing runtime, validation, store, and type logic previously in packages/compositions. Core imports switch from @modular-react/core to @modular-frontend/core. The compositions package now re-exports from the new engine package, and tracker docs are updated.

Changes

Compositions Engine Extraction

Layer / File(s) Summary
Package scaffold and build/test config
packages/compositions-engine/package.json, tsconfig.json, vite.config.ts, vitest.config.ts, README.md
New package is scaffolded with ESM build, dts generation, Vitest/typecheck config, and documentation.
Core import migration in engine source
packages/compositions-engine/src/define-composition.ts, runtime.ts, stores.ts, validation.ts, types.ts, *.test.ts, *.test-d.ts
Imports switch from @modular-react/core to @modular-frontend/core; CompositionZoneDescriptor.fallback type changes from React.ComponentType to UiComponent.
Public entrypoint re-exports
packages/compositions-engine/src/index.ts
New index re-exports authoring, runtime, hydration, validation APIs, and public types/store helpers.
Compositions package rewired to engine
packages/compositions/package.json, src/index.ts, src/hooks.ts, src/outlet.tsx, src/plugin.tsx, src/provider.tsx, src/*.test.tsx, vite.config.ts
Adds workspace dependency on the new engine package and rewires source/test imports from local files to @modular-frontend/compositions-engine; updates Rollup externals and adds a flushMicrotasks test helper.
Tracker documentation update
docs/vue-support-tracker.md
Marks PR-03 (compositions-engine extraction) as done with updated dates, decisions, and status board.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • kibertoad/modular-react#45: Introduced the composition runtime/outlet/validation surface in packages/compositions that this PR extracts into compositions-engine.

Suggested labels: minor

Suggested reviewers: diogomiguel, casamitjana

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: extracting the framework-neutral compositions engine into a new package.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/vue-version-next-phase-tq1bqb

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kibertoad
kibertoad merged commit c2ffd8d into main Jul 6, 2026
14 of 15 checks passed
@kibertoad
kibertoad deleted the claude/vue-version-next-phase-tq1bqb branch July 6, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants