Skip to content

⚡ Bolt: Optimize JSON-LD parsing in movie service#83

Closed
bartholomej wants to merge 1 commit intomasterfrom
bolt/optimize-json-ld-parsing-1526776526782896992
Closed

⚡ Bolt: Optimize JSON-LD parsing in movie service#83
bartholomej wants to merge 1 commit intomasterfrom
bolt/optimize-json-ld-parsing-1526776526782896992

Conversation

@bartholomej
Copy link
Copy Markdown
Owner

@bartholomej bartholomej commented Feb 16, 2026

  • 💡 What: Extracted JSON.parse from getMovieYear and getMovieDuration helpers into the MovieScraper service.
  • 🎯 Why: To prevent redundant parsing of the same large JSON-LD string multiple times for each movie request.
  • 📊 Impact: Reduces CPU usage by performing JSON.parse only once per request instead of 2+ times.
  • 🔬 Measurement: Verified with existing tests.

PR created automatically by Jules for task 1526776526782896992 started by @bartholomej

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced error handling for movie metadata parsing with robust fallback mechanisms to ensure graceful degradation and improved reliability.
  • Refactor

    • Improved internal movie data structure and processing logic for better type safety, consistency, and reliability in handling movie metadata throughout the application.

- Move JSON.parse call from helpers to service layer
- Parse JSON-LD once per movie request instead of multiple times
- Update helper signatures to accept parsed object
- Update tests to reflect changes

Co-authored-by: bartholomej <5861310+bartholomej@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

This PR refactors JSON-LD handling by introducing a new MovieJsonLd interface and converting from string-based to object-based processing. The movie service now parses JSON-LD strings, passing structured objects to helper functions that extract movie metadata instead of raw strings.

Changes

Cohort / File(s) Summary
MovieJsonLd Interface & Helpers
src/helpers/movie.helper.ts
Introduced new MovieJsonLd interface with optional dateCreated and duration properties. Updated getMovieYear to accept MovieJsonLd | null and return numeric dateCreated. Updated getMovieDuration to accept MovieJsonLd | null and use parsed duration property with fallback parsing logic. Minor formatting changes to multi-line signatures.
Movie Service
src/services/movie.service.ts
Added JSON.parse logic with try-catch error handling to convert JSON-LD string to MovieJsonLd object. Updated buildMovie signature to accept MovieJsonLd | null instead of string. Updated movie() method to construct and pass parsed JSON-LD object downstream instead of raw string.
Test Updates
tests/movie.test.ts
Updated getJsonLd return type from string to any to return parsed JSON-LD object. Updated test helper signatures and test data formatting (quote style normalization, trailing comma cleanup).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ESM + CommonJS build 🎉  #18: Modifies the same movie helper and service files with related changes to getMovieYear, getMovieDuration, and JSON-LD handling in buildMovie.

Suggested labels

enhancement

Poem

🐰 From strings we parse to objects clean,
MovieJsonLd dances in between,
Helper functions now work with structured grace,
As JSON-LD finds its rightful place! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description explains the motivation and impact but lacks the required template sections like 'Type of change' and 'Checklist' that are specified in the repository template. Complete the pull request description by filling in the 'Type of change' (Refactoring), 'Related Issues' section, and the 'Checklist' items as specified in the repository template.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main optimization: moving JSON-LD parsing to the service layer to reduce redundant parsing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bolt/optimize-json-ld-parsing-1526776526782896992

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.

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.20%. Comparing base (25a700c) to head (257ce54).

Files with missing lines Patch % Lines
src/helpers/movie.helper.ts 92.30% 1 Missing ⚠️
src/services/movie.service.ts 80.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #83      +/-   ##
==========================================
- Coverage   99.52%   99.20%   -0.32%     
==========================================
  Files          28       28              
  Lines         629      632       +3     
  Branches      143      145       +2     
==========================================
+ Hits          626      627       +1     
- Misses          3        5       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@src/helpers/movie.helper.ts`:
- Around line 148-153: getMovieYear is typed to return number but returns null;
update its signature to return number | null and do the same for
getMovieDuration (change their return types to number | null), verify any
callers handle null or adjust them accordingly, and ensure the exported function
declarations (getMovieYear and getMovieDuration) match the new union return
type.

In `@src/services/movie.service.ts`:
- Around line 46-52: The code currently reads the LD+JSON text with
movieHtml.querySelector('script[type="application/ld+json"]').innerText which
can throw if the element is missing; update the retrieval so it uses optional
chaining to safely access innerText (e.g., via querySelector(...)? .innerText)
and provide a safe default (empty string or null) before attempting JSON.parse
in the movieJsonLd parse block so buildMovie(...) receives a properly
null/parsed movieJsonLd; ensure you only call JSON.parse when the retrieved
jsonLd string is non-null/non-empty and keep the existing try/catch around the
parse.

In `@tests/movie.test.ts`:
- Around line 386-401: Rename the duplicate test titles to be unique so failures
are identifiable; update the two tests that call getMovieYear with movieJsonLd
and movieRichJsonLd to different names (e.g., change the test title for the
movieRichJsonLd case from 'Year' to 'Year Rich' or similar) while leaving the
other tests (including the seriesJsonLd and null case) unchanged; ensure only
the test name strings are modified around the test(...) calls that reference
getMovieYear, movieJsonLd, and movieRichJsonLd.
🧹 Nitpick comments (3)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@src/helpers/movie.helper.ts`:
- Around line 148-153: getMovieYear is typed to return number but returns null;
update its signature to return number | null and do the same for
getMovieDuration (change their return types to number | null), verify any
callers handle null or adjust them accordingly, and ensure the exported function
declarations (getMovieYear and getMovieDuration) match the new union return
type.

