feat(vue): add @modular-vue/journeys provider, composables, plugin (PR-30) - #69
Conversation
…R-30) Start Phase 3 of the Vue port with the journeys binding layer: a new `@modular-vue/journeys` (0.1.0) package over `@modular-frontend/journeys-engine`, mirroring `@modular-react/journeys`. - provider.ts: `JourneyProvider` (defineComponent + render fn) provides the journey runtime and composes over `<ModuleExitProvider>`; `useJourneyContext`. - instance-hooks.ts: `useInstanceSnapshot` (watchEffect bridge, the Vue analog of `useSyncExternalStore`), `useCallChain` (hand-managed activeChild subscriptions), `useLeafId`. - use-journey-state.ts: `useJourneyState` / `useJourneyInstance` and the leaf-walking `useActiveLeafJourneyState` / `useActiveLeafJourneyInstance`, returning Vue refs (PR-23 reactive-source convention). - plugin.ts: `journeysPlugin()` — the concrete plugin PR-21/PR-22 deferred here; identical to the React plugin except `providers()` returns a Vue provider. Composables accept `MaybeRefOrGetter` ids so a reactive/leaf id stays reactive. 17 tests (provider, use-journey-state, plugin) pass; workspace typecheck (122 tasks) and vite build (JS + dts) pass with externals unbundled. Tracker updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgWjMcA5t8zKEHpjrZhdYT
|
Warning Review limit reached
Next review available in: 48 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds ChangesVue journeys package
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant VueComponent
participant JourneyProvider
participant useJourneyState
participant JourneyRuntime
VueComponent->>JourneyProvider: mount with runtime
JourneyProvider->>useJourneyState: provide journey context
VueComponent->>useJourneyState: request journey state
useJourneyState->>JourneyRuntime: read and subscribe to instance
JourneyRuntime-->>useJourneyState: publish instance updates
useJourneyState-->>VueComponent: update computed state
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/vue-support-tracker.md`:
- Line 333: Update the PR-30 entry in the Vue support tracker to include the
completed pull request link while preserving its existing status and dependency
references.
In `@packages/vue-journeys/src/plugin.ts`:
- Around line 98-104: Update the onModuleExit callback contract in the plugin
options to reuse the upstream ModuleExitEvent or handler type instead of
redeclaring its event shape. Preserve routeId and keep the plugin callback
synchronized with the complete upstream event contract.
In `@packages/vue-journeys/src/provider.ts`:
- Around line 63-64: Update the provider setup around journeyKey so the
context’s onModuleExit reads the current props.onModuleExit rather than
capturing the initial callback; use a stable provided object with a reactive or
getter-backed handler, while preserving the existing runtime value and
ModuleExitProvider rendering behavior.
In `@packages/vue-journeys/vite.config.ts`:
- Around line 2-5: Replace the rolldown-plugin-dts import and usage in the
package’s defineConfig build setup with the repository-standard vite-plugin-dts
implementation, preserving the existing command-based plugin selection.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2501523e-9328-4d3c-b74f-4a59fcf905e4
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
docs/vue-support-tracker.mdpackages/vue-journeys/README.mdpackages/vue-journeys/package.jsonpackages/vue-journeys/src/index.tspackages/vue-journeys/src/instance-hooks.tspackages/vue-journeys/src/plugin.test.tspackages/vue-journeys/src/plugin.tspackages/vue-journeys/src/provider.test.tspackages/vue-journeys/src/provider.tspackages/vue-journeys/src/use-journey-state.test.tspackages/vue-journeys/src/use-journey-state.tspackages/vue-journeys/tsconfig.jsonpackages/vue-journeys/vite.config.tspackages/vue-journeys/vitest.config.ts
- provider: expose `onModuleExit` on the injected context value through a getter so a swapped handler is visible to consumers that introspect `useJourneyContext().onModuleExit` (parity with the React provider, which rebuilds its value object each render). `runtime` stays a raw, un-proxied reference so identity checks against `manifest.journeys` still hold. - tests: add direct coverage for `useJourneyInstance` (full snapshot + no-provider null) instead of relying solely on transitive coverage. - tests: add `use-journey-state.test-d.ts` so the type-level coverage the vitest config already enables (`*.test-d.ts`) actually exists, asserting the composable return types and `MaybeRefOrGetter` id acceptance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P1a2CFQmnRZp25ZXAKAMEQ
- plugin: reuse the upstream `ModuleExitHandler` for the `onModuleExit` option instead of a duplicated inline event shape, so the full `ModuleExitEvent` (incl. `routeId`) stays in sync with @modular-vue/vue. - docs: link PR-30's `done` status to #69, matching the tracker's "link the PR" convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P1a2CFQmnRZp25ZXAKAMEQ
Summary
Kicks off Phase 3 of the Vue support initiative (journeys and compositions on Vue) with PR-30: the
@modular-vue/journeysbinding layer. Adds a new@modular-vue/journeys(0.1.0) package over the framework-neutral@modular-frontend/journeys-engine, mirroring@modular-react/journeys. Seedocs/vue-support-tracker.mdfor the full plan.Each new file names the React source it ports, so reviewers can diff intent:
packages/vue-journeys/src)provider.tsjourneys/provider.tsxJourneyProvider(defineComponent+ render fn per D4) provides{ runtime, onModuleExit }and composes over<ModuleExitProvider>from@modular-vue/vue;useJourneyContext/journeyKey.instance-hooks.tsjourneys/instance-hooks.tsuseInstanceSnapshot(awatchEffectbridge into ashallowRef— the Vue analog of React'suseSyncExternalStore),useCallChain(walksactiveChildId, hand-managing the per-instance subscription set),useLeafId.use-journey-state.tsjourneys/use-journey-state.tsuseJourneyState/useJourneyInstanceand the leaf-walkinguseActiveLeafJourneyState/useActiveLeafJourneyInstance.plugin.tsjourneys/plugin.tsxjourneysPlugin()—extend/validate/onResolve/contributeNavigation/providers, field-for-field with React exceptproviders()returns a Vue<JourneyProvider>.index.tsjourneys/index.tsNotable decisions / deviations (all forced by the framework)
registry-plugins.test.tssynthetic plugin) and PR-22 ("the only consumer is the journeys plugin, which lands in PR-30") both deferred the concrete journeys plugin to this PR, so it ships here. End-to-end registry wiring + outlet rendering stay with PR-32.ComputedRef/ShallowRef), matching the PR-23 reactive-source convention. Single-instance snapshots update synchronously on runtime events; leaf-walk re-subscription lands on the next tick, so the chain-walk testsawait flushPromises()before asserting.MaybeRefOrGetterso a reactive id (or the internalComputedRefleaf id) stays reactive through the composable; plain strings still work (React'sInstanceId | null).Testing
provider.test.ts(4),use-journey-state.test.ts(4),plugin.test.ts(9), portingprovider.test.tsx/use-journey-state.test.tsxintent and adding focused plugin-surface coverage.vite build(JS + dts) pass; externals (vue,@modular-frontend/core,@modular-frontend/journeys-engine,@modular-vue/vue) stay unbundled.The journey outlet,
<ModuleTab>, anduseWaitForExitfollow in PR-31; end-to-end runtime wiring +renderJourneyin PR-32.🤖 Generated with Claude Code
https://claude.ai/code/session_01MgWjMcA5t8zKEHpjrZhdYT
Generated by Claude Code
Summary by CodeRabbit