-
Notifications
You must be signed in to change notification settings - Fork 4
feat: enhance playground functionality and update dependencies #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Added support for playground configuration in the vitepress-demo-plugin. - Updated the plugin version to 1.5.0 and included a patch for it. - Implemented a new event listener for code playground interactions in the theme. - Adjusted the markdown configuration to enable playground features.
WalkthroughThe changes integrate a code playground feature into the VitePress documentation site. Updates include enabling the playground plugin with code transformation in the config, adding an event-driven code-playground listener in the theme setup, updating dependencies to include the tiny-robot-playground package, and patching the vitepress-demo-plugin to expose new playground configuration APIs. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.vitepress/theme/index.ts:
- Around line 115-125: Guard against missing/malformed props.playground and
invalid package strings: wrap the decodeURIComponent/JSON.parse into a try/catch
and default extraPackages to [] if parsing fails or props.playground is falsy;
in the mapping for extraPackages (the map that uses lastIndexOf('@') and
produces { [pkg]: version }), validate each pkgAndVersion string, handle cases
where lastIndexOf('@') <= 0 (treat the entire string as the package name and set
version to '' or undefined) and skip empty names; finally reduce into
extraImports as before. Update the code around props.playground, extraPackages,
extraImports and the map/reduce logic to include these guards and fallbacks.
🧹 Nitpick comments (3)
.vitepress/theme/index.ts (2)
108-108: Hardcoded'latest'version tag is non-deterministic.Using
'latest'fortinyRobotVersionmeans the playground will resolve to whatever version is current at runtime, which may not match the docs site's own dependency version. Consider reading the version from the installed package or a build-time constant for reproducibility.
29-33: Mixinmountedhook runs for every component instance.
listenCodePlaygroundEvent()is called on every component mount site-wide. The guard flag (__CODE_PLAYGROUND_LISTENED__) makes it safe, but a one-time call duringenhanceApp(outside the mixin) would be cleaner and avoid the repeated no-op invocations.Suggested approach
enhanceApp({ app }) { setupDarkModeListener() + listenCodePlaygroundEvent() app.mixin({ mounted() { registerServiceWorker() - listenCodePlaygroundEvent() }, })This also applies to
registerServiceWorker()if it doesn't truly need the component lifecycle.patches/vitepress-demo-plugin@1.5.0.patch (1)
32-201: Patching compiled dist files is fragile — consider upstreaming.This patch modifies minified JS directly, which will break on any upstream release that changes the dist output (even a patch release, though pinning to
1.5.0mitigates this). If the playground feature is broadly useful, consider contributing it upstream tovitepress-demo-pluginto reduce the long-term maintenance burden of this patch.
| const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || [] | ||
| const extraImports = extraPackages | ||
| .map((pkgAndVersion) => { | ||
| const index = pkgAndVersion.lastIndexOf('@') | ||
| const pkg = pkgAndVersion.slice(0, index) | ||
| const version = pkgAndVersion.slice(index + 1) | ||
| return { [pkg]: version } | ||
| }) | ||
| .reduce((acc, curr) => { | ||
| return { ...acc, ...curr } | ||
| }, {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unguarded JSON.parse will crash the event handler if props.playground is missing or malformed.
If props.playground is undefined, empty, or not valid URI-encoded JSON, JSON.parse(decodeURIComponent(...)) throws and silently kills the handler — no playground opens, no error feedback to the user.
Additionally, the lastIndexOf('@') splitting strategy silently corrupts entries that lack a version suffix (e.g. "@scope/pkg" → pkg = "", version = "scope/pkg"; "pkg" → pkg = "pk", version = "pkg").
Proposed fix
- const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
- const extraImports = extraPackages
- .map((pkgAndVersion) => {
- const index = pkgAndVersion.lastIndexOf('@')
- const pkg = pkgAndVersion.slice(0, index)
- const version = pkgAndVersion.slice(index + 1)
- return { [pkg]: version }
- })
- .reduce((acc, curr) => {
- return { ...acc, ...curr }
- }, {})
+ let extraImports: Record<string, string> = {}
+ try {
+ const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || []
+ extraImports = Object.fromEntries(
+ extraPackages
+ .map((pkgAndVersion) => {
+ const index = pkgAndVersion.lastIndexOf('@')
+ // Ensure '@' is found and is not the first char of a scoped package with no version
+ if (index > 0) {
+ return [pkgAndVersion.slice(0, index), pkgAndVersion.slice(index + 1)]
+ }
+ return [pkgAndVersion, 'latest']
+ })
+ )
+ } catch {
+ console.warn('Failed to parse playground packages', props.playground)
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || [] | |
| const extraImports = extraPackages | |
| .map((pkgAndVersion) => { | |
| const index = pkgAndVersion.lastIndexOf('@') | |
| const pkg = pkgAndVersion.slice(0, index) | |
| const version = pkgAndVersion.slice(index + 1) | |
| return { [pkg]: version } | |
| }) | |
| .reduce((acc, curr) => { | |
| return { ...acc, ...curr } | |
| }, {}) | |
| let extraImports: Record<string, string> = {} | |
| try { | |
| const extraPackages: string[] = JSON.parse(decodeURIComponent(props.playground))?.packages || [] | |
| extraImports = Object.fromEntries( | |
| extraPackages | |
| .map((pkgAndVersion) => { | |
| const index = pkgAndVersion.lastIndexOf('@') | |
| // Ensure '@' is found and is not the first char of a scoped package with no version | |
| if (index > 0) { | |
| return [pkgAndVersion.slice(0, index), pkgAndVersion.slice(index + 1)] | |
| } | |
| return [pkgAndVersion, 'latest'] | |
| }) | |
| ) | |
| } catch { | |
| console.warn('Failed to parse playground packages', props.playground) | |
| } |
🤖 Prompt for AI Agents
In @.vitepress/theme/index.ts around lines 115 - 125, Guard against
missing/malformed props.playground and invalid package strings: wrap the
decodeURIComponent/JSON.parse into a try/catch and default extraPackages to []
if parsing fails or props.playground is falsy; in the mapping for extraPackages
(the map that uses lastIndexOf('@') and produces { [pkg]: version }), validate
each pkgAndVersion string, handle cases where lastIndexOf('@') <= 0 (treat the
entire string as the package name and set version to '' or undefined) and skip
empty names; finally reduce into extraImports as before. Update the code around
props.playground, extraPackages, extraImports and the map/reduce logic to
include these guards and fallbacks.
Summary by CodeRabbit
Release Notes
New Features
Dependencies