Pythonic JavaScript that doesn't suck - a Python-to-JavaScript transpiler with clean syntax and performance
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Specialized output generation system that converts AST nodes into optimized JavaScript code. The output system supports multiple JavaScript versions, formatting options, and advanced optimization features.
Core output stream class that manages JavaScript code generation with formatting and indentation.
/**
* Output stream for JavaScript code generation
*/
class OutputStream {
constructor(options: OutputOptions);
/** Print text to the output stream */
print(text: string): void;
/** Print text with a space separator */
space(): void;
/** Print an indented block */
with_indent(body: () => void): void;
/** Print text with parentheses if needed */
with_parens(body: () => void): void;
/** Print a comma-separated list */
with_commas(elements: any[], printer: (element: any) => void): void;
/** Print a block statement with braces */
with_block(body: () => void): void;
/** Get the complete generated output */
get(): string;
/** Get the complete generated output (alias for get) */
toString(): string;
/** Current indentation level */
indentation(): number;
/** Current line number */
current_line(): number;
/** Current column position */
current_col(): number;
}
interface OutputOptions {
/** Generate formatted, readable JavaScript (default: true) */
beautify?: boolean;
/** Wrap output in private scope function wrapper (default: true) */
private_scope?: boolean;
/** Exclude base library functions from output (default: false) */
omit_baselib?: boolean;
/** Target JavaScript version: 5 or 6 (default: 5) */
js_version?: number;
/** Preserve docstrings as __doc__ attributes (default: false) */
keep_docstrings?: boolean;
/** Remove assert statements from output (default: false) */
discard_asserts?: boolean;
/** Cache directory for compiled modules */
module_cache_dir?: string;
/** Pre-loaded base library code */
baselib_plain?: string;
/** Comment preservation strategy */
comments?: boolean | Function;
/** Semicolon insertion policy */
semicolons?: boolean;
/** Preserve line numbers from source */
preserve_line?: boolean;
/** Beautification options */
beautify_options?: BeautifyOptions;
}
interface BeautifyOptions {
/** Indent string (default: " ") */
indent_start?: number;
/** Indent increment (default: 4) */
indent_level?: number;
/** Quote style for strings */
quote_keys?: boolean;
/** Space after colon in objects */
space_colon?: boolean;
/** ASCII output only */
ascii_only?: boolean;
/** Inline script safety */
inline_script?: boolean;
/** Width for line breaks */
width?: number;
/** Maximum line length */
max_line_len?: number;
}Usage Examples:
const { create_compiler } = require("rapydscript-ng");
const RapydScript = create_compiler();
// Basic output generation
const ast = RapydScript.parse("def hello(): print('Hello')");
const output = new RapydScript.OutputStream({
beautify: true,
js_version: 5
});
ast.print(output);
console.log(output.get());
// Minified output
const minified = new RapydScript.OutputStream({
beautify: false,
semicolons: true
});
ast.print(minified);
console.log(minified.get());
// ES6 output with preserved docstrings
const es6Output = new RapydScript.OutputStream({
beautify: true,
js_version: 6,
keep_docstrings: true,
private_scope: false
});Advanced configuration for controlling JavaScript output characteristics.
/**
* JavaScript version-specific features
*/
interface JSVersionFeatures {
/** Use ES6 arrow functions */
arrow_functions: boolean;
/** Use ES6 template literals */
template_literals: boolean;
/** Use ES6 const/let declarations */
block_scoped_vars: boolean;
/** Use ES6 for...of loops */
for_of_loops: boolean;
/** Use ES6 destructuring */
destructuring: boolean;
/** Use ES6 classes */
native_classes: boolean;
/** Use ES6 generators */
native_generators: boolean;
/** Use ES6 iterators */
native_iterators: boolean;
}
/**
* Comment preservation strategies
*/
interface CommentOptions {
/** Preserve all comments */
all?: boolean;
/** Preserve license/copyright comments */
license?: boolean;
/** Custom filter function */
filter?: (comment: AST_Token, type: string) => boolean;
}Control how Python runtime functions are included in the output.
/**
* Base library inclusion options
*/
interface BaseLibOptions {
/** Include complete base library */
complete?: boolean;
/** Include only used functions */
minimal?: boolean;
/** External base library reference */
external?: string;
/** Inline base library functions */
inline?: boolean;
}
/**
* Python built-in functions available in base library
*/
interface PythonBuiltins {
// Type conversion
int: (value: any, base?: number) => number;
float: (value: any) => number;
bool: (value: any) => boolean;
str: (value: any) => string;
// Container functions
len: (obj: any) => number;
range: (start: number, stop?: number, step?: number) => Iterator;
enumerate: (iterable: any, start?: number) => Iterator;
zip: (...iterables: any[]) => Iterator;
// Higher-order functions
map: (func: Function, ...iterables: any[]) => Iterator;
filter: (func: Function, iterable: any) => Iterator;
sorted: (iterable: any, key?: Function, reverse?: boolean) => any[];
// Object introspection
isinstance: (obj: any, class_or_tuple: any) => boolean;
hasattr: (obj: any, name: string) => boolean;
getattr: (obj: any, name: string, default?: any) => any;
setattr: (obj: any, name: string, value: any) => void;
}Control how RapydScript's module system is compiled to JavaScript.
/**
* Module output options
*/
interface ModuleOptions {
/** Module system format */
format?: 'commonjs' | 'amd' | 'umd' | 'iife' | 'es6';
/** External dependencies */
externals?: {[name: string]: string};
/** Module name for UMD/IIFE formats */
name?: string;
/** Global variable mapping */
globals?: {[name: string]: string};
}
/**
* Import resolution configuration
*/
interface ImportOptions {
/** Import search paths */
paths?: string[];
/** Module aliases */
alias?: {[name: string]: string};
/** File extensions to try */
extensions?: string[];
/** Main file names to try */
main_files?: string[];
}The complete output generation workflow with all available options.
/**
* Complete output generation workflow
*/
function generateJavaScript(
sourceCode: string,
options: CompilationOptions
): CompilationResult;
interface CompilationOptions extends ParseOptions, OutputOptions {
/** Source filename */
filename?: string;
/** Include source maps */
source_map?: boolean;
/** Source map options */
source_map_options?: SourceMapOptions;
/** Optimization level */
optimize?: number;
/** Dead code elimination */
dead_code?: boolean;
/** Variable renaming/mangling */
mangle?: boolean;
}
interface CompilationResult {
/** Generated JavaScript code */
code: string;
/** Source map (if requested) */
map?: string;
/** Compilation warnings */
warnings: Warning[];
/** Import dependencies */
dependencies: string[];
/** Generated AST */
ast: AST_Toplevel;
}
interface SourceMapOptions {
/** Source map filename */
filename?: string;
/** Include sources content */
include_sources?: boolean;
/** Source root URL */
source_root?: string;
}Specialized output generation for specific use cases.
/**
* Conditional compilation support
*/
interface ConditionalOptions {
/** Compile-time constants */
defines?: {[name: string]: any};
/** Feature flags */
features?: string[];
/** Debug mode */
debug?: boolean;
/** Production mode optimizations */
production?: boolean;
}
/**
* Runtime profiling and debugging
*/
interface DebuggingOptions {
/** Include runtime profiling hooks */
profile?: boolean;
/** Include debugging information */
debug_info?: boolean;
/** Line number preservation */
line_numbers?: boolean;
/** Function name preservation */
function_names?: boolean;
}Complete Compilation Workflow:
const { create_compiler } = require("rapydscript-ng");
const RapydScript = create_compiler();
// Advanced compilation with all options
function compileRapydScript(sourceCode, filename) {
try {
// Parse with full options
const ast = RapydScript.parse(sourceCode, {
filename: filename,
basedir: path.dirname(filename),
libdir: '/usr/local/lib/rapydscript/lib',
import_dirs: ['./modules', './vendor'],
discard_asserts: process.env.NODE_ENV === 'production'
});
// Generate optimized output
const output = new RapydScript.OutputStream({
beautify: process.env.NODE_ENV !== 'production',
private_scope: true,
js_version: 6,
keep_docstrings: process.env.NODE_ENV !== 'production',
discard_asserts: process.env.NODE_ENV === 'production',
comments: process.env.NODE_ENV !== 'production',
semicolons: true,
beautify_options: {
indent_level: 2,
max_line_len: 120,
space_colon: true
}
});
ast.print(output);
return {
code: output.get(),
ast: ast,
success: true
};
} catch (error) {
return {
error: error.message,
success: false
};
}
}Custom Output Formatting:
// Create custom output stream with specific formatting
const customOutput = new RapydScript.OutputStream({
beautify: true,
beautify_options: {
indent_level: 8, // 8-space indentation
quote_keys: true, // Always quote object keys
space_colon: false, // No space after colons
ascii_only: true, // ASCII-only output
max_line_len: 80 // 80-character line limit
},
comments: function(node, comment) {
// Only preserve comments containing 'TODO' or 'FIXME'
return /TODO|FIXME/i.test(comment.value);
}
});ES6-Specific Output:
// Generate modern ES6 JavaScript
const es6Output = new RapydScript.OutputStream({
js_version: 6,
beautify: true,
private_scope: false, // Use ES6 modules instead
beautify_options: {
indent_level: 2,
space_colon: true
}
});
// The output will use:
// - Arrow functions instead of function expressions
// - const/let instead of var
// - Template literals instead of string concatenation
// - Native classes instead of function constructors
// - for...of loops instead of array iterationInstall with Tessl CLI
npx tessl i tessl/npm-rapydscript-ng