Skip to content

feat: support getIn and getBufferIn#33

Merged
fengmk2 merged 4 commits intomasterfrom
get-in
Dec 4, 2025
Merged

feat: support getIn and getBufferIn#33
fengmk2 merged 4 commits intomasterfrom
get-in

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Dec 4, 2025

Summary by CodeRabbit

  • New Features

    • Added path-based JSON value retrieval (returns parsed value or undefined), buffer-level access to raw value bytes, and returned positional metadata for found ranges.
  • Tests

    • Added comprehensive tests covering successful retrievals, missing-path behavior, empty-path validation, and buffer-return correctness.
  • Chores

    • Extended benchmark suite with new scripts to measure property-access performance and memory/GC behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 4, 2025 12:37
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a native-backed positional lookup API: Rust get_in returning start/end offsets, JS exports for getIn, TypeScript JSONBuilder methods getIn and getBufferIn, plus tests and benchmarks exercising property retrieval and GC-enabled benchmark scripts.

Changes

Cohort / File(s) Summary
Native JSON implementation
src/json.rs
Added check_paths(paths) validation; introduced #[napi(object)] pub struct GetInResult { start: u32, end: u32 }; added #[napi] pub fn get_in(data: &[u8], paths: Vec<String>) -> Result<Option<GetInResult>>; invoked check_paths in relevant functions.
JS runtime exports
index.js, index.d.ts
Re-exported native getIn from the binding in index.js; added GetInResult type and `getIn(data: Uint8Array, paths: Array): GetInResult
JSONBuilder (TS)
js/builder.ts
Removed empty-path validations from setIn, deleteIn, hasIn; added `getBufferIn(paths: string[]): Buffer
Tests
__test__/builder-get-in.spec.ts
New test suite covering getIn and getBufferIn: various value types, missing-path behavior, empty-path error, and buffer content assertions.
Benchmarks & scripts
benchmark/get_property_value.ts, benchmark/bench_memory.ts, package.json
Added benchmark/get_property_value.ts; extended benchmark/bench_memory.ts to include new script runs; updated package.json scripts (bench:gc now runs bench:gc:add_version and bench:gc:get_property_value, added those scripts).

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Builder as JSONBuilder
    participant Binding as Native Binding (N-API)
    participant Rust as get_in (Rust)

    Client->>Builder: getIn(paths)
    Builder->>Builder: getBufferIn(paths)
    Builder->>Binding: native getIn(data, paths)
    Binding->>Rust: invoke get_in(data, paths)
    Rust->>Rust: validate paths, locate value, compute start/end
    Rust-->>Binding: Some(GetInResult { start, end }) or None
    Binding-->>Builder: GetInResult | null
    alt offsets returned
        Builder->>Builder: slice Buffer[start:end]
        Builder->>Builder: JSON.parse(slice) -> value
        Builder-->>Client: value
    else not found
        Builder-->>Client: undefined
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Inspect src/json.rs for accidental duplicate blocks and validate check_paths placement.
  • Verify start/end offset semantics (inclusive/exclusive) match Buffer.slice usage in js/builder.ts.
  • Confirm error messages for empty path arrays are consistent across Rust, JS, and tests.
  • Validate native binding export names in index.js and index.d.ts.

Possibly related PRs

Poem

🐰 I nibbled through bytes by lantern light,
Found start and end where values hide at night.
Rust roots dug, TypeScript paws fetched in,
Buffers cradled secrets from within.
Hop, parse, deliver — a tiny win! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes, which add getIn and getBufferIn methods to the JSONBuilder API across multiple files.
✨ 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 get-in

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bee5c58 and 609681a.

📒 Files selected for processing (2)
  • js/builder.ts (2 hunks)
  • src/json.rs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/json.rs (2)
src/package.rs (1)
  • new (19-23)
index.d.ts (2)
  • SetPropertyPositionResult (173-182)
  • GetInResult (117-120)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Agent
  • GitHub Check: stable - aarch64-pc-windows-msvc - node@24
  • GitHub Check: stable - x86_64-pc-windows-msvc - node@24
  • GitHub Check: Run Benchmark
  • GitHub Check: Analyze (rust)
🔇 Additional comments (9)
js/builder.ts (3)

5-5: LGTM: Import addition aligns with new functionality.

