@griffel/transform 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Change Log - @griffel/transform
2
+
3
+ This log was last generated on Mon, 03 Nov 2025 15:42:47 GMT and should not be manually modified.
4
+
5
+ <!-- Start content -->
6
+
7
+ ## 1.1.0
8
+
9
+ Mon, 03 Nov 2025 15:42:47 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Add initial @griffel/transform package boilerplate (copilot@github.com)
14
+ - feat: add functionality (copilot@github.com)
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @griffel/transform
2
+
3
+ A high-performance transformation package for Griffel that unifies CSS-in-JS transformation and extraction functionality.
4
+
5
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
6
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
7
+
8
+ - [Overview](#overview)
9
+ - [Features](#features)
10
+ - [Install](#install)
11
+ - [Usage](#usage)
12
+ - [Basic Transformation](#basic-transformation)
13
+ - [API Reference](#api-reference)
14
+ - [transformSync(sourceCode, options)](#transformsyncsourcecode-options)
15
+
16
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
17
+
18
+ ## Overview
19
+
20
+ `@griffel/transform` provides a unified approach to CSS-in-JS transformation and extraction for Griffel. It replaces Babel-based processing with modern OXC-based parsing for improved performance while maintaining full compatibility with existing Griffel APIs.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ yarn add --dev @griffel/transform
26
+ # or
27
+ npm install --save-dev @griffel/transform
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Basic Transformation
33
+
34
+ ```typescript
35
+ import { transformSync } from '@griffel/transform';
36
+
37
+ const sourceCode = `
38
+ import { makeStyles } from '@griffel/react';
39
+
40
+ const useStyles = makeStyles({
41
+ root: { color: 'red' }
42
+ });
43
+ `;
44
+
45
+ const result = transformSync(sourceCode, {
46
+ filename: 'styles.ts',
47
+ });
48
+
49
+ console.log(result.code); // Transformed code with __css calls
50
+ console.log(result.cssRulesByBucket); // Extracted CSS rules
51
+ ```
52
+
53
+ ## API Reference
54
+
55
+ ### transformSync(sourceCode, options)
56
+
57
+ Transforms source code containing `makeStyles` or `makeResetStyles` calls.
58
+
59
+ **Parameters:**
60
+
61
+ - `sourceCode` (string): Source code to transform
62
+ - `options` (TransformOptions): Transformation options
63
+
64
+ **Returns:** `TransformResult` object containing:
65
+
66
+ - `code`: Transformed source code
67
+ - `cssRulesByBucket`: Extracted CSS rules organized by bucket type
68
+ - `usedProcessing`: Whether any transformations were applied
69
+ - `usedVMForEvaluation`: Whether VM evaluation was used
70
+
71
+ **TransformOptions:**
72
+
73
+ - `filename` (string): File path for error reporting and source maps
74
+ - `classNameHashSalt?` (string): Salt for CSS class name generation
75
+ - `generateMetadata?` (boolean): Include metadata in CSS rules
76
+ - `modules?` (string[]): Module sources to process
77
+ - `babelOptions?` (object): Babel configuration for complex evaluations
78
+ - `evaluationRules?` (array): Rules for determining evaluation strategy
@@ -0,0 +1,12 @@
1
+ import { Node } from 'oxc-parser';
2
+ import { EvaluationResult } from './types.mjs';
3
+ /**
4
+ * Simple static evaluator for object expressions with nested objects.
5
+ * Based on Babel's evaluation approach but simplified for our specific use case.
6
+ *
7
+ * Handles:
8
+ * - Objects with nested objects: { root: { color: 'red', padding: 0 } }
9
+ * - String literals, numeric literals, boolean literals, null
10
+ * - Simple property access
11
+ */
12
+ export declare function astEvaluator(node: Node): EvaluationResult;
@@ -0,0 +1,11 @@
1
+ import { StrictOptions } from '@linaria/babel-preset';
2
+ import { StyleCall } from '../types.mjs';
3
+ /**
4
+ * Batch evaluates all style calls in a file for better performance.
5
+ * Uses static evaluation first, then falls back to VM evaluation for complex expressions.
6
+ * Optimizes VM evaluation by sharing module loading and parsing overhead.
7
+ */
8
+ export declare function batchEvaluator(sourceCode: string, filename: string, styleCalls: StyleCall[], babelOptions: NonNullable<StrictOptions['babelOptions']>, evaluationRules: NonNullable<StrictOptions['rules']>): {
9
+ usedVMForEvaluation: boolean;
10
+ evaluationResults: unknown[];
11
+ };
@@ -0,0 +1,5 @@
1
+ export interface EvaluationResult {
2
+ confident: boolean;
3
+ value?: unknown;
4
+ error?: Error;
5
+ }
@@ -0,0 +1,3 @@
1
+ import { StrictOptions } from '@linaria/babel-preset';
2
+ import { EvaluationResult } from './types.mjs';
3
+ export declare function vmEvaluator(sourceCode: string, filename: string, expressionCode: string, babelOptions: NonNullable<StrictOptions['babelOptions']>, evaluationRules: NonNullable<StrictOptions['rules']>): EvaluationResult;
package/index.d.mts ADDED
@@ -0,0 +1,4 @@
1
+ export { default as shakerEvaluator } from '@linaria/shaker';
2
+ export { EvalCache, Module } from '@linaria/babel-preset';
3
+ export type { Evaluator, EvalRule } from '@linaria/babel-preset';
4
+ export { transformSync, type TransformOptions, type TransformResult } from './transformSync.mjs';
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@griffel/transform",
3
+ "version": "1.1.0",
4
+ "description": "A package that performs build time transforms for Griffel",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/microsoft/griffel"
9
+ },
10
+ "type": "module",
11
+ "exports": {
12
+ ".": {
13
+ "node": "./transform.js",
14
+ "types": "./index.d.mts"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "dependencies": {
19
+ "@griffel/core": "^1.19.2",
20
+ "@linaria/babel-preset": "^3.0.0-beta.24",
21
+ "@linaria/shaker": "^3.0.0-beta.22",
22
+ "magic-string": "^0.30.19",
23
+ "oxc-parser": "^0.90.0",
24
+ "oxc-walker": "^0.5.2"
25
+ }
26
+ }
package/transform.js ADDED
@@ -0,0 +1,428 @@
1
+ import _shaker from "@linaria/shaker";
2
+ import { default as default2 } from "@linaria/shaker";
3
+ import { Module } from "@linaria/babel-preset";
4
+ import { EvalCache, Module as Module2 } from "@linaria/babel-preset";
5
+ import { parseSync } from "oxc-parser";
6
+ import { walk } from "oxc-walker";
7
+ import MagicString from "magic-string";
8
+ import { resolveResetStyleRules, resolveStyleRulesForSlots, normalizeCSSBucketEntry } from "@griffel/core";
9
+ class DeoptError extends Error {
10
+ }
11
+ function evaluateNode(node) {
12
+ switch (node.type) {
13
+ case "Literal":
14
+ return node.value;
15
+ case "ObjectExpression":
16
+ return evaluateObjectExpression(node);
17
+ case "TemplateLiteral":
18
+ return evaluateTemplateLiteral(node);
19
+ case "MemberExpression":
20
+ return evaluateMemberExpression(node);
21
+ default:
22
+ throw new DeoptError(`Unsupported node type: ${node.type}`);
23
+ }
24
+ }
25
+ function evaluateObjectExpression(node) {
26
+ const obj = {};
27
+ for (const prop of node.properties) {
28
+ if (prop.type !== "Property" || prop.kind !== "init") {
29
+ throw new DeoptError("Only standard properties are supported");
30
+ }
31
+ let key;
32
+ if (prop.computed) {
33
+ throw new DeoptError("Computed properties are not supported");
34
+ } else if (prop.key.type === "Identifier") {
35
+ key = prop.key.name;
36
+ } else if (prop.key.type === "Literal") {
37
+ const keyLiteral = prop.key;
38
+ if (typeof keyLiteral.value === "string" || typeof keyLiteral.value === "number") {
39
+ key = String(keyLiteral.value);
40
+ } else {
41
+ throw new DeoptError("Unsupported literal key type");
42
+ }
43
+ } else {
44
+ throw new DeoptError("Unsupported key type");
45
+ }
46
+ obj[key] = evaluateNode(prop.value);
47
+ }
48
+ return obj;
49
+ }
50
+ function evaluateTemplateLiteral(node) {
51
+ let result = "";
52
+ for (let i = 0; i < node.quasis.length; i++) {
53
+ result += node.quasis[i].value.cooked;
54
+ if (i < node.expressions.length) {
55
+ const expression = node.expressions[i];
56
+ if (expression.type === "MemberExpression" && expression.object.type === "Identifier" && expression.object.name === "tokens" && expression.property.type === "Identifier" && !expression.computed) {
57
+ result += `var(--${expression.property.name})`;
58
+ } else {
59
+ throw new DeoptError("Only tokens.propertyName expressions are supported in template literals");
60
+ }
61
+ }
62
+ }
63
+ return result;
64
+ }
65
+ function evaluateMemberExpression(node) {
66
+ if (node.object.type === "Identifier" && node.object.name === "tokens" && node.property.type === "Identifier" && !node.computed) {
67
+ return `var(--${node.property.name})`;
68
+ } else {
69
+ throw new DeoptError("Only tokens.propertyName member expressions are supported");
70
+ }
71
+ }
72
+ function astEvaluator(node) {
73
+ try {
74
+ return {
75
+ confident: true,
76
+ value: evaluateNode(node)
77
+ };
78
+ } catch {
79
+ return {
80
+ confident: false,
81
+ value: void 0
82
+ };
83
+ }
84
+ }
85
+ function isError(e) {
86
+ return Object.prototype.toString.call(e) === "[object Error]";
87
+ }
88
+ function vmEvaluator(sourceCode, filename, expressionCode, babelOptions, evaluationRules) {
89
+ const codeForEvaluation = `
90
+ ${sourceCode}
91
+
92
+ const __mkPreval = (() => {
93
+ try {
94
+ return ([${expressionCode}]);
95
+ } catch (e) {
96
+ return e;
97
+ }
98
+ })();
99
+
100
+ if (typeof module !== 'undefined' && module.exports) {
101
+ module.exports = { __mkPreval };
102
+ }
103
+ `;
104
+ try {
105
+ const options = {
106
+ displayName: false,
107
+ evaluate: true,
108
+ rules: evaluationRules,
109
+ babelOptions: {
110
+ ...babelOptions,
111
+ configFile: false,
112
+ babelrc: false
113
+ }
114
+ };
115
+ const mod = new Module(filename, options);
116
+ mod.evaluate(codeForEvaluation, ["__mkPreval"]);
117
+ const result = mod.exports.__mkPreval;
118
+ if (isError(result)) {
119
+ return { confident: false, error: result };
120
+ }
121
+ return { confident: true, value: result };
122
+ } catch (err) {
123
+ return { confident: false, error: err };
124
+ }
125
+ }
126
+ function batchEvaluator(sourceCode, filename, styleCalls, babelOptions, evaluationRules) {
127
+ const evaluationResults = new Array(styleCalls.length);
128
+ const argumentsCode = new Array(styleCalls.length).fill(null);
129
+ let vmEvaluationNeeded = false;
130
+ for (let i = 0; i < styleCalls.length; i++) {
131
+ const styleCall = styleCalls[i];
132
+ const staticResult = astEvaluator(styleCall.argumentNode);
133
+ if (staticResult.confident) {
134
+ evaluationResults[i] = staticResult.value;
135
+ continue;
136
+ }
137
+ vmEvaluationNeeded = true;
138
+ argumentsCode[i] = styleCall.argumentCode;
139
+ }
140
+ if (!vmEvaluationNeeded) {
141
+ return {
142
+ usedVMForEvaluation: false,
143
+ evaluationResults
144
+ };
145
+ }
146
+ const vmResult = vmEvaluator(sourceCode, filename, argumentsCode.join(","), babelOptions, evaluationRules);
147
+ if (!vmResult.confident) {
148
+ if (vmResult.error) {
149
+ throw vmResult.error;
150
+ } else {
151
+ throw new Error("Evaluation of a code fragment failed, this is a bug, please report it");
152
+ }
153
+ }
154
+ const vmValues = vmResult.value;
155
+ for (let i = 0; i < vmValues.length; i++) {
156
+ if (vmValues[i] === null) {
157
+ continue;
158
+ }
159
+ evaluationResults[i] = vmValues[i];
160
+ }
161
+ return {
162
+ usedVMForEvaluation: true,
163
+ evaluationResults
164
+ };
165
+ }
166
+ function dedupeCSSRules(cssRulesByBucket) {
167
+ return Object.fromEntries(
168
+ Object.entries(cssRulesByBucket).map(([styleBucketName, cssBucketEntries]) => {
169
+ if (styleBucketName === "m") {
170
+ return [
171
+ styleBucketName,
172
+ cssBucketEntries.filter(
173
+ (entryA, index, entries) => entries.findIndex((entryB) => entryA[0] === entryB[0]) === index
174
+ )
175
+ ];
176
+ }
177
+ return [styleBucketName, [...new Set(cssBucketEntries)]];
178
+ })
179
+ );
180
+ }
181
+ const shakerEvaluator = _shaker.default || _shaker;
182
+ function buildCSSResetEntriesMetadata(cssResetEntries, cssRules, declaratorId) {
183
+ const cssRulesByBucket = Array.isArray(cssRules) ? { d: cssRules } : cssRules;
184
+ cssResetEntries[declaratorId] ??= [];
185
+ cssResetEntries[declaratorId] = Object.values(cssRulesByBucket).flatMap((bucketEntries) => {
186
+ return bucketEntries.map((bucketEntry) => {
187
+ if (Array.isArray(bucketEntry)) {
188
+ throw new Error(
189
+ `CSS rules in buckets for "makeResetStyles()" should not contain arrays, got: ${JSON.stringify(
190
+ bucketEntry
191
+ )})}`
192
+ );
193
+ }
194
+ return bucketEntry;
195
+ });
196
+ });
197
+ }
198
+ function buildCSSEntriesMetadata(cssEntries, classnamesMapping, cssRulesByBucket, declaratorId) {
199
+ const classesBySlot = Object.fromEntries(
200
+ Object.entries(classnamesMapping).map(([slot, cssClassesMap]) => {
201
+ const uniqueClasses = /* @__PURE__ */ new Set();
202
+ Object.values(cssClassesMap).forEach((cssClasses) => {
203
+ if (typeof cssClasses === "string") {
204
+ uniqueClasses.add(cssClasses);
205
+ } else if (Array.isArray(cssClasses)) {
206
+ cssClasses.forEach((cssClass) => uniqueClasses.add(cssClass));
207
+ }
208
+ });
209
+ return [slot, Array.from(uniqueClasses)];
210
+ })
211
+ );
212
+ const cssRules = Object.values(cssRulesByBucket).flatMap((cssRulesByBucket2) => {
213
+ return cssRulesByBucket2.map((bucketEntry) => {
214
+ const [cssRule] = normalizeCSSBucketEntry(bucketEntry);
215
+ return cssRule;
216
+ });
217
+ });
218
+ cssEntries[declaratorId] = Object.fromEntries(
219
+ Object.entries(classesBySlot).map(([slot, cssClasses]) => {
220
+ return [
221
+ slot,
222
+ cssClasses.map((cssClass) => {
223
+ return cssRules.find((rule) => rule.includes(cssClass));
224
+ })
225
+ ];
226
+ })
227
+ );
228
+ }
229
+ function concatCSSRulesByBucket(bucketA = {}, bucketB) {
230
+ Object.entries(bucketB).forEach(([cssBucketName, cssBucketEntries]) => {
231
+ bucketA[cssBucketName] = cssBucketEntries.concat(
232
+ bucketA[cssBucketName] || []
233
+ );
234
+ });
235
+ return bucketA;
236
+ }
237
+ function transformSync(sourceCode, options) {
238
+ const {
239
+ babelOptions = {},
240
+ filename,
241
+ classNameHashSalt = "",
242
+ generateMetadata = false,
243
+ modules = ["@griffel/core", "@griffel/react", "@fluentui/react-components"],
244
+ evaluationRules = [
245
+ { action: shakerEvaluator },
246
+ {
247
+ test: /[/\\]node_modules[/\\]/,
248
+ action: "ignore"
249
+ }
250
+ ]
251
+ } = options;
252
+ if (!filename) {
253
+ throw new Error('Transform error: "filename" option is required');
254
+ }
255
+ const parseResult = parseSync(filename, sourceCode);
256
+ parseResult.module.staticImports;
257
+ if (parseResult.errors.length > 0) {
258
+ throw new Error(`Failed to parse "${filename}": ${parseResult.errors.map((e) => e.message).join(", ")}`);
259
+ }
260
+ const magicString = new MagicString(sourceCode);
261
+ const programAst = parseResult.program;
262
+ const imports = [];
263
+ const styleCalls = [];
264
+ const cssEntries = {};
265
+ const cssResetEntries = {};
266
+ let cssRulesByBucket = {};
267
+ walk(programAst, {
268
+ enter(node, parent) {
269
+ if (node.type === "ImportDeclaration") {
270
+ const moduleSource = node.source.value;
271
+ if (modules.includes(moduleSource)) {
272
+ const specifiers = node.specifiers.reduce((acc, spec) => {
273
+ if (spec.type === "ImportSpecifier") {
274
+ const importedName = spec.imported;
275
+ if (importedName.type === "Identifier" && (importedName.name === "makeStyles" || importedName.name === "makeResetStyles")) {
276
+ acc.push({
277
+ imported: importedName.name,
278
+ local: spec.local.name,
279
+ start: spec.start,
280
+ end: spec.end
281
+ });
282
+ }
283
+ }
284
+ return acc;
285
+ }, []);
286
+ if (specifiers.length > 0) {
287
+ imports.push({
288
+ source: moduleSource,
289
+ specifiers,
290
+ start: node.start,
291
+ end: node.end
292
+ });
293
+ }
294
+ }
295
+ }
296
+ if (node.type === "CallExpression") {
297
+ let functionKind = null;
298
+ let importId;
299
+ if (node.callee.type === "Identifier") {
300
+ const calleeName = node.callee.name;
301
+ for (const importInfo of imports) {
302
+ const specifier = importInfo.specifiers.find((s) => s.local === calleeName);
303
+ if (specifier) {
304
+ if (node.arguments.length !== 1) {
305
+ throw new Error(`${functionKind}() function accepts only a single param`);
306
+ }
307
+ functionKind = specifier.imported;
308
+ importId = specifier.local;
309
+ break;
310
+ }
311
+ }
312
+ }
313
+ if (functionKind && importId) {
314
+ let declaratorId = "unknownHook";
315
+ let current = parent;
316
+ while (current) {
317
+ if (!current) {
318
+ break;
319
+ }
320
+ if (current.type === "VariableDeclarator" && current.id.type === "Identifier") {
321
+ declaratorId = current.id.name;
322
+ break;
323
+ }
324
+ if ("parent" in current) {
325
+ current = current.parent;
326
+ continue;
327
+ }
328
+ break;
329
+ }
330
+ const argument = node.arguments[0];
331
+ styleCalls.push({
332
+ declaratorId,
333
+ functionKind,
334
+ argumentStart: argument.start,
335
+ argumentEnd: argument.end,
336
+ argumentCode: sourceCode.slice(argument.start, argument.end),
337
+ argumentNode: argument,
338
+ callStart: node.start,
339
+ callEnd: node.end,
340
+ importId
341
+ });
342
+ }
343
+ }
344
+ }
345
+ });
346
+ if (imports.length === 0 || styleCalls.length === 0) {
347
+ return {
348
+ code: sourceCode,
349
+ usedProcessing: false,
350
+ usedVMForEvaluation: false
351
+ };
352
+ }
353
+ const { evaluationResults, usedVMForEvaluation } = batchEvaluator(
354
+ sourceCode,
355
+ filename,
356
+ styleCalls,
357
+ babelOptions,
358
+ evaluationRules
359
+ );
360
+ for (let i = 0; i < styleCalls.length; i++) {
361
+ const styleCall = styleCalls[i];
362
+ const evaluationResult = evaluationResults[i];
363
+ switch (styleCall.functionKind) {
364
+ case "makeStyles":
365
+ {
366
+ const stylesBySlots = evaluationResult;
367
+ const [classnamesMapping, cssRulesByBucketA] = resolveStyleRulesForSlots(stylesBySlots, classNameHashSalt);
368
+ if (generateMetadata) {
369
+ buildCSSEntriesMetadata(
370
+ cssEntries,
371
+ classnamesMapping,
372
+ dedupeCSSRules(cssRulesByBucket),
373
+ styleCall.declaratorId
374
+ );
375
+ }
376
+ magicString.overwrite(styleCall.argumentStart, styleCall.argumentEnd, `${JSON.stringify(classnamesMapping)}`);
377
+ cssRulesByBucket = concatCSSRulesByBucket(cssRulesByBucket, cssRulesByBucketA);
378
+ }
379
+ break;
380
+ case "makeResetStyles":
381
+ {
382
+ const styles = evaluationResult;
383
+ const [ltrClassName, rtlClassName, cssRules] = resolveResetStyleRules(styles, classNameHashSalt);
384
+ if (generateMetadata) {
385
+ buildCSSResetEntriesMetadata(cssResetEntries, cssRules, styleCall.declaratorId);
386
+ }
387
+ magicString.overwrite(
388
+ styleCall.argumentStart,
389
+ styleCall.argumentEnd,
390
+ `${JSON.stringify(ltrClassName)}, ${JSON.stringify(rtlClassName)}`
391
+ );
392
+ cssRulesByBucket = concatCSSRulesByBucket(
393
+ cssRulesByBucket,
394
+ Array.isArray(cssRules) ? { r: cssRules } : cssRules
395
+ );
396
+ }
397
+ break;
398
+ }
399
+ }
400
+ for (const importInfo of imports) {
401
+ for (const specifier of importInfo.specifiers) {
402
+ if (specifier.imported === "makeStyles") {
403
+ magicString.overwrite(specifier.start, specifier.end, "__css");
404
+ } else if (specifier.imported === "makeResetStyles") {
405
+ magicString.overwrite(specifier.start, specifier.end, "__resetCSS");
406
+ }
407
+ }
408
+ }
409
+ for (const styleCall of styleCalls) {
410
+ magicString.overwrite(
411
+ styleCall.callStart,
412
+ styleCall.callStart + styleCall.importId.length,
413
+ "__" + (styleCall.functionKind === "makeStyles" ? "css" : "resetCSS")
414
+ );
415
+ }
416
+ return {
417
+ code: magicString.toString(),
418
+ cssRulesByBucket,
419
+ usedProcessing: true,
420
+ usedVMForEvaluation
421
+ };
422
+ }
423
+ export {
424
+ EvalCache,
425
+ Module2 as Module,
426
+ default2 as shakerEvaluator,
427
+ transformSync
428
+ };
@@ -0,0 +1,30 @@
1
+ import { StrictOptions } from '@linaria/babel-preset';
2
+ import { CSSRulesByBucket } from '@griffel/core';
3
+ export type TransformOptions = {
4
+ filename: string;
5
+ classNameHashSalt?: string;
6
+ /**
7
+ * Returns the evaluated CSS rules in the file result metadata
8
+ * @default false
9
+ */
10
+ generateMetadata?: boolean;
11
+ /** Defines set of modules and imports handled by a transformPlugin. */
12
+ modules?: string[];
13
+ /**
14
+ * If you need to specify custom Babel configuration, you can pass them here. These options will be used by the
15
+ * transformPlugin when parsing and evaluating modules.
16
+ */
17
+ babelOptions?: Pick<StrictOptions['babelOptions'], 'plugins' | 'presets'>;
18
+ /** The set of rules that defines how the matched files will be transformed during the evaluation. */
19
+ evaluationRules?: StrictOptions['rules'];
20
+ };
21
+ export type TransformResult = {
22
+ code: string;
23
+ cssRulesByBucket?: CSSRulesByBucket;
24
+ usedProcessing: boolean;
25
+ usedVMForEvaluation: boolean;
26
+ };
27
+ /**
28
+ * Transforms passed source code with oxc-parser and oxc-walker instead of Babel.
29
+ */
30
+ export declare function transformSync(sourceCode: string, options: TransformOptions): TransformResult;
package/types.d.mts ADDED
@@ -0,0 +1,12 @@
1
+ import { Node } from 'oxc-parser';
2
+ export interface StyleCall {
3
+ declaratorId: string;
4
+ functionKind: 'makeStyles' | 'makeResetStyles';
5
+ argumentStart: number;
6
+ argumentEnd: number;
7
+ argumentCode: string;
8
+ argumentNode: Node;
9
+ callStart: number;
10
+ callEnd: number;
11
+ importId: string;
12
+ }
@@ -0,0 +1,6 @@
1
+ import { CSSRulesByBucket } from '@griffel/core';
2
+ /**
3
+ * Rules that are returned by `resolveStyles()` are not deduplicated.
4
+ * It's critical to filter out duplicates for build-time transform to avoid duplicated rules in a bundle.
5
+ */
6
+ export declare function dedupeCSSRules(cssRulesByBucket: CSSRulesByBucket): CSSRulesByBucket;