In `@src/services/movie.service.ts`:
- Around line 46-52: The code currently reads the LD+JSON text with
movieHtml.querySelector('script[type="application/ld+json"]').innerText which
can throw if the element is missing; update the retrieval so it uses optional
chaining to safely access innerText (e.g., via querySelector(...)? .innerText)
and provide a safe default (empty string or null) before attempting JSON.parse
in the movieJsonLd parse block so buildMovie(...) receives a properly
null/parsed movieJsonLd; ensure you only call JSON.parse when the retrieved
jsonLd string is non-null/non-empty and keep the existing try/catch around the
parse.

In `@tests/movie.test.ts`:
- Around line 386-401: Rename the duplicate test titles to be unique so failures
are identifiable; update the two tests that call getMovieYear with movieJsonLd
and movieRichJsonLd to different names (e.g., change the test title for the
movieRichJsonLd case from 'Year' to 'Year Rich' or similar) while leaving the
other tests (including the seriesJsonLd and null case) unchanged; ensure only
the test name strings are modified around the test(...) calls that reference
getMovieYear, movieJsonLd, and movieRichJsonLd.
src/helpers/movie.helper.ts (1)

148-153: Return type should include null.

getMovieYear is declared as returning number but returns null on line 152. Same issue applies to getMovieDuration (line 155). While this may have been pre-existing (and works if strict null checks are disabled), it's worth fixing since you're already updating these signatures.

Proposed fix
-export const getMovieYear = (jsonLd: MovieJsonLd | null): number => {
+export const getMovieYear = (jsonLd: MovieJsonLd | null): number | null => {
-export const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number => {
+export const getMovieDuration = (jsonLd: MovieJsonLd | null, el: HTMLElement): number | null => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/helpers/movie.helper.ts` around lines 148 - 153, getMovieYear is typed to
return number but returns null; update its signature to return number | null and
do the same for getMovieDuration (change their return types to number | null),
verify any callers handle null or adjust them accordingly, and ensure the
exported function declarations (getMovieYear and getMovieDuration) match the new
union return type.
src/services/movie.service.ts (1)

46-52: Good: JSON-LD parsed once with proper error handling.

The try/catch around JSON.parse with fallback to null is appropriate. This centralizes parsing and avoids redundant work in helpers.

One note: line 45 (movieHtml.querySelector('script[type="application/ld+json"]').innerText) can throw if the element isn't found. While pre-existing, you could harden it with optional chaining since you're already touching this area:

Optional hardening
-    const jsonLd = movieHtml.querySelector('script[type="application/ld+json"]').innerText;
-    let movieJsonLd: MovieJsonLd | null = null;
-    try {
-      movieJsonLd = JSON.parse(jsonLd);
-    } catch (e) {
-      console.error('node-csfd-api: Error parsing JSON-LD', e);
-    }
+    const jsonLdText = movieHtml.querySelector('script[type="application/ld+json"]')?.innerText;
+    let movieJsonLd: MovieJsonLd | null = null;
+    if (jsonLdText) {
+      try {
+        movieJsonLd = JSON.parse(jsonLdText);
+      } catch (e) {
+        console.error('node-csfd-api: Error parsing JSON-LD', e);
+      }
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/movie.service.ts` around lines 46 - 52, The code currently reads
the LD+JSON text with
movieHtml.querySelector('script[type="application/ld+json"]').innerText which
can throw if the element is missing; update the retrieval so it uses optional
chaining to safely access innerText (e.g., via querySelector(...)? .innerText)
and provide a safe default (empty string or null) before attempting JSON.parse
in the movieJsonLd parse block so buildMovie(...) receives a properly
null/parsed movieJsonLd; ensure you only call JSON.parse when the retrieved
jsonLd string is non-null/non-empty and keep the existing try/catch around the
parse.
tests/movie.test.ts (1)

386-401: Duplicate test names: both year tests are named 'Year'.

Lines 387 and 390 both use test('Year', ...). This makes it harder to identify which test failed. Consider giving them distinct names (e.g., 'Year Rich').

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/movie.test.ts` around lines 386 - 401, Rename the duplicate test titles
to be unique so failures are identifiable; update the two tests that call
getMovieYear with movieJsonLd and movieRichJsonLd to different names (e.g.,
change the test title for the movieRichJsonLd case from 'Year' to 'Year Rich' or
similar) while leaving the other tests (including the seriesJsonLd and null
case) unchanged; ensure only the test name strings are modified around the
test(...) calls that reference getMovieYear, movieJsonLd, and movieRichJsonLd.

@bartholomej bartholomej deleted the bolt/optimize-json-ld-parsing-1526776526782896992 branch March 20, 2026 22:49
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.

2 participants