The getIn import is necessary for the new getBufferIn method implementation and is correctly placed.


107-113: LGTM: Clean delegation to native code with appropriate error handling.

The method correctly delegates path validation to the native getIn function, which now includes the check_paths validation in Rust. This aligns with the previous review feedback to centralize validation on the native side.


98-105: > Likely an incorrect or invalid review comment.

src/json.rs (6)

33-42: Excellent addition: Centralized validation prevents panics and ensures API consistency.

This helper function addresses the concern from the previous review about moving validation to Rust. By validating non-empty paths at the native layer, it:

  • Prevents potential panics from paths.len() - 1 operations in detect_set_property_position (line 71) and detect_delete_property_position (line 154)
  • Ensures consistent behavior across all exported functions
  • Provides clear error messages to JS consumers

Based on learnings from past review feedback.


49-49: LGTM: Early validation protects against panics.

The check_paths call at the beginning of the function correctly prevents the potential panic at line 71 where paths[..paths.len() - 1] is used.


141-141: LGTM: Consistent validation pattern applied.

The validation correctly protects lines 154-155 where paths[paths.len() - 1] and path slicing operations are performed.


246-246: LGTM: Validation ensures API consistency.

While has_in doesn't perform path slicing operations, the validation ensures consistent behavior across all path-based APIs, as noted in the previous review feedback.


255-260: LGTM: Struct follows established patterns.

The GetInResult struct correctly mirrors the pattern used by SetPropertyPositionResult and DeletePropertyPositionResult, ensuring consistency across the API.


262-274: LGTM: Well-structured implementation following established patterns.

The get_in function correctly:

  • Validates paths using the new check_paths helper
  • Reuses the existing get_value_position helper for calculating buffer offsets
  • Distinguishes between "not found" (returns None) and actual errors (returns Err)
  • Follows the same error handling pattern as has_in and other path-based functions

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.

@gemini-code-assist
Copy link

Summary of Changes

Hello @fengmk2, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the JSONBuilder class by introducing getIn and getBufferIn methods. These new functionalities enable developers to efficiently extract specific values or their raw byte representations from a JSON buffer using a path, without the overhead of parsing the entire document. The underlying implementation leverages native Rust code for optimal performance, and new benchmarks have been included to validate these performance improvements. This change significantly streamlines access to nested JSON data.

Highlights

  • New getIn and getBufferIn methods: Introduced getIn and getBufferIn methods to the JSONBuilder class, allowing efficient retrieval of specific values or their raw buffer representations from a JSON document using a path array.
  • Native Rust Implementation: The core logic for path-based JSON value retrieval (getIn) is implemented in Rust, providing high performance by directly working with byte buffers and avoiding full JSON parsing.
  • Performance Benchmarks: Added new benchmark scripts to compare the performance of the new getIn method against standard JSON.parse for property value retrieval, demonstrating its efficiency.
  • Comprehensive Testing: New test cases have been added to ensure the correctness and robustness of getIn and getBufferIn across various data types and edge cases, including non-existent paths and empty path arrays.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces getIn and getBufferIn methods to the JSONBuilder, allowing for efficient retrieval of nested values from a JSON buffer by leveraging native Rust code to avoid parsing the entire document. The changes include the core implementation in Rust and JavaScript, along with corresponding type definitions, tests, and benchmarks. The implementation is solid, but I've identified a significant API inconsistency regarding the handling of empty path arrays. The JavaScript wrapper methods throw an error for empty paths, while the directly-exported native functions have a different behavior, which can even lead to panics in some existing functions. My review includes a recommendation to move this validation into the native Rust code for consistency and safety.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
benchmark/get_property_value.ts (1)

19-40: Consider benchmark methodology for more accurate comparison.

The benchmark compares two different operations:

  • JSONParse: Parses the entire document and accesses the property
  • SonicJSONParse: Creates a JSONBuilder and retrieves only the specific property

Two recommendations:

  1. Document the comparison intent: If the goal is to benchmark end-to-end property access (including parsing), the current approach is fine. However, if you want to isolate the property retrieval performance, consider moving the JSONBuilder construction outside the timed loop.

  2. Reduce noise from builder construction: Line 26 creates a new JSONBuilder instance on each iteration, which includes construction overhead in the timing.

