Skip to content

Latest commit

 

History

History
117 lines (88 loc) · 6.81 KB

File metadata and controls

117 lines (88 loc) · 6.81 KB

Rollup - Agent Instructions

Keep instructions concise, only add non-obvious information. Proactively update AGENTS.md to prevent future mistakes.

General

  • Variables and functions should have clear, descriptive names that reflect their purpose and behavior and not e.g. their data types.
  • Code should be organized so that things that will most likely change together are located near each other, instead of e.g. grouping solely by technical categories.

Architecture

  • TypeScript + Rust hybrid: Rust code in rust/ (bindings_napi, bindings_wasm, parse_ast crates) called via native.js and native.wasm.js
  • Generated files: Files with "Do not edit this file directly" comments (e.g., src/ast/bufferParsers.ts, src/ast/childNodeKeys.ts, src/ast/nodeIds.ts) are generated from scripts/ast-types.ts via scripts/generate-ast-converters.ts and files that are imported in that file
  • Tests run against full artifact only—no unit tests to allow easy refactoring of internal APIs
  • Test cases in test/*/samples/ are configured via _config.js files; focus tests with solo: true
  • See CONTRIBUTING.md "How to write tests" for test type selection (function/form/chunking-form/cli/etc.)

JS-Rust Interface

When adding/modifying functions that cross the JS-Rust boundary:

  1. Rust implementations: Update rust/bindings_napi/src/lib.rs (Node native) and rust/bindings_wasm/src/lib.rs (WASM)
  2. JS handover points (must have matching signatures):
    • native.js - Node native build (NAPI)
    • native.wasm.js - Node WASM build
    • browser/src/wasm.ts - Browser WASM build
  3. Build process: rollup.config.ts replaces native.js with browser/src/wasm.ts for browser builds; CI replaces it with native.wasm.js for Node WASM builds
  4. TypeScript definitions: native.d.ts is auto-generated by napi-rs for NAPI bindings; WASM types are generated in wasm/bindings_wasm.d.ts
  5. Testing builds (will also generate definitions):
    • Node native: npm run build:napi
    • Browser WASM: npm run build:wasm
    • Node WASM: npm run build:wasm:node

Rust Code Organization

  • Focus on performance, avoid unnecessary copying of data or AST loops, build the final buffer once
  • When adding headers, reserve space for them once upfront to avoid the need to change all existing buffer references

Browser Path Shim

  • browser/src/path.ts replaces node:path in the browser build (wired via rollup.config.ts aliases)
  • src/utils/relativeId.ts imports relative directly from ../../browser/src/path (not via src/utils/path.ts) so it works in both builds
  • src/utils/path.ts re-exports from node:path; for browser builds rollup.config.ts substitutes browser/src/path.ts transparently for all other imports

Development Workflow

Build Outputs

  • Node build: Artifacts placed in dist/ (JavaScript + .node native modules)
  • Browser build: Artifacts placed in browser/dist/; browser tests use browser/dist/rollup.browser.js
  • All tests import from these dist folders - tests run against the full built artifact only

Quick Rebuild Commands

  • npm run build:quick - Rebuild both JavaScript and Rust for Node build, copy to dist/
  • npm run update:js - Rebuild only JavaScript for both Node (dist/) and browser (browser/dist/), then copy native to dist/; run this after any change to src/ or browser/src/
  • npm run update:napi - Rebuild only Rust NAPI, copy to dist/
  • npm run build:copy-native - Copy Rust .node files to dist/ (called internally by update commands)

Full Build Commands

  • npm run build - Full build: WASM + AST converters + NAPI (release) + JavaScript + copy native
  • npm run build:napi - Build Rust NAPI bindings (use -- --release for optimized)
  • npm run build:wasm - Build browser WASM
  • npm run build:js - Build JavaScript (Node and browser)

Common Workflows

  • Rust changes only: npm run update:napi then npm run test:only
  • JavaScript changes only: npm run update:js then npm run test:only
  • AST schema changes: npm run build:ast-converters to regenerate TypeScript and Rust files
  • Testing changes: npm run build:quick then npm run test:only

Testing

  • Always test edge cases, especially in core logic or build/test infrastructure
  • Test names and descriptions use clear, descriptive language of the expected behavior, e.g. "description: 'does X when Y happens"

Test Types

  • Directory based tests
    • Should be preferred for tests if possible
    • Reside in directories in test/<category>/samples
    • Each test has a _config.js file with a description field and potentially other configuration options
    • The preferred way to work on a single or few of those tests is to add solo: true to the test's _config.js file first, and then run:
      npm run build:quick
      npm run test:quick
      
    • Each test category is run by a test/<category>/index.js file
    • The available options for each test category are defined in test/types.d.ts
  • Traditional file based tests
    • Are run directly by mocha using describe and it blocks
    • Can be found in test/misc/, test/hooks and test/incremental

Test Categories

  • function
    • Will bundle a main.js file next to the _config.js file and then run it
    • Has node:assert injected as a global variable in the bundled test code (main.js), allowing you to use assert directly without importing
    • In _config.js, you must explicitly require assert: const assert = require('node:assert/strict'); to use it in the exports function or other config functions
    • Use when testing if bundled code still works (use inline assert in the code or the exports field in _config.js to make assertions)
    • Use when testing build errors, warnings, or plugin hooks
  • form
    • Will bundle a main.js file and store the output either as an _actual directory with outputs for each format (es.js, cjs.js, amd.js, system.js, umd.js, iife.js) or an _actual.js file for a single format, compared with an existing _expected directory or _expected.js file
    • The single _actual.js file will be generated if an _expected.js file is present. Having a single file is preferred, so when writing a form test, start with writing the _expected.js file before running the test for the first time
  • chunking-form
    • Similar to form, but always generates all formats and produces a separate directory for each format; the entire directory is compared with an _expected directory
    • Use when multiple files are expected in the output
  • cli
    • Use when running rollup as a command line tool

Code Review Focus

  • Ignore style/linting issues in test sample files (test/*/samples/) except for _config.js files
  • Test samples intentionally violate best practices to test edge cases—do not flag style violations in these files
  • Focus reviews on production code quality