Skip to content

Commit 0d39819

Browse files
committed
feat(extractor): add extract_with_context() for stateless extraction
Add sync methods to ExtractionContext for global state interop: - sync_to_globals(): push context state to global variables - sync_from_globals(): pull global state back to context - from_globals(): create context from current global state Add extract_with_context() function that wraps extract() with context synchronization, enabling stateless extraction for parallel processing (e.g., Turbopack multi-core builds). This is an incremental approach - internal modules still use global state, but the new API provides the foundation for future parallelization work.
1 parent 7d81726 commit 0d39819

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

libs/extractor/src/context.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,43 @@ impl ExtractionContext {
180180
}
181181
}
182182

183+
/// Synchronize context with global state (for incremental migration).
184+
///
185+
/// This allows using ExtractionContext while the codebase still uses global
186+
/// state internally. Once the full migration is complete, this can be removed.
187+
impl ExtractionContext {
188+
/// Populate global state from this context.
189+
///
190+
/// Call this before extraction to set up the global state.
191+
pub fn sync_to_globals(&self) {
192+
css::class_map::set_class_map(self.class_map.clone());
193+
css::file_map::set_file_map(self.file_map.clone());
194+
css::set_prefix(self.prefix.clone());
195+
css::debug::set_debug(self.debug);
196+
}
197+
198+
/// Populate this context from global state.
199+
///
200+
/// Call this after extraction to capture any state changes.
201+
pub fn sync_from_globals(&mut self) {
202+
self.class_map = css::class_map::get_class_map();
203+
self.file_map = css::file_map::get_file_map();
204+
self.prefix = css::get_prefix();
205+
self.debug = css::debug::is_debug();
206+
}
207+
208+
/// Create a context initialized from current global state.
209+
#[must_use]
210+
pub fn from_globals() -> Self {
211+
Self {
212+
class_map: css::class_map::get_class_map(),
213+
file_map: css::file_map::get_file_map(),
214+
prefix: css::get_prefix(),
215+
debug: css::debug::is_debug(),
216+
}
217+
}
218+
}
219+
183220
#[cfg(test)]
184221
mod tests {
185222
use super::*;

libs/extractor/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,50 @@ pub fn extract(
268268
})
269269
}
270270

271+
/// Extract styles from code using an explicit context instead of global state.
272+
///
273+
/// This function enables stateless extraction for parallel processing (e.g., Turbopack).
274+
/// It synchronizes the context with global state before extraction and captures any
275+
/// state changes afterward.
276+
///
277+
/// # Arguments
278+
///
279+
/// * `filename` - The source file path (used for file-specific class prefixes)
280+
/// * `code` - The source code to extract styles from
281+
/// * `option` - Extraction options (package name, CSS directory, etc.)
282+
/// * `ctx` - Mutable reference to the extraction context
283+
///
284+
/// # Example
285+
///
286+
/// ```rust,ignore
287+
/// use extractor::{ExtractionContext, extract_with_context, ExtractOption};
288+
///
289+
/// let mut ctx = ExtractionContext::new();
290+
/// let result = extract_with_context(
291+
/// "component.tsx",
292+
/// r#"import { Box } from '@devup-ui/react'; export default () => <Box bg="red" />"#,
293+
/// ExtractOption::default(),
294+
/// &mut ctx,
295+
/// )?;
296+
/// ```
297+
pub fn extract_with_context(
298+
filename: &str,
299+
code: &str,
300+
option: ExtractOption,
301+
ctx: &mut ExtractionContext,
302+
) -> Result<ExtractOutput, Box<dyn Error>> {
303+
// Sync context state to globals before extraction
304+
ctx.sync_to_globals();
305+
306+
// Perform extraction using existing implementation
307+
let result = extract(filename, code, option);
308+
309+
// Capture any state changes back to context
310+
ctx.sync_from_globals();
311+
312+
result
313+
}
314+
271315
/// Extract class names from generated code for specific style names
272316
/// Used for two-pass vanilla-extract processing to resolve selector references
273317
pub fn extract_class_map_from_code(

0 commit comments

Comments
 (0)