Skip to content

fix(speedcurve): vendor LUX snippet and group schema options#805

Open
harlan-zw wants to merge 8 commits into
mainfrom
fix/speedcurve-followups
Open

fix(speedcurve): vendor LUX snippet and group schema options#805
harlan-zw wants to merge 8 commits into
mainfrom
fix/speedcurve-followups

Conversation

@harlan-zw
Copy link
Copy Markdown
Collaborator

@harlan-zw harlan-zw commented May 27, 2026

🔗 Linked issue

Follow-up to #782 — addresses unresolved review comments.

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

Resolves the two open review items left after #782 was merged.

Snippet sourcing — opt-in registration + user-installed peer dep. SpeedCurve LUX now requires the user to register the script in scripts.registry.speedcurve and install @speedcurve/lux themselves. The Nuxt module:

  • Only emits the #build/nuxt-scripts-speedcurve-snippet virtual template when scripts.registry.speedcurve is set. Calling useScriptSpeedCurve without registering produces a clear build error from the missing virtual.
  • Resolves the LUX primer snippet from the user-installed @speedcurve/lux at build time via resolvePath + readFileSync, then emits it as a string export. No ?raw import in runtime, no vendored snippet to keep in sync, users control the snippet version.
  • If the package is registered but missing, the emitted template throws at import with an install hint (npm i -D @speedcurve/lux).

Docs gain a Setup section documenting the opt-in registration + peer dep install.

Schema clarity. SpeedCurveOptions is split with section comments — id, spaMode, autoTrackSpaNavigations are composable-only; the rest match upstream LUX UserConfig casing and are forwarded onto window.LUX. Comment points future editors to keep this in sync with LUX_USER_CONFIG_KEYS in speedcurve.ts.

Regenerated registry-types.json. All 717 unit tests pass and @nuxt/scripts builds clean.

- Inline the LUX 2.0.0 snippet as a string const in `runtime/utils/speedcurve-snippet.ts` so `@speedcurve/lux` is no longer required at user build time (still kept as an optional peer dep for types).
- Drop `@speedcurve/lux` from `build.externals`; remove obsolete `?raw` mocks from the unit tests.
- Split `SpeedCurveOptions` into composable-only options (`id`, `spaMode`, `autoTrackSpaNavigations`) and LUX `UserConfig` passthrough, with a note pointing to `LUX_USER_CONFIG_KEYS`.
- Regenerate `registry-types.json`.

Addresses unresolved review comments from #782.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview, Comment May 27, 2026 10:26am

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 27, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/scripts@805

commit: 763b10a

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors SpeedCurve snippet resolution from a direct external package import to a build-time generated virtual module. The Nuxt module now conditionally generates a virtual module #build/nuxt-scripts-speedcurve-snippet when SpeedCurve is registered, which loads and inlines the @speedcurve/lux snippet at build time. The runtime speedcurve.ts now imports from this virtual module instead of directly from the external package. Corresponding changes remove @speedcurve/lux from build externals, update test infrastructure and mocks, and clarify label callback documentation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: vendoring the LUX snippet and grouping/clarifying schema options for SpeedCurve.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining snippet sourcing changes, schema clarity improvements, and validation results.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/speedcurve-followups

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 and usage tips.

…stration

- Replace the vendored snippet with a virtual `#build/nuxt-scripts-speedcurve-snippet` template.
- The module only emits the template when `scripts.registry.speedcurve` is set; missing registration produces a clear build error.
- The template resolves the snippet from the user-installed `@speedcurve/lux` peer dep so users control the snippet version; missing dep throws at import with an install hint.
- Adds a setup section to the docs documenting the opt-in registration + peer dep install.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@packages/script/src/module.ts`:
- Around line 672-675: The fallback currently returns only a throwing expression
which causes ESM to fail before the install-hint can be read; change the
fallback returned by the module generator so it always exports luxSnippetSource
(e.g., an empty string or null) and then throws the install hint, so imports
that expect the luxSnippetSource export (from useScriptSpeedCurve / the
generated module using snippetPath and luxSnippetSource) won't fail during
instantiation; update the branch that checks snippetPath/existsSync to return a
module string that includes an export for luxSnippetSource plus the throw
message.

In `@packages/script/src/runtime/registry/speedcurve.ts`:
- Around line 7-12: Reorder the import statements so that the virtual/build
alias import "luxSnippetSource" from '`#build/nuxt-scripts-speedcurve-snippet`'
appears before the relative import from '../utils/after-next-paint' to satisfy
the linter's import ordering rule; locate the import of luxSnippetSource and
move it above the import of afterNextPaint (or any other ../utils/* imports) in
packages/script/src/runtime/registry/speedcurve.ts.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b9871179-1a35-4617-ac2b-0e687eda8770

📥 Commits

Reviewing files that changed from the base of the PR and between f837af7 and 7638dfe.

📒 Files selected for processing (8)
  • docs/content/scripts/speedcurve.md
  • packages/script/src/module.ts
  • packages/script/src/runtime/registry/speedcurve.ts
  • test/unit/__mocks__/empty.ts
  • test/unit/speedcurve-auto-tracker.test.ts
  • test/unit/speedcurve-config.test.ts
  • test/unit/speedcurve-primer.test.ts
  • vitest.config.ts
✅ Files skipped from review due to trivial changes (2)
  • test/unit/mocks/empty.ts
  • docs/content/scripts/speedcurve.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/unit/speedcurve-primer.test.ts
  • test/unit/speedcurve-config.test.ts

Comment thread packages/script/src/module.ts
Comment thread packages/script/src/runtime/registry/speedcurve.ts Outdated
A bare `throw` in the virtual template body produces an ESM module with no exports, so `import { luxSnippetSource }` fails at instantiation with "does not provide an export named 'luxSnippetSource'" before the install hint can surface. Wrap the throw inside the export initializer so the error fires only when the snippet is read.

Also reorders the virtual import in speedcurve.ts ahead of the relative imports to satisfy import-order lint.
…heck

The Nuxt `#build/*` tsconfig path resolves to a real file on disk; without an emitted .d.ts the typecheck fails for any consumer of useScriptSpeedCurve regardless of registration. Always emit a tiny declaration template so types resolve, keep the runtime .mjs emission gated on `scripts.registry.speedcurve` so non-users carry no LUX primer code.
Drop the unconditional .d.ts template; the virtual is only emitted on registration, so just suppress the type error on the import line. Non-registered consumers still hit the unresolved-virtual build error at user build time.
harlan-zw added 2 commits May 27, 2026 20:23
…ual snippet

The playground has speed-curve demo pages but speedcurve wasn't registered, so the gated `#build/nuxt-scripts-speedcurve-snippet` virtual didn't emit and the Vercel build failed at module resolution.
…l load

Make explicit that `scripts.registry.speedcurve` registration is what triggers the build-time primer resolution, not optional. Show the minimum `speedcurve: {}` shape for composable-only usage alongside the global-load variant, plus the two failure modes (missing registration vs missing peer dep) so users can diagnose without spelunking.
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