1#![recursion_limit = "2048"]
30#![feature(arbitrary_self_types)]
32#![feature(arbitrary_self_types_pointers)]
33
34#[macro_use]
35extern crate napi_derive;
36
37use std::sync::{Arc, Once};
38
39use napi::bindgen_prelude::*;
40use rustc_hash::{FxHashMap, FxHashSet};
41use swc_core::{
42 atoms::Atom,
43 base::{Compiler, TransformOutput},
44 common::{FilePathMapping, SourceMap},
45};
46#[cfg(not(target_arch = "wasm32"))]
47pub mod css;
48pub mod mdx;
49pub mod minify;
50#[cfg(not(target_arch = "wasm32"))]
51pub mod next_api;
52pub mod parse;
53pub mod react_compiler;
54pub mod rspack;
55pub mod transform;
56#[cfg(not(target_arch = "wasm32"))]
57pub mod turbo_trace_server;
58#[cfg(not(target_arch = "wasm32"))]
59pub mod turbopack;
60pub mod util;
61
62#[cfg(not(any(feature = "__internal_dhat-heap", feature = "__internal_dhat-ad-hoc")))]
63#[global_allocator]
64static ALLOC: turbo_tasks_malloc::TurboMalloc = turbo_tasks_malloc::TurboMalloc;
65
66#[cfg(feature = "__internal_dhat-heap")]
67#[global_allocator]
68static ALLOC: dhat::Alloc = dhat::Alloc;
69
70#[cfg(not(target_arch = "wasm32"))]
71#[napi::module_init]
72fn init() {
73 use std::{
74 cell::RefCell,
75 panic::{set_hook, take_hook},
76 thread::available_parallelism,
77 time::{Duration, Instant},
78 };
79
80 thread_local! {
81 static LAST_SWC_ATOM_GC_TIME: RefCell<Option<Instant>> = const { RefCell::new(None) };
82 }
83
84 use tokio::runtime::Builder;
85 use turbo_tasks::panic_hooks::handle_panic;
86 use turbo_tasks_malloc::TurboMalloc;
87
88 let prev_hook = take_hook();
89 set_hook(Box::new(move |info| {
90 handle_panic(info);
91 prev_hook(info);
92 }));
93
94 let worker_threads = available_parallelism().map(|n| n.get()).unwrap_or(1);
95
96 let rt = Builder::new_multi_thread()
97 .enable_all()
98 .on_thread_stop(|| {
99 TurboMalloc::thread_stop();
100 })
101 .on_thread_park(|| {
102 LAST_SWC_ATOM_GC_TIME.with_borrow_mut(|cell| {
103 if cell.is_none_or(|t| t.elapsed() > Duration::from_secs(2)) {
104 swc_core::ecma::atoms::hstr::global_atom_store_gc();
105 *cell = Some(Instant::now());
106 }
107 });
108 })
109 .worker_threads(worker_threads)
110 .max_blocking_threads(usize::MAX - worker_threads)
112 .disable_lifo_slot()
114 .build()
115 .unwrap();
116 create_custom_tokio_runtime(rt);
117}
118
119#[inline]
120fn get_compiler() -> Compiler {
121 let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
122
123 Compiler::new(cm)
124}
125
126pub fn complete_output(
127 env: &Env,
128 output: TransformOutput,
129 eliminated_packages: FxHashSet<Atom>,
130 use_cache_telemetry_tracker: FxHashMap<String, usize>,
131) -> napi::Result<Object> {
132 let mut js_output = env.create_object()?;
133 js_output.set_named_property("code", env.create_string_from_std(output.code)?)?;
134 if let Some(map) = output.map {
135 js_output.set_named_property("map", env.create_string_from_std(map)?)?;
136 }
137 if !eliminated_packages.is_empty() {
138 js_output.set_named_property(
139 "eliminatedPackages",
140 env.create_string_from_std(serde_json::to_string(&eliminated_packages)?)?,
141 )?;
142 }
143 if !use_cache_telemetry_tracker.is_empty() {
144 js_output.set_named_property(
145 "useCacheTelemetryTracker",
146 env.create_string_from_std(serde_json::to_string(
147 &use_cache_telemetry_tracker
148 .iter()
149 .map(|(k, v)| (k.clone(), *v))
150 .collect::<Vec<_>>(),
151 )?)?,
152 )?;
153 }
154
155 Ok(js_output)
156}
157
158static REGISTER_ONCE: Once = Once::new();
159
160#[cfg(not(target_arch = "wasm32"))]
161fn register() {
162 REGISTER_ONCE.call_once(|| {
163 ::next_api::register();
164 next_core::register();
165 include!(concat!(env!("OUT_DIR"), "/register.rs"));
166 });
167}
168
169#[cfg(target_arch = "wasm32")]
170fn register() {
171 }