add tsx, jsx validation support
This commit is contained in:
parent
ef0fd4b2ab
commit
5db4f435a8
4 changed files with 34 additions and 25 deletions
|
|
@ -14,6 +14,7 @@ from tree_sitter import Language, Parser
|
|||
js_parser = Parser(Language(tree_sitter_javascript.language()))
|
||||
|
||||
ts_parser = Parser(Language(tree_sitter_typescript.language_typescript()))
|
||||
tsx_parser = Parser(Language(tree_sitter_typescript.language_tsx()))
|
||||
|
||||
|
||||
@lru_cache(maxsize=100)
|
||||
|
|
@ -30,5 +31,9 @@ def validate_typescript_syntax(code: str) -> tuple[bool, str | None]:
|
|||
tree = ts_parser.parse(bytes(code, "utf8"))
|
||||
has_error = tree.root_node.has_error
|
||||
if has_error:
|
||||
# Try TSX parser for files containing JSX syntax
|
||||
tsx_tree = tsx_parser.parse(bytes(code, "utf8"))
|
||||
if not tsx_tree.root_node.has_error:
|
||||
return True, None
|
||||
return False, "Invalid syntax"
|
||||
return True, None
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
# Pattern to extract code blocks from LLM response (single file, no file path)
|
||||
JS_CODE_PATTERN = re.compile(r"```(?:javascript|js|typescript|ts)\s*\n(.*?)```", re.MULTILINE | re.DOTALL)
|
||||
JS_CODE_PATTERN = re.compile(r"```(?:javascript|jsx|js|typescript|tsx|ts)\s*\n(.*?)```", re.MULTILINE | re.DOTALL)
|
||||
|
||||
# Pattern to extract code blocks with file paths (multi-file context)
|
||||
JS_CODE_WITH_PATH_PATTERN = re.compile(
|
||||
r"```(?:javascript|js|typescript|ts):([^\n]+)\n(.*?)```", re.MULTILINE | re.DOTALL
|
||||
r"```(?:javascript|jsx|js|typescript|tsx|ts):([^\n]+)\n(.*?)```", re.MULTILINE | re.DOTALL
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -146,8 +146,9 @@ async def optimize_javascript_code_single(
|
|||
system_prompt = get_system_prompt(is_async)
|
||||
user_prompt = get_user_prompt(is_async)
|
||||
|
||||
# Format prompts with proper language tag
|
||||
system_prompt = system_prompt.format(language_version=language_version)
|
||||
# Format prompts with proper language tag (React prompts don't use language_version placeholder)
|
||||
if not is_react_component:
|
||||
system_prompt = system_prompt.format(language_version=language_version)
|
||||
|
||||
if is_multi_file:
|
||||
# For multi-file, identify the first file as the target and others as helper context
|
||||
|
|
@ -230,6 +231,7 @@ You MUST output the target file. You may also output helper files if you optimiz
|
|||
|
||||
if not extracted_code:
|
||||
sentry_sdk.capture_message("No code block found in JavaScript optimization response")
|
||||
logging.error(f"No code block found in LLM response. Content starts with: {output.content[:500]}")
|
||||
debug_log_sensitive_data(f"No code found in response for source:\n{source_code}")
|
||||
return None, llm_cost, optimize_model.name
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,27 @@ You are a professional React performance engineer. Your goal is to optimize Reac
|
|||
- Extract inline function expressions from JSX props to useCallback.
|
||||
- Style objects that never change should be module-level constants, not useMemo.
|
||||
|
||||
**Lazy State Initialization**
|
||||
- `useState(expensiveComputation())` calls the function on EVERY render, even though the result is only used on mount.
|
||||
- Use the lazy initializer form: `useState(() => expensiveComputation())` to run it only once.
|
||||
- This applies to any function call, object construction, or complex expression passed to useState.
|
||||
- Simple literals (strings, numbers, booleans) do NOT need lazy initialization.
|
||||
|
||||
**Expensive Object Construction**
|
||||
- `new RegExp(...)`, `new Date(...)`, `new Map(...)`, `new Set(...)`, `JSON.parse(...)`, `JSON.stringify(...)` in the render body create new objects on every render.
|
||||
- Move to `useMemo()` with appropriate dependencies, or to module scope if the value is static.
|
||||
- Regular expressions that don't change should be module-level constants (e.g., `const EMAIL_RE = /pattern/;`).
|
||||
|
||||
**Combining Loop Iterations**
|
||||
- If the same array is scanned multiple times with separate `.filter()`, `.map()`, `.reduce()`, `.forEach()` calls, combine them into a single `.reduce()` or `for...of` loop.
|
||||
- Example: `items.filter(x => x.active).map(x => x.name)` can be combined into a single pass with `.reduce()`.
|
||||
- This reduces time complexity from O(n*k) to O(n) where k is the number of passes.
|
||||
|
||||
**Parallelizing Async Operations**
|
||||
- Sequential `await` calls that are independent should use `Promise.all()` or `Promise.allSettled()`.
|
||||
- Example: `const a = await fetchA(); const b = await fetchB();` → `const [a, b] = await Promise.all([fetchA(), fetchB()]);`
|
||||
- Only parallelize when the operations are truly independent (no data dependency between them).
|
||||
|
||||
**React 19+ Awareness**
|
||||
- If the code uses React 19 or later, be aware that the React Compiler may auto-memoize.
|
||||
- Still apply optimizations that help the compiler (avoid inline objects, use stable references).
|
||||
|
|
|
|||
|
|
@ -1,29 +1,10 @@
|
|||
Optimize the following React component for rendering performance. Focus on reducing unnecessary re-renders while preserving identical behavior.
|
||||
|
||||
## Component Source Code
|
||||
```{{ language }}
|
||||
{{ source_code }}
|
||||
```
|
||||
|
||||
{% if dependency_code %}
|
||||
## Read-Only Context (Dependencies)
|
||||
```{{ language }}
|
||||
{{ dependency_code }}
|
||||
```
|
||||
{% endif %}
|
||||
|
||||
{% if react_context %}
|
||||
## React Component Analysis
|
||||
{{ react_context }}
|
||||
{% endif %}
|
||||
|
||||
{% if module_system %}
|
||||
## Module System
|
||||
This project uses {{ module_system }} modules.
|
||||
{% endif %}
|
||||
{source_code}
|
||||
|
||||
## Requirements
|
||||
1. The optimized component MUST produce identical rendered output for all possible prop/state combinations.
|
||||
2. Focus on: React.memo wrapping, useMemo for expensive computations, useCallback for event handlers passed to children, extracting inline objects/arrays from JSX props.
|
||||
2. Focus on: React.memo wrapping, useMemo for expensive computations, useCallback for event handlers passed to children, extracting inline objects/arrays from JSX props, lazy state initialization, combining loop iterations, and parallelizing independent async operations.
|
||||
3. Do NOT change the component's props interface or exported name.
|
||||
4. Return the complete optimized component code.
|
||||
|
|
|
|||
Loading…
Reference in a new issue