@flairjs/webpack-loader 0.0.1-beta.1 → 0.0.1-beta.10

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/README.md CHANGED
@@ -0,0 +1,146 @@
1
+ # @flairjs/webpack-loader
2
+
3
+ Webpack loader for Flair CSS-in-JSX.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @flairjs/webpack-loader
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```js
14
+ // webpack.config.js
15
+ module.exports = {
16
+ module: {
17
+ rules: [
18
+ {
19
+ test: /\.(tsx|jsx)$/,
20
+ use: [
21
+ '@flairjs/webpack-loader'
22
+ ],
23
+ exclude: /node_modules/
24
+ }
25
+ ]
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## Configuration
31
+
32
+ ```js
33
+ // webpack.config.js
34
+ module.exports = {
35
+ module: {
36
+ rules: [
37
+ {
38
+ test: /\.(tsx|jsx)$/,
39
+ use: [
40
+ 'babel-loader',
41
+ {
42
+ loader: '@flairjs/webpack-loader',
43
+ options: {
44
+ // Configuration options
45
+ cssPreprocessor: (css, id) => {
46
+ // Custom CSS preprocessing
47
+ return css
48
+ },
49
+ include: ['src/**/*.{tsx,jsx}'],
50
+ exclude: ['**/*.test.{tsx,jsx}'],
51
+ classNameList: ["className", "class"]
52
+ }
53
+ },
54
+ ]
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Configuration Options
62
+
63
+ ```typescript
64
+ interface FlairJsWebpackLoaderOptions {
65
+ /**
66
+ * Preprocess the extracted CSS before it is passed to lightningcss
67
+ * @experimental
68
+ */
69
+ cssPreprocessor?: (css: string, id: string) => string
70
+
71
+ /**
72
+ * Files to include (default: all .tsx/.jsx files)
73
+ */
74
+ include?: string | string[]
75
+
76
+ /**
77
+ * Files to exclude (default: node_modules)
78
+ */
79
+ exclude?: string | string[]
80
+
81
+ /**
82
+ * Override the default theme file content
83
+ */
84
+ buildThemeFile?: (theme: FlairThemeConfig) => string
85
+
86
+ /**
87
+ * List of class names used in the project. Supports regex.
88
+ */
89
+ classNameList?: string[]
90
+ }
91
+ ```
92
+
93
+ ## CSS Handling
94
+
95
+ Ensure your webpack configuration can handle CSS files:
96
+
97
+ ```js
98
+ // webpack.config.js
99
+ module.exports = {
100
+ module: {
101
+ rules: [
102
+ // Flair loader
103
+ {
104
+ test: /\.(tsx|jsx)$/,
105
+ use: ['@flairjs/webpack-loader']
106
+ },
107
+ // CSS loader for generated styles
108
+ {
109
+ test: /\.css$/,
110
+ use: ['style-loader', 'css-loader']
111
+ }
112
+ ]
113
+ }
114
+ }
115
+ ```
116
+
117
+
118
+ ## Theme Integration
119
+
120
+ Create a `flair.theme.ts` in your project root:
121
+
122
+ ```typescript
123
+ // flair.theme.ts
124
+ import { defineConfig } from '@flairjs/client'
125
+
126
+ export default defineConfig({
127
+ tokens: {
128
+ colors: {
129
+ primary: '#3b82f6',
130
+ secondary: '#64748b'
131
+ }
132
+ }
133
+ })
134
+ ```
135
+
136
+ Import the theme in your entry file:
137
+
138
+ ```js
139
+ // src/index.js
140
+ import '@flairjs/client/theme.css'
141
+ import './App'
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT
package/dist/cjs/index.js CHANGED
@@ -71,8 +71,33 @@ function tokensToCSSVars(tokens, prefix = []) {
71
71
  }
72
72
  return css$1;
73
73
  }
74
+ var Store = class {
75
+ fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
76
+ lastThemeUpdate = Date.now();
77
+ userTheme = /* @__PURE__ */ new Map();
78
+ getUserTheme() {
79
+ return this.userTheme.get(this.lastThemeUpdate) ?? null;
80
+ }
81
+ setUserTheme(theme) {
82
+ this.userTheme.set(this.lastThemeUpdate, theme);
83
+ }
84
+ getLastThemeUpdate() {
85
+ return this.lastThemeUpdate;
86
+ }
87
+ setLastThemeUpdate(timestamp) {
88
+ this.lastThemeUpdate = timestamp;
89
+ }
90
+ setFileNameToGeneratedCssNameMap(fileName, generatedCssName) {
91
+ this.fileNameToGeneratedCssNameMap.set(fileName, generatedCssName);
92
+ }
93
+ getGeneratedCssName(fileName) {
94
+ return this.fileNameToGeneratedCssNameMap.get(fileName);
95
+ }
96
+ };
97
+ const store = new Store();
74
98
  const __dirname$1 = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
75
- const getUserTheme = async () => {
99
+ const getUserTheme = async (options) => {
100
+ if (store.getUserTheme() && !options?.ignoreCache) return store.getUserTheme();
76
101
  try {
77
102
  let userThemeFilePath = path.default.resolve(process.cwd(), "flair.theme.ts");
78
103
  if (!(0, fs.existsSync)(userThemeFilePath)) userThemeFilePath = path.default.resolve(process.cwd(), "flair.theme.js");
@@ -88,10 +113,17 @@ const getUserTheme = async () => {
88
113
  });
89
114
  const cacheBuster = Date.now();
90
115
  const userTheme = await import(`${(0, url.pathToFileURL)(outFile).href}?update=${cacheBuster}`);
91
- if (userTheme.default) return {
92
- theme: userTheme.default,
93
- originalPath: userThemeFilePath
94
- };
116
+ if (userTheme.default) {
117
+ store.setUserTheme({
118
+ theme: userTheme.default,
119
+ originalPath: userThemeFilePath
120
+ });
121
+ return {
122
+ theme: userTheme.default,
123
+ originalPath: userThemeFilePath
124
+ };
125
+ }
126
+ store.setUserTheme(null);
95
127
  return null;
96
128
  } catch (error) {
97
129
  console.error("Error loading user theme:", error);
@@ -99,57 +131,60 @@ const getUserTheme = async () => {
99
131
  }
100
132
  };
101
133
  const require$1 = node_module.default.createRequire(require("url").pathToFileURL(__filename).href);
102
- /**
103
- * Initialize the shared plugin context
104
- */
105
- async function initializeSharedContext(options = {}) {
106
- const { buildThemeFile } = options;
107
- const fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
134
+ const getGeneratedCssDir = () => {
108
135
  const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
109
- const flairGeneratedCssDir = node_path.default.resolve(flairThemeFile, "../generated-css");
110
- if (!(0, node_fs.existsSync)(flairGeneratedCssDir)) await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
111
- else {
112
- await (0, node_fs_promises.rm)(flairGeneratedCssDir, {
113
- recursive: true,
114
- force: true
115
- });
116
- await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
136
+ return node_path.default.resolve(flairThemeFile, "../generated-css");
137
+ };
138
+ const setupGeneratedCssDir = async (options) => {
139
+ const flairGeneratedCssDir = getGeneratedCssDir();
140
+ const { clearExisting = true } = options ?? {};
141
+ try {
142
+ if (!(0, node_fs.existsSync)(flairGeneratedCssDir)) await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
143
+ else if (clearExisting) {
144
+ await (0, node_fs_promises.rm)(flairGeneratedCssDir, {
145
+ recursive: true,
146
+ force: true
147
+ });
148
+ await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
149
+ }
150
+ } catch (err) {
151
+ if (err?.code === "EEXIST") return flairGeneratedCssDir;
152
+ else if ((0, node_fs.existsSync)(flairGeneratedCssDir)) return flairGeneratedCssDir;
153
+ console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
154
+ return null;
117
155
  }
156
+ return flairGeneratedCssDir;
157
+ };
158
+ const setupUserThemeFile = async ({ buildThemeFile, onThemeFileChange, deleteBeforeWrite = false }) => {
159
+ const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
118
160
  let userTheme = await getUserTheme();
119
161
  const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
120
162
  if (userTheme) {
121
163
  const themeCSS = buildThemeCSS(userTheme.theme);
164
+ store.setLastThemeUpdate(Date.now());
165
+ if (deleteBeforeWrite) await (0, node_fs_promises.rm)(flairThemeFile, { force: true });
122
166
  await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS, "utf-8");
123
167
  (0, node_fs.watch)(userTheme.originalPath, async () => {
124
168
  userTheme = await getUserTheme();
169
+ store.setLastThemeUpdate(Date.now());
125
170
  if (!userTheme) return;
126
171
  const themeCSS$1 = buildThemeCSS(userTheme.theme);
172
+ onThemeFileChange?.();
127
173
  await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS$1, "utf-8");
128
174
  });
129
175
  }
130
- const refreshCssFile = (filePath) => {
131
- if (fileNameToGeneratedCssNameMap.has(filePath)) {
132
- const previousGeneratedCssName = fileNameToGeneratedCssNameMap.get(filePath);
133
- setTimeout(() => {
134
- (0, node_fs_promises.rm)(node_path.default.join(flairGeneratedCssDir, previousGeneratedCssName));
135
- }, 2e3);
136
- }
137
- };
138
- return {
139
- flairThemeFile,
140
- flairGeneratedCssDir,
141
- userTheme,
142
- buildThemeCSS,
143
- refreshCssFile
144
- };
145
- }
176
+ return userTheme;
177
+ };
146
178
  function shouldProcessFile(id, include, exclude) {
147
- const isIncluded = (0, picomatch.default)(include || ["**/*.{js,ts,jsx,tsx}"]);
148
- const isExcluded = (0, picomatch.default)(exclude || ["node_modules/**"]);
149
- if (!isIncluded(id)) return false;
150
- if (isExcluded(id)) return false;
179
+ const isIncluded = (0, picomatch.default)(include ?? ["**/*.{js,ts,jsx,tsx}"]);
180
+ const isExcluded = (0, picomatch.default)(exclude ?? ["**/node_modules/**"]);
181
+ if (!isIncluded(normalizeFilePath(id))) return false;
182
+ if (isExcluded(normalizeFilePath(id))) return false;
151
183
  return true;
152
184
  }
185
+ function normalizeFilePath(filePath) {
186
+ return filePath.replace(/\\/g, "/");
187
+ }
153
188
  const colors = {
154
189
  reset: "\x1B[0m",
155
190
  fg: {
@@ -191,28 +226,50 @@ const transformCode = (code, filePath, options) => {
191
226
 
192
227
  //#endregion
193
228
  //#region src/index.ts
229
+ let initialized = false;
194
230
  async function flairJsLoader(source, sourceMap) {
195
231
  const callback = this.async();
232
+ const options = this.getOptions() || {};
196
233
  if (!callback) {
197
234
  console.error("@flairjs/webpack-loader requires async support");
198
235
  return;
199
236
  }
200
- const options = this.getOptions() || {};
201
- const context = await initializeSharedContext(options);
202
237
  const fileName = this.resourcePath;
203
238
  if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
239
+ let cssGeneratedDir = null;
240
+ let userTheme = null;
241
+ if (!initialized) {
242
+ cssGeneratedDir = await setupGeneratedCssDir();
243
+ userTheme = await setupUserThemeFile({
244
+ buildThemeFile: options.buildThemeFile,
245
+ deleteBeforeWrite: true
246
+ });
247
+ initialized = true;
248
+ } else {
249
+ cssGeneratedDir = getGeneratedCssDir();
250
+ userTheme = await getUserTheme();
251
+ }
252
+ if (!cssGeneratedDir) {
253
+ console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
254
+ return callback(null, source, sourceMap);
255
+ }
204
256
  try {
205
257
  const result = transformCode(source, fileName, {
206
- appendTimestampToCssFile: true,
258
+ appendTimestampToCssFile: false,
207
259
  classNameList: options?.classNameList,
208
260
  cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
209
- theme: context.userTheme?.theme,
210
- useTheme: !!context.userTheme,
211
- cssOutDir: context.flairGeneratedCssDir
261
+ theme: userTheme?.theme,
262
+ useTheme: !!userTheme,
263
+ cssOutDir: cssGeneratedDir
212
264
  });
213
265
  if (!result) return callback(null, source, sourceMap);
214
- if (result.generatedCssName) context.refreshCssFile(result.generatedCssName);
215
- callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
266
+ if (!result.generatedCssName) return callback(null, source, sourceMap);
267
+ this.addDependency(path.resolve(result.generatedCssName));
268
+ let resultSourcemap = null;
269
+ if (result.sourcemap) try {
270
+ resultSourcemap = JSON.parse(result.sourcemap);
271
+ } catch {}
272
+ callback(null, result.code, resultSourcemap ?? sourceMap);
216
273
  } catch (error) {
217
274
  console.error("[@flairjs/webpack-loader]", error);
218
275
  callback(error, source, sourceMap);
package/dist/esm/index.js CHANGED
@@ -5,6 +5,7 @@ import path, { dirname } from "node:path";
5
5
  import * as esbuild from "esbuild";
6
6
  import { existsSync as existsSync$1 } from "fs";
7
7
  import { fileURLToPath } from "node:url";
8
+ import * as path$2 from "path";
8
9
  import path$1 from "path";
9
10
  import { pathToFileURL } from "url";
10
11
  import picomatch from "picomatch";
@@ -37,8 +38,33 @@ function tokensToCSSVars(tokens, prefix = []) {
37
38
  }
38
39
  return css$1;
39
40
  }
41
+ var Store = class {
42
+ fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
43
+ lastThemeUpdate = Date.now();
44
+ userTheme = /* @__PURE__ */ new Map();
45
+ getUserTheme() {
46
+ return this.userTheme.get(this.lastThemeUpdate) ?? null;
47
+ }
48
+ setUserTheme(theme) {
49
+ this.userTheme.set(this.lastThemeUpdate, theme);
50
+ }
51
+ getLastThemeUpdate() {
52
+ return this.lastThemeUpdate;
53
+ }
54
+ setLastThemeUpdate(timestamp) {
55
+ this.lastThemeUpdate = timestamp;
56
+ }
57
+ setFileNameToGeneratedCssNameMap(fileName, generatedCssName) {
58
+ this.fileNameToGeneratedCssNameMap.set(fileName, generatedCssName);
59
+ }
60
+ getGeneratedCssName(fileName) {
61
+ return this.fileNameToGeneratedCssNameMap.get(fileName);
62
+ }
63
+ };
64
+ const store = new Store();
40
65
  const __dirname = dirname(fileURLToPath(import.meta.url));
41
- const getUserTheme = async () => {
66
+ const getUserTheme = async (options) => {
67
+ if (store.getUserTheme() && !options?.ignoreCache) return store.getUserTheme();
42
68
  try {
43
69
  let userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.ts");
44
70
  if (!existsSync$1(userThemeFilePath)) userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.js");
@@ -54,10 +80,17 @@ const getUserTheme = async () => {
54
80
  });
55
81
  const cacheBuster = Date.now();
56
82
  const userTheme = await import(`${pathToFileURL(outFile).href}?update=${cacheBuster}`);
57
- if (userTheme.default) return {
58
- theme: userTheme.default,
59
- originalPath: userThemeFilePath
60
- };
83
+ if (userTheme.default) {
84
+ store.setUserTheme({
85
+ theme: userTheme.default,
86
+ originalPath: userThemeFilePath
87
+ });
88
+ return {
89
+ theme: userTheme.default,
90
+ originalPath: userThemeFilePath
91
+ };
92
+ }
93
+ store.setUserTheme(null);
61
94
  return null;
62
95
  } catch (error) {
63
96
  console.error("Error loading user theme:", error);
@@ -65,57 +98,60 @@ const getUserTheme = async () => {
65
98
  }
66
99
  };
67
100
  const require = module.createRequire(import.meta.url);
68
- /**
69
- * Initialize the shared plugin context
70
- */
71
- async function initializeSharedContext(options = {}) {
72
- const { buildThemeFile } = options;
73
- const fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
101
+ const getGeneratedCssDir = () => {
74
102
  const flairThemeFile = require.resolve("@flairjs/client/theme.css");
75
- const flairGeneratedCssDir = path.resolve(flairThemeFile, "../generated-css");
76
- if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
77
- else {
78
- await rm(flairGeneratedCssDir, {
79
- recursive: true,
80
- force: true
81
- });
82
- await mkdir(flairGeneratedCssDir);
103
+ return path.resolve(flairThemeFile, "../generated-css");
104
+ };
105
+ const setupGeneratedCssDir = async (options) => {
106
+ const flairGeneratedCssDir = getGeneratedCssDir();
107
+ const { clearExisting = true } = options ?? {};
108
+ try {
109
+ if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
110
+ else if (clearExisting) {
111
+ await rm(flairGeneratedCssDir, {
112
+ recursive: true,
113
+ force: true
114
+ });
115
+ await mkdir(flairGeneratedCssDir);
116
+ }
117
+ } catch (err) {
118
+ if (err?.code === "EEXIST") return flairGeneratedCssDir;
119
+ else if (existsSync(flairGeneratedCssDir)) return flairGeneratedCssDir;
120
+ console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
121
+ return null;
83
122
  }
123
+ return flairGeneratedCssDir;
124
+ };
125
+ const setupUserThemeFile = async ({ buildThemeFile, onThemeFileChange, deleteBeforeWrite = false }) => {
126
+ const flairThemeFile = require.resolve("@flairjs/client/theme.css");
84
127
  let userTheme = await getUserTheme();
85
128
  const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
86
129
  if (userTheme) {
87
130
  const themeCSS = buildThemeCSS(userTheme.theme);
131
+ store.setLastThemeUpdate(Date.now());
132
+ if (deleteBeforeWrite) await rm(flairThemeFile, { force: true });
88
133
  await writeFile(flairThemeFile, themeCSS, "utf-8");
89
134
  watch(userTheme.originalPath, async () => {
90
135
  userTheme = await getUserTheme();
136
+ store.setLastThemeUpdate(Date.now());
91
137
  if (!userTheme) return;
92
138
  const themeCSS$1 = buildThemeCSS(userTheme.theme);
139
+ onThemeFileChange?.();
93
140
  await writeFile(flairThemeFile, themeCSS$1, "utf-8");
94
141
  });
95
142
  }
96
- const refreshCssFile = (filePath) => {
97
- if (fileNameToGeneratedCssNameMap.has(filePath)) {
98
- const previousGeneratedCssName = fileNameToGeneratedCssNameMap.get(filePath);
99
- setTimeout(() => {
100
- rm(path.join(flairGeneratedCssDir, previousGeneratedCssName));
101
- }, 2e3);
102
- }
103
- };
104
- return {
105
- flairThemeFile,
106
- flairGeneratedCssDir,
107
- userTheme,
108
- buildThemeCSS,
109
- refreshCssFile
110
- };
111
- }
143
+ return userTheme;
144
+ };
112
145
  function shouldProcessFile(id, include, exclude) {
113
- const isIncluded = picomatch(include || ["**/*.{js,ts,jsx,tsx}"]);
114
- const isExcluded = picomatch(exclude || ["node_modules/**"]);
115
- if (!isIncluded(id)) return false;
116
- if (isExcluded(id)) return false;
146
+ const isIncluded = picomatch(include ?? ["**/*.{js,ts,jsx,tsx}"]);
147
+ const isExcluded = picomatch(exclude ?? ["**/node_modules/**"]);
148
+ if (!isIncluded(normalizeFilePath(id))) return false;
149
+ if (isExcluded(normalizeFilePath(id))) return false;
117
150
  return true;
118
151
  }
152
+ function normalizeFilePath(filePath) {
153
+ return filePath.replace(/\\/g, "/");
154
+ }
119
155
  const colors = {
120
156
  reset: "\x1B[0m",
121
157
  fg: {
@@ -157,28 +193,50 @@ const transformCode$1 = (code, filePath, options) => {
157
193
 
158
194
  //#endregion
159
195
  //#region src/index.ts
196
+ let initialized = false;
160
197
  async function flairJsLoader(source, sourceMap) {
161
198
  const callback = this.async();
199
+ const options = this.getOptions() || {};
162
200
  if (!callback) {
163
201
  console.error("@flairjs/webpack-loader requires async support");
164
202
  return;
165
203
  }
166
- const options = this.getOptions() || {};
167
- const context = await initializeSharedContext(options);
168
204
  const fileName = this.resourcePath;
169
205
  if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
206
+ let cssGeneratedDir = null;
207
+ let userTheme = null;
208
+ if (!initialized) {
209
+ cssGeneratedDir = await setupGeneratedCssDir();
210
+ userTheme = await setupUserThemeFile({
211
+ buildThemeFile: options.buildThemeFile,
212
+ deleteBeforeWrite: true
213
+ });
214
+ initialized = true;
215
+ } else {
216
+ cssGeneratedDir = getGeneratedCssDir();
217
+ userTheme = await getUserTheme();
218
+ }
219
+ if (!cssGeneratedDir) {
220
+ console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
221
+ return callback(null, source, sourceMap);
222
+ }
170
223
  try {
171
224
  const result = transformCode$1(source, fileName, {
172
- appendTimestampToCssFile: true,
225
+ appendTimestampToCssFile: false,
173
226
  classNameList: options?.classNameList,
174
227
  cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
175
- theme: context.userTheme?.theme,
176
- useTheme: !!context.userTheme,
177
- cssOutDir: context.flairGeneratedCssDir
228
+ theme: userTheme?.theme,
229
+ useTheme: !!userTheme,
230
+ cssOutDir: cssGeneratedDir
178
231
  });
179
232
  if (!result) return callback(null, source, sourceMap);
180
- if (result.generatedCssName) context.refreshCssFile(result.generatedCssName);
181
- callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
233
+ if (!result.generatedCssName) return callback(null, source, sourceMap);
234
+ this.addDependency(path$2.resolve(result.generatedCssName));
235
+ let resultSourcemap = null;
236
+ if (result.sourcemap) try {
237
+ resultSourcemap = JSON.parse(result.sourcemap);
238
+ } catch {}
239
+ callback(null, result.code, resultSourcemap ?? sourceMap);
182
240
  } catch (error) {
183
241
  console.error("[@flairjs/webpack-loader]", error);
184
242
  callback(error, source, sourceMap);
@@ -1,6 +1,33 @@
1
- import { SharedPluginOptions } from "@flairjs/bundler-shared";
2
- import { LoaderContext } from "webpack";
3
- interface FlairJsWebpackLoaderOptions extends SharedPluginOptions {
4
- }
5
- export default function flairJsLoader(this: LoaderContext<FlairJsWebpackLoaderOptions>, source: string, sourceMap: string): Promise<void>;
6
- export {};
1
+ import { FlairThemeConfig } from '@flairjs/client';
2
+ import { LoaderContext } from 'webpack';
3
+
4
+ declare function flairJsLoader(this: LoaderContext<FlairJsWebpackLoaderOptions>, source: string, sourceMap: string): Promise<void>;
5
+ export default flairJsLoader;
6
+
7
+ declare interface FlairJsWebpackLoaderOptions extends SharedPluginOptions {
8
+ }
9
+
10
+ declare interface SharedPluginOptions {
11
+ /**
12
+ * Preprocess the extracted CSS before it is passed to lightningcss
13
+ * @experimental
14
+ * @param css the extracted css
15
+ * @param id the id of the file being processed
16
+ * @returns the processed css
17
+ */
18
+ cssPreprocessor?: (css: string, id: string) => string;
19
+ include?: string | string[];
20
+ exclude?: string | string[];
21
+ /**
22
+ * Override the default theme file content based on the user theme
23
+ * @param theme the user theme
24
+ * @returns the theme file content
25
+ */
26
+ buildThemeFile?: (theme: FlairThemeConfig) => string;
27
+ /**
28
+ * List of class names used in the project. Supports regex.
29
+ */
30
+ classNameList?: string[];
31
+ }
32
+
33
+ export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flairjs/webpack-loader",
3
- "version": "0.0.1-beta.1",
3
+ "version": "0.0.1-beta.10",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/types/index.d.ts",
@@ -13,20 +13,25 @@
13
13
  },
14
14
  "peerDependencies": {
15
15
  "webpack": ">=5.0.0",
16
- "@flairjs/core": "0.0.1-beta.4"
16
+ "@flairjs/core": "0.0.1-beta.8"
17
17
  },
18
18
  "devDependencies": {
19
- "@biomejs/biome": "^1.9.4",
20
- "@rollup/plugin-typescript": "^12.1.4",
19
+ "@biomejs/biome": "^2.2.4",
20
+ "@microsoft/api-extractor": "^7.52.13",
21
21
  "@types/node": "^22.8.1",
22
+ "rimraf": "^6.0.1",
22
23
  "rolldown": "1.0.0-beta.37",
23
24
  "typescript": "^5.8.2",
24
25
  "webpack": "^5.101.0",
25
- "@flairjs/bundler-shared": "0.0.1-beta.4",
26
- "@flairjs/core": "0.0.1-beta.4"
26
+ "@flairjs/bundler-shared": "0.0.1-beta.14",
27
+ "@flairjs/core": "0.0.1-beta.8"
28
+ },
29
+ "dependencies": {
30
+ "esbuild": "^0.25.10",
31
+ "picomatch": "^4.0.3"
27
32
  },
28
33
  "scripts": {
29
- "build": "rolldown -c",
34
+ "build": "rimraf dist && tsc && api-extractor run --local && rolldown -c && rimraf dist/types-temp",
30
35
  "check": "biome check --write",
31
36
  "dev": "rolldown -w -c",
32
37
  "format": "biome format --write"