@flairjs/webpack-loader 0.0.1-beta.5 → 0.0.1-beta.6
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/dist/cjs/index.js +105 -44
- package/dist/esm/index.js +105 -44
- package/dist/types/index.js +129 -56
- package/package.json +9 -16
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
99
|
const getUserTheme = async () => {
|
|
100
|
+
if (store.getUserTheme()) 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)
|
|
92
|
-
|
|
93
|
-
|
|
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,72 @@ 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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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 }) => {
|
|
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());
|
|
122
165
|
await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS, "utf-8");
|
|
123
166
|
(0, node_fs.watch)(userTheme.originalPath, async () => {
|
|
124
167
|
userTheme = await getUserTheme();
|
|
168
|
+
store.setLastThemeUpdate(Date.now());
|
|
125
169
|
if (!userTheme) return;
|
|
126
170
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
127
171
|
await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS$1, "utf-8");
|
|
128
172
|
});
|
|
129
173
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
174
|
+
return userTheme;
|
|
175
|
+
};
|
|
176
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir, clearInstantly = false }) => {
|
|
177
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
178
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) {
|
|
179
|
+
if (clearInstantly) {
|
|
180
|
+
await (0, node_fs_promises.rm)(node_path.default.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
181
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
182
|
+
return;
|
|
136
183
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
refreshCssFile
|
|
144
|
-
};
|
|
145
|
-
}
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
(0, node_fs_promises.rm)(node_path.default.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
186
|
+
}, 2e3);
|
|
187
|
+
}
|
|
188
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
189
|
+
};
|
|
146
190
|
function shouldProcessFile(id, include, exclude) {
|
|
147
|
-
const isIncluded = (0, picomatch.default)(include
|
|
148
|
-
const isExcluded = (0, picomatch.default)(exclude
|
|
149
|
-
if (!isIncluded(id)) return false;
|
|
150
|
-
if (isExcluded(id)) return false;
|
|
191
|
+
const isIncluded = (0, picomatch.default)(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
192
|
+
const isExcluded = (0, picomatch.default)(exclude ?? ["**/node_modules/**"]);
|
|
193
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
194
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
151
195
|
return true;
|
|
152
196
|
}
|
|
197
|
+
function normalizeFilePath(filePath) {
|
|
198
|
+
return filePath.replace(/\\/g, "/");
|
|
199
|
+
}
|
|
153
200
|
const colors = {
|
|
154
201
|
reset: "\x1B[0m",
|
|
155
202
|
fg: {
|
|
@@ -191,28 +238,42 @@ const transformCode = (code, filePath, options) => {
|
|
|
191
238
|
|
|
192
239
|
//#endregion
|
|
193
240
|
//#region src/index.ts
|
|
241
|
+
let initialized = false;
|
|
194
242
|
async function flairJsLoader(source, sourceMap) {
|
|
195
243
|
const callback = this.async();
|
|
244
|
+
const options = this.getOptions() || {};
|
|
196
245
|
if (!callback) {
|
|
197
246
|
console.error("@flairjs/webpack-loader requires async support");
|
|
198
247
|
return;
|
|
199
248
|
}
|
|
200
|
-
const options = this.getOptions() || {};
|
|
201
|
-
const context = await initializeSharedContext(options);
|
|
202
249
|
const fileName = this.resourcePath;
|
|
203
250
|
if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
|
|
251
|
+
let cssGeneratedDir = null;
|
|
252
|
+
let userTheme = null;
|
|
253
|
+
if (!initialized) {
|
|
254
|
+
cssGeneratedDir = await setupGeneratedCssDir();
|
|
255
|
+
userTheme = await setupUserThemeFile({ buildThemeFile: options.buildThemeFile });
|
|
256
|
+
initialized = true;
|
|
257
|
+
} else {
|
|
258
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
259
|
+
userTheme = await getUserTheme();
|
|
260
|
+
}
|
|
261
|
+
if (!cssGeneratedDir) {
|
|
262
|
+
console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
|
|
263
|
+
return callback(null, source, sourceMap);
|
|
264
|
+
}
|
|
204
265
|
try {
|
|
205
266
|
const result = transformCode(source, fileName, {
|
|
206
267
|
appendTimestampToCssFile: true,
|
|
207
268
|
classNameList: options?.classNameList,
|
|
208
269
|
cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
|
|
209
|
-
theme:
|
|
210
|
-
useTheme: !!
|
|
211
|
-
cssOutDir:
|
|
270
|
+
theme: userTheme?.theme,
|
|
271
|
+
useTheme: !!userTheme,
|
|
272
|
+
cssOutDir: cssGeneratedDir
|
|
212
273
|
});
|
|
213
274
|
if (!result) return callback(null, source, sourceMap);
|
|
214
|
-
if (result.generatedCssName)
|
|
215
|
-
callback(null, result.code, result.
|
|
275
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
276
|
+
callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
|
|
216
277
|
} catch (error) {
|
|
217
278
|
console.error("[@flairjs/webpack-loader]", error);
|
|
218
279
|
callback(error, source, sourceMap);
|
package/dist/esm/index.js
CHANGED
|
@@ -37,8 +37,33 @@ function tokensToCSSVars(tokens, prefix = []) {
|
|
|
37
37
|
}
|
|
38
38
|
return css$1;
|
|
39
39
|
}
|
|
40
|
+
var Store = class {
|
|
41
|
+
fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
|
|
42
|
+
lastThemeUpdate = Date.now();
|
|
43
|
+
userTheme = /* @__PURE__ */ new Map();
|
|
44
|
+
getUserTheme() {
|
|
45
|
+
return this.userTheme.get(this.lastThemeUpdate) ?? null;
|
|
46
|
+
}
|
|
47
|
+
setUserTheme(theme) {
|
|
48
|
+
this.userTheme.set(this.lastThemeUpdate, theme);
|
|
49
|
+
}
|
|
50
|
+
getLastThemeUpdate() {
|
|
51
|
+
return this.lastThemeUpdate;
|
|
52
|
+
}
|
|
53
|
+
setLastThemeUpdate(timestamp) {
|
|
54
|
+
this.lastThemeUpdate = timestamp;
|
|
55
|
+
}
|
|
56
|
+
setFileNameToGeneratedCssNameMap(fileName, generatedCssName) {
|
|
57
|
+
this.fileNameToGeneratedCssNameMap.set(fileName, generatedCssName);
|
|
58
|
+
}
|
|
59
|
+
getGeneratedCssName(fileName) {
|
|
60
|
+
return this.fileNameToGeneratedCssNameMap.get(fileName);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const store = new Store();
|
|
40
64
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
41
65
|
const getUserTheme = async () => {
|
|
66
|
+
if (store.getUserTheme()) return store.getUserTheme();
|
|
42
67
|
try {
|
|
43
68
|
let userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.ts");
|
|
44
69
|
if (!existsSync$1(userThemeFilePath)) userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.js");
|
|
@@ -54,10 +79,17 @@ const getUserTheme = async () => {
|
|
|
54
79
|
});
|
|
55
80
|
const cacheBuster = Date.now();
|
|
56
81
|
const userTheme = await import(`${pathToFileURL(outFile).href}?update=${cacheBuster}`);
|
|
57
|
-
if (userTheme.default)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
if (userTheme.default) {
|
|
83
|
+
store.setUserTheme({
|
|
84
|
+
theme: userTheme.default,
|
|
85
|
+
originalPath: userThemeFilePath
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
theme: userTheme.default,
|
|
89
|
+
originalPath: userThemeFilePath
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
store.setUserTheme(null);
|
|
61
93
|
return null;
|
|
62
94
|
} catch (error) {
|
|
63
95
|
console.error("Error loading user theme:", error);
|
|
@@ -65,57 +97,72 @@ const getUserTheme = async () => {
|
|
|
65
97
|
}
|
|
66
98
|
};
|
|
67
99
|
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();
|
|
100
|
+
const getGeneratedCssDir = () => {
|
|
74
101
|
const flairThemeFile = require.resolve("@flairjs/client/theme.css");
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
return path.resolve(flairThemeFile, "../generated-css");
|
|
103
|
+
};
|
|
104
|
+
const setupGeneratedCssDir = async (options) => {
|
|
105
|
+
const flairGeneratedCssDir = getGeneratedCssDir();
|
|
106
|
+
const { clearExisting = true } = options ?? {};
|
|
107
|
+
try {
|
|
108
|
+
if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
|
|
109
|
+
else if (clearExisting) {
|
|
110
|
+
await rm(flairGeneratedCssDir, {
|
|
111
|
+
recursive: true,
|
|
112
|
+
force: true
|
|
113
|
+
});
|
|
114
|
+
await mkdir(flairGeneratedCssDir);
|
|
115
|
+
}
|
|
116
|
+
} catch (err) {
|
|
117
|
+
if (err?.code === "EEXIST") return flairGeneratedCssDir;
|
|
118
|
+
else if (existsSync(flairGeneratedCssDir)) return flairGeneratedCssDir;
|
|
119
|
+
console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
|
|
120
|
+
return null;
|
|
83
121
|
}
|
|
122
|
+
return flairGeneratedCssDir;
|
|
123
|
+
};
|
|
124
|
+
const setupUserThemeFile = async ({ buildThemeFile }) => {
|
|
125
|
+
const flairThemeFile = require.resolve("@flairjs/client/theme.css");
|
|
84
126
|
let userTheme = await getUserTheme();
|
|
85
127
|
const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
|
|
86
128
|
if (userTheme) {
|
|
87
129
|
const themeCSS = buildThemeCSS(userTheme.theme);
|
|
130
|
+
store.setLastThemeUpdate(Date.now());
|
|
88
131
|
await writeFile(flairThemeFile, themeCSS, "utf-8");
|
|
89
132
|
watch(userTheme.originalPath, async () => {
|
|
90
133
|
userTheme = await getUserTheme();
|
|
134
|
+
store.setLastThemeUpdate(Date.now());
|
|
91
135
|
if (!userTheme) return;
|
|
92
136
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
93
137
|
await writeFile(flairThemeFile, themeCSS$1, "utf-8");
|
|
94
138
|
});
|
|
95
139
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
140
|
+
return userTheme;
|
|
141
|
+
};
|
|
142
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir, clearInstantly = false }) => {
|
|
143
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
144
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) {
|
|
145
|
+
if (clearInstantly) {
|
|
146
|
+
await rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
147
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
148
|
+
return;
|
|
102
149
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
refreshCssFile
|
|
110
|
-
};
|
|
111
|
-
}
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
152
|
+
}, 2e3);
|
|
153
|
+
}
|
|
154
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
155
|
+
};
|
|
112
156
|
function shouldProcessFile(id, include, exclude) {
|
|
113
|
-
const isIncluded = picomatch(include
|
|
114
|
-
const isExcluded = picomatch(exclude
|
|
115
|
-
if (!isIncluded(id)) return false;
|
|
116
|
-
if (isExcluded(id)) return false;
|
|
157
|
+
const isIncluded = picomatch(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
158
|
+
const isExcluded = picomatch(exclude ?? ["**/node_modules/**"]);
|
|
159
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
160
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
117
161
|
return true;
|
|
118
162
|
}
|
|
163
|
+
function normalizeFilePath(filePath) {
|
|
164
|
+
return filePath.replace(/\\/g, "/");
|
|
165
|
+
}
|
|
119
166
|
const colors = {
|
|
120
167
|
reset: "\x1B[0m",
|
|
121
168
|
fg: {
|
|
@@ -157,28 +204,42 @@ const transformCode$1 = (code, filePath, options) => {
|
|
|
157
204
|
|
|
158
205
|
//#endregion
|
|
159
206
|
//#region src/index.ts
|
|
207
|
+
let initialized = false;
|
|
160
208
|
async function flairJsLoader(source, sourceMap) {
|
|
161
209
|
const callback = this.async();
|
|
210
|
+
const options = this.getOptions() || {};
|
|
162
211
|
if (!callback) {
|
|
163
212
|
console.error("@flairjs/webpack-loader requires async support");
|
|
164
213
|
return;
|
|
165
214
|
}
|
|
166
|
-
const options = this.getOptions() || {};
|
|
167
|
-
const context = await initializeSharedContext(options);
|
|
168
215
|
const fileName = this.resourcePath;
|
|
169
216
|
if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
|
|
217
|
+
let cssGeneratedDir = null;
|
|
218
|
+
let userTheme = null;
|
|
219
|
+
if (!initialized) {
|
|
220
|
+
cssGeneratedDir = await setupGeneratedCssDir();
|
|
221
|
+
userTheme = await setupUserThemeFile({ buildThemeFile: options.buildThemeFile });
|
|
222
|
+
initialized = true;
|
|
223
|
+
} else {
|
|
224
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
225
|
+
userTheme = await getUserTheme();
|
|
226
|
+
}
|
|
227
|
+
if (!cssGeneratedDir) {
|
|
228
|
+
console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
|
|
229
|
+
return callback(null, source, sourceMap);
|
|
230
|
+
}
|
|
170
231
|
try {
|
|
171
232
|
const result = transformCode$1(source, fileName, {
|
|
172
233
|
appendTimestampToCssFile: true,
|
|
173
234
|
classNameList: options?.classNameList,
|
|
174
235
|
cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
|
|
175
|
-
theme:
|
|
176
|
-
useTheme: !!
|
|
177
|
-
cssOutDir:
|
|
236
|
+
theme: userTheme?.theme,
|
|
237
|
+
useTheme: !!userTheme,
|
|
238
|
+
cssOutDir: cssGeneratedDir
|
|
178
239
|
});
|
|
179
240
|
if (!result) return callback(null, source, sourceMap);
|
|
180
|
-
if (result.generatedCssName)
|
|
181
|
-
callback(null, result.code, result.
|
|
241
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
242
|
+
callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
|
|
182
243
|
} catch (error) {
|
|
183
244
|
console.error("[@flairjs/webpack-loader]", error);
|
|
184
245
|
callback(error, source, sourceMap);
|
package/dist/types/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import { existsSync as existsSync$1 } from "fs";
|
|
|
6
6
|
import path$1 from "path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { pathToFileURL } from "url";
|
|
9
|
-
import { transformCode } from "@flairjs/core";
|
|
10
9
|
|
|
11
10
|
//#region rolldown:runtime
|
|
12
11
|
var __create = Object.create;
|
|
@@ -28,6 +27,7 @@ var __copyProps$1 = (to, from, except, desc) => {
|
|
|
28
27
|
}
|
|
29
28
|
return to;
|
|
30
29
|
};
|
|
30
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps$1(target, mod, "default"), secondTarget && __copyProps$1(secondTarget, mod, "default"));
|
|
31
31
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps$1(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
|
|
32
32
|
value: mod,
|
|
33
33
|
enumerable: true
|
|
@@ -3947,9 +3947,15 @@ var require_picomatch = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/p
|
|
|
3947
3947
|
}) });
|
|
3948
3948
|
|
|
3949
3949
|
//#endregion
|
|
3950
|
-
//#region ../
|
|
3951
|
-
var import_main = /* @__PURE__ */ __toESM(require_main(), 1);
|
|
3950
|
+
//#region ../core/browser.js
|
|
3952
3951
|
var import_picomatch = /* @__PURE__ */ __toESM(require_picomatch(), 1);
|
|
3952
|
+
var import_main = /* @__PURE__ */ __toESM(require_main(), 1);
|
|
3953
|
+
var browser_exports = {};
|
|
3954
|
+
import * as import___flairjs_core_wasm32_wasi from "@flairjs/core-wasm32-wasi";
|
|
3955
|
+
__reExport(browser_exports, import___flairjs_core_wasm32_wasi);
|
|
3956
|
+
|
|
3957
|
+
//#endregion
|
|
3958
|
+
//#region ../shared/dist/esm/index.js
|
|
3953
3959
|
String.raw;
|
|
3954
3960
|
const buildThemeTokens = (theme, themeName) => {
|
|
3955
3961
|
let css$1 = "";
|
|
@@ -3976,8 +3982,33 @@ function tokensToCSSVars(tokens, prefix = []) {
|
|
|
3976
3982
|
}
|
|
3977
3983
|
return css$1;
|
|
3978
3984
|
}
|
|
3985
|
+
var Store = class {
|
|
3986
|
+
fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
|
|
3987
|
+
lastThemeUpdate = Date.now();
|
|
3988
|
+
userTheme = /* @__PURE__ */ new Map();
|
|
3989
|
+
getUserTheme() {
|
|
3990
|
+
return this.userTheme.get(this.lastThemeUpdate) ?? null;
|
|
3991
|
+
}
|
|
3992
|
+
setUserTheme(theme) {
|
|
3993
|
+
this.userTheme.set(this.lastThemeUpdate, theme);
|
|
3994
|
+
}
|
|
3995
|
+
getLastThemeUpdate() {
|
|
3996
|
+
return this.lastThemeUpdate;
|
|
3997
|
+
}
|
|
3998
|
+
setLastThemeUpdate(timestamp) {
|
|
3999
|
+
this.lastThemeUpdate = timestamp;
|
|
4000
|
+
}
|
|
4001
|
+
setFileNameToGeneratedCssNameMap(fileName, generatedCssName) {
|
|
4002
|
+
this.fileNameToGeneratedCssNameMap.set(fileName, generatedCssName);
|
|
4003
|
+
}
|
|
4004
|
+
getGeneratedCssName(fileName) {
|
|
4005
|
+
return this.fileNameToGeneratedCssNameMap.get(fileName);
|
|
4006
|
+
}
|
|
4007
|
+
};
|
|
4008
|
+
const store = new Store();
|
|
3979
4009
|
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
3980
4010
|
const getUserTheme = async () => {
|
|
4011
|
+
if (store.getUserTheme()) return store.getUserTheme();
|
|
3981
4012
|
try {
|
|
3982
4013
|
let userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.ts");
|
|
3983
4014
|
if (!existsSync$1(userThemeFilePath)) userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.js");
|
|
@@ -3993,10 +4024,17 @@ const getUserTheme = async () => {
|
|
|
3993
4024
|
});
|
|
3994
4025
|
const cacheBuster = Date.now();
|
|
3995
4026
|
const userTheme = await import(`${pathToFileURL(outFile).href}?update=${cacheBuster}`);
|
|
3996
|
-
if (userTheme.default)
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4027
|
+
if (userTheme.default) {
|
|
4028
|
+
store.setUserTheme({
|
|
4029
|
+
theme: userTheme.default,
|
|
4030
|
+
originalPath: userThemeFilePath
|
|
4031
|
+
});
|
|
4032
|
+
return {
|
|
4033
|
+
theme: userTheme.default,
|
|
4034
|
+
originalPath: userThemeFilePath
|
|
4035
|
+
};
|
|
4036
|
+
}
|
|
4037
|
+
store.setUserTheme(null);
|
|
4000
4038
|
return null;
|
|
4001
4039
|
} catch (error) {
|
|
4002
4040
|
console.error("Error loading user theme:", error);
|
|
@@ -4004,57 +4042,72 @@ const getUserTheme = async () => {
|
|
|
4004
4042
|
}
|
|
4005
4043
|
};
|
|
4006
4044
|
const require$1 = module$1.createRequire(import.meta.url);
|
|
4007
|
-
|
|
4008
|
-
* Initialize the shared plugin context
|
|
4009
|
-
*/
|
|
4010
|
-
async function initializeSharedContext(options = {}) {
|
|
4011
|
-
const { buildThemeFile } = options;
|
|
4012
|
-
const fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
|
|
4045
|
+
const getGeneratedCssDir = () => {
|
|
4013
4046
|
const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4047
|
+
return path.resolve(flairThemeFile, "../generated-css");
|
|
4048
|
+
};
|
|
4049
|
+
const setupGeneratedCssDir = async (options) => {
|
|
4050
|
+
const flairGeneratedCssDir = getGeneratedCssDir();
|
|
4051
|
+
const { clearExisting = true } = options ?? {};
|
|
4052
|
+
try {
|
|
4053
|
+
if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
|
|
4054
|
+
else if (clearExisting) {
|
|
4055
|
+
await rm(flairGeneratedCssDir, {
|
|
4056
|
+
recursive: true,
|
|
4057
|
+
force: true
|
|
4058
|
+
});
|
|
4059
|
+
await mkdir(flairGeneratedCssDir);
|
|
4060
|
+
}
|
|
4061
|
+
} catch (err) {
|
|
4062
|
+
if (err?.code === "EEXIST") return flairGeneratedCssDir;
|
|
4063
|
+
else if (existsSync(flairGeneratedCssDir)) return flairGeneratedCssDir;
|
|
4064
|
+
console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
|
|
4065
|
+
return null;
|
|
4022
4066
|
}
|
|
4067
|
+
return flairGeneratedCssDir;
|
|
4068
|
+
};
|
|
4069
|
+
const setupUserThemeFile = async ({ buildThemeFile }) => {
|
|
4070
|
+
const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
|
|
4023
4071
|
let userTheme = await getUserTheme();
|
|
4024
4072
|
const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
|
|
4025
4073
|
if (userTheme) {
|
|
4026
4074
|
const themeCSS = buildThemeCSS(userTheme.theme);
|
|
4075
|
+
store.setLastThemeUpdate(Date.now());
|
|
4027
4076
|
await writeFile(flairThemeFile, themeCSS, "utf-8");
|
|
4028
4077
|
watch(userTheme.originalPath, async () => {
|
|
4029
4078
|
userTheme = await getUserTheme();
|
|
4079
|
+
store.setLastThemeUpdate(Date.now());
|
|
4030
4080
|
if (!userTheme) return;
|
|
4031
4081
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
4032
4082
|
await writeFile(flairThemeFile, themeCSS$1, "utf-8");
|
|
4033
4083
|
});
|
|
4034
4084
|
}
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4085
|
+
return userTheme;
|
|
4086
|
+
};
|
|
4087
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir, clearInstantly = false }) => {
|
|
4088
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
4089
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) {
|
|
4090
|
+
if (clearInstantly) {
|
|
4091
|
+
await rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
4092
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
4093
|
+
return;
|
|
4041
4094
|
}
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
refreshCssFile
|
|
4049
|
-
};
|
|
4050
|
-
}
|
|
4095
|
+
setTimeout(() => {
|
|
4096
|
+
rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
4097
|
+
}, 2e3);
|
|
4098
|
+
}
|
|
4099
|
+
store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
4100
|
+
};
|
|
4051
4101
|
function shouldProcessFile(id, include, exclude) {
|
|
4052
|
-
const isIncluded = (0, import_picomatch.default)(include
|
|
4053
|
-
const isExcluded = (0, import_picomatch.default)(exclude
|
|
4054
|
-
if (!isIncluded(id)) return false;
|
|
4055
|
-
if (isExcluded(id)) return false;
|
|
4102
|
+
const isIncluded = (0, import_picomatch.default)(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
4103
|
+
const isExcluded = (0, import_picomatch.default)(exclude ?? ["**/node_modules/**"]);
|
|
4104
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
4105
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
4056
4106
|
return true;
|
|
4057
4107
|
}
|
|
4108
|
+
function normalizeFilePath(filePath) {
|
|
4109
|
+
return filePath.replace(/\\/g, "/");
|
|
4110
|
+
}
|
|
4058
4111
|
const colors = {
|
|
4059
4112
|
reset: "\x1B[0m",
|
|
4060
4113
|
fg: {
|
|
@@ -4080,8 +4133,8 @@ const logger = {
|
|
|
4080
4133
|
console.log(`${colors.bg.blue}${colors.fg.white}[flairjs/Info]${colors.reset} ${msg}${colors.reset}`);
|
|
4081
4134
|
}
|
|
4082
4135
|
};
|
|
4083
|
-
const transformCode
|
|
4084
|
-
const result = transformCode(code, filePath, {
|
|
4136
|
+
const transformCode = (code, filePath, options) => {
|
|
4137
|
+
const result = (0, browser_exports.transformCode)(code, filePath, {
|
|
4085
4138
|
cssOutDir: options.cssOutDir,
|
|
4086
4139
|
classNameList: options.classNameList,
|
|
4087
4140
|
useTheme: options.useTheme,
|
|
@@ -4096,38 +4149,58 @@ const transformCode$1 = (code, filePath, options) => {
|
|
|
4096
4149
|
|
|
4097
4150
|
//#endregion
|
|
4098
4151
|
//#region src/index.ts
|
|
4152
|
+
var initialized = false;
|
|
4099
4153
|
function flairJsLoader(source, sourceMap) {
|
|
4100
4154
|
return __awaiter(this, void 0, void 0, function() {
|
|
4101
|
-
var callback, options,
|
|
4102
|
-
var _a$1
|
|
4103
|
-
return __generator(this, function(
|
|
4104
|
-
switch (
|
|
4155
|
+
var callback, options, fileName, cssGeneratedDir, userTheme, result;
|
|
4156
|
+
var _a$1;
|
|
4157
|
+
return __generator(this, function(_b) {
|
|
4158
|
+
switch (_b.label) {
|
|
4105
4159
|
case 0:
|
|
4106
4160
|
callback = this.async();
|
|
4161
|
+
options = this.getOptions() || {};
|
|
4107
4162
|
if (!callback) {
|
|
4108
4163
|
console.error("@flairjs/webpack-loader requires async support");
|
|
4109
4164
|
return [2];
|
|
4110
4165
|
}
|
|
4111
|
-
options = this.getOptions() || {};
|
|
4112
|
-
return [4, initializeSharedContext(options)];
|
|
4113
|
-
case 1:
|
|
4114
|
-
context$1 = _c.sent();
|
|
4115
4166
|
fileName = this.resourcePath;
|
|
4116
4167
|
if (!shouldProcessFile(fileName, options === null || options === void 0 ? void 0 : options.include, options === null || options === void 0 ? void 0 : options.exclude)) return [2, callback(null, source, sourceMap)];
|
|
4168
|
+
cssGeneratedDir = null;
|
|
4169
|
+
userTheme = null;
|
|
4170
|
+
if (!!initialized) return [3, 3];
|
|
4171
|
+
return [4, setupGeneratedCssDir()];
|
|
4172
|
+
case 1:
|
|
4173
|
+
cssGeneratedDir = _b.sent();
|
|
4174
|
+
return [4, setupUserThemeFile({ buildThemeFile: options.buildThemeFile })];
|
|
4175
|
+
case 2:
|
|
4176
|
+
userTheme = _b.sent();
|
|
4177
|
+
initialized = true;
|
|
4178
|
+
return [3, 5];
|
|
4179
|
+
case 3:
|
|
4180
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
4181
|
+
return [4, getUserTheme()];
|
|
4182
|
+
case 4:
|
|
4183
|
+
userTheme = _b.sent();
|
|
4184
|
+
_b.label = 5;
|
|
4185
|
+
case 5:
|
|
4186
|
+
if (!cssGeneratedDir) {
|
|
4187
|
+
console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
|
|
4188
|
+
return [2, callback(null, source, sourceMap)];
|
|
4189
|
+
}
|
|
4117
4190
|
try {
|
|
4118
|
-
result = transformCode
|
|
4191
|
+
result = transformCode(source, fileName, {
|
|
4119
4192
|
appendTimestampToCssFile: true,
|
|
4120
4193
|
classNameList: options === null || options === void 0 ? void 0 : options.classNameList,
|
|
4121
4194
|
cssPreprocessor: (options === null || options === void 0 ? void 0 : options.cssPreprocessor) ? function(css) {
|
|
4122
4195
|
return options.cssPreprocessor(css, fileName);
|
|
4123
4196
|
} : void 0,
|
|
4124
|
-
theme:
|
|
4125
|
-
useTheme: !!
|
|
4126
|
-
cssOutDir:
|
|
4197
|
+
theme: userTheme === null || userTheme === void 0 ? void 0 : userTheme.theme,
|
|
4198
|
+
useTheme: !!userTheme,
|
|
4199
|
+
cssOutDir: cssGeneratedDir
|
|
4127
4200
|
});
|
|
4128
4201
|
if (!result) return [2, callback(null, source, sourceMap)];
|
|
4129
|
-
if (result.generatedCssName)
|
|
4130
|
-
callback(null, result.code, result.
|
|
4202
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
4203
|
+
callback(null, result.code, result.sourcemap ? JSON.parse((_a$1 = result.sourcemap) !== null && _a$1 !== void 0 ? _a$1 : "{}") : sourceMap);
|
|
4131
4204
|
} catch (error) {
|
|
4132
4205
|
console.error("[@flairjs/webpack-loader]", error);
|
|
4133
4206
|
callback(error, source, sourceMap);
|
package/package.json
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flairjs/webpack-loader",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"exports": {
|
|
6
|
-
".": {
|
|
7
|
-
"types": "./dist/types/index.d.ts",
|
|
8
|
-
"import": "./dist/esm/index.js",
|
|
9
|
-
"require": "./dist/cjs/index.js"
|
|
10
|
-
},
|
|
11
|
-
"./cached-css/*": {
|
|
12
|
-
"import": "./dist/.cache/*"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
3
|
+
"version": "0.0.1-beta.6",
|
|
15
4
|
"main": "./dist/cjs/index.js",
|
|
16
5
|
"module": "./dist/esm/index.js",
|
|
17
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -24,7 +13,7 @@
|
|
|
24
13
|
},
|
|
25
14
|
"peerDependencies": {
|
|
26
15
|
"webpack": ">=5.0.0",
|
|
27
|
-
"@flairjs/core": "0.0.1-beta.
|
|
16
|
+
"@flairjs/core": "0.0.1-beta.5"
|
|
28
17
|
},
|
|
29
18
|
"devDependencies": {
|
|
30
19
|
"@biomejs/biome": "^1.9.4",
|
|
@@ -33,11 +22,15 @@
|
|
|
33
22
|
"rolldown": "1.0.0-beta.37",
|
|
34
23
|
"typescript": "^5.8.2",
|
|
35
24
|
"webpack": "^5.101.0",
|
|
36
|
-
"@flairjs/bundler-shared": "0.0.1-beta.
|
|
37
|
-
"@flairjs/core": "0.0.1-beta.
|
|
25
|
+
"@flairjs/bundler-shared": "0.0.1-beta.9",
|
|
26
|
+
"@flairjs/core": "0.0.1-beta.5"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"esbuild": "^0.25.10",
|
|
30
|
+
"picomatch": "^4.0.3"
|
|
38
31
|
},
|
|
39
32
|
"scripts": {
|
|
40
|
-
"build": "rolldown -c",
|
|
33
|
+
"build": "tsc && rolldown -c",
|
|
41
34
|
"check": "biome check --write",
|
|
42
35
|
"dev": "rolldown -w -c",
|
|
43
36
|
"format": "biome format --write"
|