If you want to measure only retrieval performance, consider this refactor:

 function SonicJSONParse(data: Buffer) {
   const builder = new JSONBuilder(data)
   return builder.getIn<string>(['name'])
 }
 
 const parse = method === 'SonicJSONParse' ? SonicJSONParse : JSONParse
 
+// Create builder once for SonicJSONParse to isolate retrieval performance
+const builder = method === 'SonicJSONParse' ? new JSONBuilder(largeData) : null
+
 const name = parse(largeData)
 console.log(`${method} get name of ${filename}: %o`, name)
 
 for (let i = 0; i < 5; i++) {
   const startTime = performance.now()
-  parse(largeData)
+  if (method === 'SonicJSONParse' && builder) {
+    builder.getIn<string>(['name'])
+  } else {
+    parse(largeData)
+  }
   const endTime = performance.now()

Alternatively, if the intent is to benchmark the full operation including construction, consider adding a comment clarifying this design choice.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5680af and 20c78e1.

📒 Files selected for processing (7)
  • __test__/builder-get-in.spec.ts (1 hunks)
  • benchmark/get_property_value.ts (1 hunks)
  • index.d.ts (1 hunks)
  • index.js (1 hunks)
  • js/builder.ts (2 hunks)
  • package.json (1 hunks)
  • src/json.rs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
__test__/builder-get-in.spec.ts (1)
js/builder.ts (1)
  • JSONBuilder (20-134)
index.d.ts (1)
js/builder.ts (1)
  • getIn (107-114)
src/json.rs (2)
index.d.ts (1)
  • GetInResult (117-120)
src/package.rs (1)
  • new (19-23)
benchmark/get_property_value.ts (2)
js/builder.ts (1)
  • JSONBuilder (20-134)
benchmark/gc.ts (1)
  • getGCStats (51-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Agent
  • GitHub Check: Analyze (rust)
🔇 Additional comments (6)
index.js (1)

560-560: LGTM! Clean addition of the new native binding export.

The changes correctly expose the getIn function from the native binding, following the established pattern for other exports like hasIn.

Also applies to: 565-565

package.json (1)

59-61: LGTM! Benchmark script organization improved.

The refactoring to separate benchmark scripts for different scenarios (add_version and get_property_value) improves maintainability and allows targeted benchmarking.

index.d.ts (1)

115-120: LGTM! Type declarations are well-structured.

The GetInResult interface and getIn function signature are correctly defined and align with the Rust implementation. The placement next to hasIn maintains good API organization.

__test__/builder-get-in.spec.ts (1)

1-47: LGTM! Excellent test coverage.

The test suite thoroughly validates the new getIn and getBufferIn functionality:

  • Multiple data types (string, number, object, null, boolean, array)
  • Nested paths
  • Non-existent path handling
  • Empty path validation
  • Buffer representation accuracy
js/builder.ts (1)

5-5: LGTM! Clean implementation with proper delegation.

The new methods are well-implemented:

  • getIn appropriately delegates to getBufferIn for code reuse
  • Empty path validation is consistent with other methods (setIn, deleteIn, hasIn)
  • Error handling follows established patterns
  • The @ts-expect-error on line 112 is acceptable since the package targets Node.js >= 22 where JSON.parse accepts Uint8Array

Also applies to: 107-125

src/json.rs (1)

241-259: LGTM! Solid Rust implementation following established patterns.

The get_in function and GetInResult struct are well-implemented:

  • Mirrors the design of has_in (lines 231-239) but returns positional metadata
  • Proper error handling: returns Ok(None) for not found, propagates other errors
  • Uses the existing get_value_position helper for consistency
  • Type definitions align with the TypeScript declarations in index.d.ts

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

📦 napi-rs Build Size Comparison

File Base Size PR Size Diff %
📈 packument.linux-x64-gnu.node 849.82 KB 853.82 KB +4.00 KB +.47%

Total: 849.82 KB → 853.82 KB (+4.00 KB, +.47%)

Compared using x86_64-unknown-linux-gnu target

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for getIn and getBufferIn methods to the JSONBuilder class, allowing users to efficiently retrieve values from JSON data without parsing the entire document. The Rust backend provides a new get_in function that returns the byte positions of requested values, which the TypeScript methods use to extract and optionally parse the data.

Key changes:

  • Added Rust get_in function that returns start/end byte positions of JSON values at specified paths
  • Added getIn<T>() method to JSONBuilder that retrieves and parses values
  • Added getBufferIn() method that returns the raw buffer slice without parsing
  • Added benchmark suite to compare performance with standard JSON.parse

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/json.rs Implements get_in function and GetInResult struct in Rust for efficient position detection
js/builder.ts Adds getIn and getBufferIn methods to JSONBuilder class
index.js Exports the new getIn function from native bindings
index.d.ts Adds TypeScript type definitions for getIn and GetInResult
test/builder-get-in.spec.ts Adds comprehensive test suite for the new methods
benchmark/get_property_value.ts Adds performance benchmark comparing JSONBuilder.getIn with JSON.parse
package.json Updates benchmark scripts to include the new get_property_value benchmark

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

⚡ Benchmark Results

Click to expand benchmark output
┌─────────┬──────────────────────────────────────────────────────────────────────┬─────────────────────┬───────────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name                                                            │ Latency avg (ns)    │ Latency med (ns)      │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼──────────────────────────────────────────────────────────────────────┼─────────────────────┼───────────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0       │ 'JSONParse small data readme string (117KB)'                         │ '464341 ± 0.62%'    │ '433427 ± 11344'      │ '2185 ± 0.45%'         │ '2307 ± 62'            │ 2154    │
│ 1       │ 'sonic-rs small data readme string (117KB)'                          │ '142513 ± 0.23%'    │ '140212 ± 1954.0'     │ '7060 ± 0.15%'         │ '7132 ± 100'           │ 7017    │
│ 2       │ 'sonic-rs small data readme string with position (117KB)'            │ '154806 ± 0.28%'    │ '151588 ± 2346.0'     │ '6505 ± 0.17%'         │ '6597 ± 102'           │ 6460    │
│ 3       │ 'sonic-rs small data readme JSON buffer with position (117KB)'       │ '112682 ± 0.14%'    │ '111472 ± 285.00'     │ '8886 ± 0.05%'         │ '8971 ± 23'            │ 8875    │
│ 4       │ 'JSONParse large data readme string (22MB)'                          │ '147847870 ± 1.28%' │ '146382491 ± 362359'  │ '7 ± 1.00%'            │ '7 ± 0'                │ 64      │
│ 5       │ 'sonic-rs large data readme string (22MB)'                           │ '24371546 ± 0.97%'  │ '24243905 ± 164613'   │ '41 ± 0.76%'           │ '41 ± 0'               │ 64      │
│ 6       │ 'sonic-rs large data readme string with position (22MB)'             │ '24151042 ± 0.34%'  │ '24164606 ± 183303'   │ '41 ± 0.33%'           │ '41 ± 0'               │ 64      │
│ 7       │ 'sonic-rs large data readme JSON buffer with position (22MB)'        │ '24178701 ± 0.49%'  │ '24097969 ± 189372'   │ '41 ± 0.46%'           │ '41 ± 0'               │ 64      │
│ 8       │ 'JSONParse super large data readme string (89M)'                     │ '348977706 ± 1.24%' │ '339054050 ± 4611774' │ '3 ± 1.20%'            │ '3 ± 0'                │ 64      │
│ 9       │ 'sonic-rs super large data readme string (89M)'                      │ '85257477 ± 0.12%'  │ '85221765 ± 149182'   │ '12 ± 0.12%'           │ '12 ± 0'               │ 64      │
│ 10      │ 'sonic-rs super large data readme string with position (89M)'        │ '85340229 ± 0.39%'  │ '85172008 ± 185008'   │ '12 ± 0.35%'           │ '12 ± 0'               │ 64      │
│ 11      │ 'sonic-rs super large data readme JSON buffer with position (89M)'   │ '85114759 ± 0.07%'  │ '85077501 ± 143368'   │ '12 ± 0.07%'           │ '12 ± 0'               │ 64      │
│ 12      │ 'JSONParse big readme string (229KB, 64KB readme)'                   │ '645964 ± 2.00%'    │ '624031 ± 10529'      │ '1588 ± 0.35%'         │ '1602 ± 27'            │ 1549    │
│ 13      │ 'sonic-rs big readme string (229KB, 64KB readme)'                    │ '271203 ± 0.71%'    │ '268041 ± 1041.0'     │ '3705 ± 0.10%'         │ '3731 ± 15'            │ 3688    │
│ 14      │ 'sonic-rs big readme string with position (229KB, 64KB readme)'      │ '294678 ± 0.23%'    │ '292013 ± 1596.5'     │ '3401 ± 0.12%'         │ '3425 ± 19'            │ 3394    │
│ 15      │ 'sonic-rs big readme JSON buffer with position (229KB, 64KB readme)' │ '240825 ± 0.20%'    │ '237302 ± 345.00'     │ '4163 ± 0.13%'         │ '4214 ± 6'             │ 4153    │
│ 16      │ 'JSONParse large data add version (22MB)'                            │ '304946167 ± 0.21%' │ '304492586 ± 1161425' │ '3 ± 0.20%'            │ '3 ± 0'                │ 64      │
│ 17      │ 'sonic-rs large data add version (22MB)'                             │ '69769123 ± 0.78%'  │ '68472544 ± 783129'   │ '14 ± 0.77%'           │ '15 ± 0'               │ 64      │
│ 18      │ 'JSONParse super large data add version (89M)'                       │ '725747683 ± 0.19%' │ '725578635 ± 3021368' │ '1 ± 0.19%'            │ '1 ± 0'                │ 64      │
│ 19      │ 'sonic-rs super large data add version (89M)'                        │ '257303499 ± 0.08%' │ '257278443 ± 554609'  │ '4 ± 0.08%'            │ '4 ± 0'                │ 64      │
└─────────┴──────────────────────────────────────────────────────────────────────┴─────────────────────┴───────────────────────┴────────────────────────┴────────────────────────┴─────────┘

Memory Usage:
  JSONParse description (22M): 472.0 MB (min: 471.6 MB, max: 473.5 MB)
  JSONParse description (89M): 866.4 MB (min: 865.9 MB, max: 866.8 MB)
  SonicJSONParse description (22M): 90.2 MB (min: 89.9 MB, max: 91.2 MB)
  SonicJSONParse description (89M): 158.3 MB (min: 157.6 MB, max: 159.5 MB)

Memory Usage:
  JSONParse add version (22M): 421.3 MB (min: 419.2 MB, max: 426.0 MB)
  JSONParse add version (89M): 777.8 MB (min: 777.3 MB, max: 779.0 MB)
  SonicJSONParse add version (22M): 182.4 MB (min: 181.8 MB, max: 183.8 MB)
  SonicJSONParse add version (89M): 427.0 MB (min: 425.8 MB, max: 428.0 MB)

Memory Usage:
  JSONParse get property value (22M): 489.4 MB (min: 488.8 MB, max: 490.5 MB)
  JSONParse get property value (89M): 871.8 MB (min: 869.4 MB, max: 874.0 MB)
  SonicJSONParse get property value (22M): 93.1 MB (min: 92.3 MB, max: 93.4 MB)
  SonicJSONParse get property value (89M): 159.8 MB (min: 159.0 MB, max: 160.5 MB)

## Benchmarking JSONParse with @primer/react.json
- Data size: 89MB
- GC: enabled

JSONParse add version (@primer/react.json) #1 time: 764ms
JSONParse add version (@primer/react.json) #2 time: 715ms
JSONParse add version (@primer/react.json) #3 time: 751ms
JSONParse add version (@primer/react.json) #4 time: 726ms
JSONParse add version (@primer/react.json) #5 time: 723ms

[GC] total(ms)= 138.24 count= 24 avg(ms)= 5.76 byKind= {
  scavenge: 52.29183700028807,
  markSweepCompact: 83.58488099987153,
  incremental: 2.361832999973558,
  weakc: 0,
  unknown: 0
}

## Benchmarking SonicJSONParse with @primer/react.json
- Data size: 89MB
- GC: enabled

SonicJSONParse add version (@primer/react.json) #1 time: 259ms
SonicJSONParse add version (@primer/react.json) #2 time: 258ms
SonicJSONParse add version (@primer/react.json) #3 time: 257ms
SonicJSONParse add version (@primer/react.json) #4 time: 257ms
SonicJSONParse add version (@primer/react.json) #5 time: 257ms

[GC] total(ms)= 5.22 count= 8 avg(ms)= 0.65 byKind= {
  scavenge: 0,
  markSweepCompact: 4.128702000016347,
  incremental: 1.09590999991633,
  weakc: 0,
  unknown: 0
}

## Benchmarking JSONParse with @primer/react.json
- Data size: 89MB
- GC: enabled

JSONParse get name of @primer/react.json: '@primer/react'
JSONParse get property value (@primer/react.json) #1 time: 382ms
JSONParse get property value (@primer/react.json) #2 time: 350ms
JSONParse get property value (@primer/react.json) #3 time: 347ms
JSONParse get property value (@primer/react.json) #4 time: 390ms
JSONParse get property value (@primer/react.json) #5 time: 338ms

[GC] total(ms)= 220.06 count= 22 avg(ms)= 10.00 byKind= {
  scavenge: 183.09609600005206,
  markSweepCompact: 35.85724600008689,
  incremental: 1.1039009999949485,
  weakc: 0,
  unknown: 0
}

## Benchmarking SonicJSONParse with @primer/react.json
- Data size: 89MB
- GC: enabled

SonicJSONParse get name of @primer/react.json: '@primer/react'
SonicJSONParse get property value (@primer/react.json) #1 time: 0ms
SonicJSONParse get property value (@primer/react.json) #2 time: 0ms
SonicJSONParse get property value (@primer/react.json) #3 time: 0ms
SonicJSONParse get property value (@primer/react.json) #4 time: 0ms
SonicJSONParse get property value (@primer/react.json) #5 time: 0ms

[GC] total(ms)= 2.04 count= 2 avg(ms)= 1.02 byKind= {
  scavenge: 0,
  markSweepCompact: 1.7713020000373945,
  incremental: 0.2641209999565035,
  weakc: 0,
  unknown: 0
}

Benchmark ran on x86_64-unknown-linux-gnu target

@fengmk2 fengmk2 added the enhancement New feature or request label Dec 4, 2025
Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
__test__/builder-get-in.spec.ts (1)

49-55: Consider using valid JSON and adding more error test cases.

The test partially addresses the past review comment about error scenarios, but could be improved:

  1. The test uses malformed JSON ('{"name": "John",'), which obscures whether the error is from invalid JSON parsing or from accessing a property of a non-object type. Consider using valid JSON like '{"name": "John"}' for clarity.

  2. Additional test cases are still missing for accessing properties of other non-object types in valid JSON:

    • ['age', 'country'] - accessing property of a number
    • ['bar', 'something'] - accessing property of a boolean
    • ['foo', 'something'] - accessing property of null

These tests exist in __test__/builder-has-in.spec.ts and would improve consistency across the test suite.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20c78e1 and bee5c58.

📒 Files selected for processing (2)
  • __test__/builder-get-in.spec.ts (1 hunks)
  • benchmark/bench_memory.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
benchmark/bench_memory.ts (1)
benchmark/memory_usage.ts (1)
  • runMemoryBenchmarks (87-114)
__test__/builder-get-in.spec.ts (1)
js/builder.ts (1)
  • JSONBuilder (20-134)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Benchmark
  • GitHub Check: stable - aarch64-pc-windows-msvc - node@24
  • GitHub Check: stable - x86_64-pc-windows-msvc - node@24
  • GitHub Check: Analyze (rust)
🔇 Additional comments (2)
benchmark/bench_memory.ts (1)

38-51: LGTM! Consistent with existing benchmark patterns.

The new memory benchmarks for get_property_value follow the exact same structure as the existing getDescription and addVersion benchmarks, maintaining consistency in the test suite.

__test__/builder-get-in.spec.ts (1)

5-47: Well-structured test coverage for the happy paths.

The test cases comprehensively cover:

  • Various data types (string, number, object, null, boolean, array)
  • Non-existent property handling (undefined returns)
  • Empty paths validation
  • Both getIn and getBufferIn methods with correct assertions

Copilot AI review requested due to automatic review settings December 4, 2025 12:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@fengmk2 fengmk2 merged commit 1e2c68c into master Dec 4, 2025
44 checks passed
@fengmk2 fengmk2 deleted the get-in branch December 4, 2025 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants