@flairjs/webpack-loader 0.0.1-beta.2 → 0.0.1-beta.4
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 +97 -44
- package/dist/esm/index.js +97 -44
- package/dist/types/index.js +109 -50
- package/package.json +4 -4
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,64 @@ 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 () => {
|
|
139
|
+
const flairGeneratedCssDir = getGeneratedCssDir();
|
|
140
|
+
try {
|
|
141
|
+
if (!(0, node_fs.existsSync)(flairGeneratedCssDir)) await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
|
|
142
|
+
else {
|
|
143
|
+
await (0, node_fs_promises.rm)(flairGeneratedCssDir, {
|
|
144
|
+
recursive: true,
|
|
145
|
+
force: true
|
|
146
|
+
});
|
|
147
|
+
await (0, node_fs_promises.mkdir)(flairGeneratedCssDir);
|
|
148
|
+
}
|
|
149
|
+
} catch (err) {
|
|
150
|
+
if (err?.code === "EEXIST") return flairGeneratedCssDir;
|
|
151
|
+
else if ((0, node_fs.existsSync)(flairGeneratedCssDir)) return flairGeneratedCssDir;
|
|
152
|
+
console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
|
|
153
|
+
return null;
|
|
117
154
|
}
|
|
155
|
+
return flairGeneratedCssDir;
|
|
156
|
+
};
|
|
157
|
+
const setupUserThemeFile = async ({ buildThemeFile }) => {
|
|
158
|
+
const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
|
|
118
159
|
let userTheme = await getUserTheme();
|
|
119
160
|
const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
|
|
120
161
|
if (userTheme) {
|
|
121
162
|
const themeCSS = buildThemeCSS(userTheme.theme);
|
|
163
|
+
store.setLastThemeUpdate(Date.now());
|
|
122
164
|
await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS, "utf-8");
|
|
123
165
|
(0, node_fs.watch)(userTheme.originalPath, async () => {
|
|
124
166
|
userTheme = await getUserTheme();
|
|
167
|
+
store.setLastThemeUpdate(Date.now());
|
|
125
168
|
if (!userTheme) return;
|
|
126
169
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
127
170
|
await (0, node_fs_promises.writeFile)(flairThemeFile, themeCSS$1, "utf-8");
|
|
128
171
|
});
|
|
129
172
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
flairThemeFile,
|
|
140
|
-
flairGeneratedCssDir,
|
|
141
|
-
userTheme,
|
|
142
|
-
buildThemeCSS,
|
|
143
|
-
refreshCssFile
|
|
144
|
-
};
|
|
145
|
-
}
|
|
173
|
+
return userTheme;
|
|
174
|
+
};
|
|
175
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir }) => {
|
|
176
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
177
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) setTimeout(() => {
|
|
178
|
+
(0, node_fs_promises.rm)(node_path.default.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
179
|
+
}, 2e3);
|
|
180
|
+
else store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
181
|
+
};
|
|
146
182
|
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;
|
|
183
|
+
const isIncluded = (0, picomatch.default)(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
184
|
+
const isExcluded = (0, picomatch.default)(exclude ?? ["node_modules/**"]);
|
|
185
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
186
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
151
187
|
return true;
|
|
152
188
|
}
|
|
189
|
+
function normalizeFilePath(filePath) {
|
|
190
|
+
return filePath.replace(/\\/g, "/");
|
|
191
|
+
}
|
|
153
192
|
const colors = {
|
|
154
193
|
reset: "\x1B[0m",
|
|
155
194
|
fg: {
|
|
@@ -191,27 +230,41 @@ const transformCode = (code, filePath, options) => {
|
|
|
191
230
|
|
|
192
231
|
//#endregion
|
|
193
232
|
//#region src/index.ts
|
|
233
|
+
let initialized = false;
|
|
194
234
|
async function flairJsLoader(source, sourceMap) {
|
|
195
235
|
const callback = this.async();
|
|
236
|
+
const options = this.getOptions() || {};
|
|
196
237
|
if (!callback) {
|
|
197
238
|
console.error("@flairjs/webpack-loader requires async support");
|
|
198
239
|
return;
|
|
199
240
|
}
|
|
200
|
-
|
|
201
|
-
|
|
241
|
+
let cssGeneratedDir = null;
|
|
242
|
+
let userTheme = null;
|
|
243
|
+
if (!initialized) {
|
|
244
|
+
cssGeneratedDir = await setupGeneratedCssDir();
|
|
245
|
+
userTheme = await setupUserThemeFile({ buildThemeFile: options.buildThemeFile });
|
|
246
|
+
initialized = true;
|
|
247
|
+
} else {
|
|
248
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
249
|
+
userTheme = await getUserTheme();
|
|
250
|
+
}
|
|
202
251
|
const fileName = this.resourcePath;
|
|
203
252
|
if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
|
|
253
|
+
if (!cssGeneratedDir) {
|
|
254
|
+
console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
|
|
255
|
+
return callback(null, source, sourceMap);
|
|
256
|
+
}
|
|
204
257
|
try {
|
|
205
258
|
const result = transformCode(source, fileName, {
|
|
206
259
|
appendTimestampToCssFile: true,
|
|
207
260
|
classNameList: options?.classNameList,
|
|
208
261
|
cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
|
|
209
|
-
theme:
|
|
210
|
-
useTheme: !!
|
|
211
|
-
cssOutDir:
|
|
262
|
+
theme: userTheme?.theme,
|
|
263
|
+
useTheme: !!userTheme,
|
|
264
|
+
cssOutDir: cssGeneratedDir
|
|
212
265
|
});
|
|
213
266
|
if (!result) return callback(null, source, sourceMap);
|
|
214
|
-
if (result.generatedCssName)
|
|
267
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
215
268
|
callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
|
|
216
269
|
} catch (error) {
|
|
217
270
|
console.error("[@flairjs/webpack-loader]", error);
|
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,64 @@ 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 () => {
|
|
105
|
+
const flairGeneratedCssDir = getGeneratedCssDir();
|
|
106
|
+
try {
|
|
107
|
+
if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
|
|
108
|
+
else {
|
|
109
|
+
await rm(flairGeneratedCssDir, {
|
|
110
|
+
recursive: true,
|
|
111
|
+
force: true
|
|
112
|
+
});
|
|
113
|
+
await mkdir(flairGeneratedCssDir);
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
if (err?.code === "EEXIST") return flairGeneratedCssDir;
|
|
117
|
+
else if (existsSync(flairGeneratedCssDir)) return flairGeneratedCssDir;
|
|
118
|
+
console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
|
|
119
|
+
return null;
|
|
83
120
|
}
|
|
121
|
+
return flairGeneratedCssDir;
|
|
122
|
+
};
|
|
123
|
+
const setupUserThemeFile = async ({ buildThemeFile }) => {
|
|
124
|
+
const flairThemeFile = require.resolve("@flairjs/client/theme.css");
|
|
84
125
|
let userTheme = await getUserTheme();
|
|
85
126
|
const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
|
|
86
127
|
if (userTheme) {
|
|
87
128
|
const themeCSS = buildThemeCSS(userTheme.theme);
|
|
129
|
+
store.setLastThemeUpdate(Date.now());
|
|
88
130
|
await writeFile(flairThemeFile, themeCSS, "utf-8");
|
|
89
131
|
watch(userTheme.originalPath, async () => {
|
|
90
132
|
userTheme = await getUserTheme();
|
|
133
|
+
store.setLastThemeUpdate(Date.now());
|
|
91
134
|
if (!userTheme) return;
|
|
92
135
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
93
136
|
await writeFile(flairThemeFile, themeCSS$1, "utf-8");
|
|
94
137
|
});
|
|
95
138
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
flairThemeFile,
|
|
106
|
-
flairGeneratedCssDir,
|
|
107
|
-
userTheme,
|
|
108
|
-
buildThemeCSS,
|
|
109
|
-
refreshCssFile
|
|
110
|
-
};
|
|
111
|
-
}
|
|
139
|
+
return userTheme;
|
|
140
|
+
};
|
|
141
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir }) => {
|
|
142
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
143
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) setTimeout(() => {
|
|
144
|
+
rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
145
|
+
}, 2e3);
|
|
146
|
+
else store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
147
|
+
};
|
|
112
148
|
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;
|
|
149
|
+
const isIncluded = picomatch(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
150
|
+
const isExcluded = picomatch(exclude ?? ["node_modules/**"]);
|
|
151
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
152
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
117
153
|
return true;
|
|
118
154
|
}
|
|
155
|
+
function normalizeFilePath(filePath) {
|
|
156
|
+
return filePath.replace(/\\/g, "/");
|
|
157
|
+
}
|
|
119
158
|
const colors = {
|
|
120
159
|
reset: "\x1B[0m",
|
|
121
160
|
fg: {
|
|
@@ -157,27 +196,41 @@ const transformCode$1 = (code, filePath, options) => {
|
|
|
157
196
|
|
|
158
197
|
//#endregion
|
|
159
198
|
//#region src/index.ts
|
|
199
|
+
let initialized = false;
|
|
160
200
|
async function flairJsLoader(source, sourceMap) {
|
|
161
201
|
const callback = this.async();
|
|
202
|
+
const options = this.getOptions() || {};
|
|
162
203
|
if (!callback) {
|
|
163
204
|
console.error("@flairjs/webpack-loader requires async support");
|
|
164
205
|
return;
|
|
165
206
|
}
|
|
166
|
-
|
|
167
|
-
|
|
207
|
+
let cssGeneratedDir = null;
|
|
208
|
+
let userTheme = null;
|
|
209
|
+
if (!initialized) {
|
|
210
|
+
cssGeneratedDir = await setupGeneratedCssDir();
|
|
211
|
+
userTheme = await setupUserThemeFile({ buildThemeFile: options.buildThemeFile });
|
|
212
|
+
initialized = true;
|
|
213
|
+
} else {
|
|
214
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
215
|
+
userTheme = await getUserTheme();
|
|
216
|
+
}
|
|
168
217
|
const fileName = this.resourcePath;
|
|
169
218
|
if (!shouldProcessFile(fileName, options?.include, options?.exclude)) return callback(null, source, sourceMap);
|
|
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
225
|
appendTimestampToCssFile: true,
|
|
173
226
|
classNameList: options?.classNameList,
|
|
174
227
|
cssPreprocessor: options?.cssPreprocessor ? (css) => options.cssPreprocessor(css, fileName) : void 0,
|
|
175
|
-
theme:
|
|
176
|
-
useTheme: !!
|
|
177
|
-
cssOutDir:
|
|
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)
|
|
233
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
181
234
|
callback(null, result.code, result.sourcemap ? JSON.parse(result.sourcemap ?? "{}") : sourceMap);
|
|
182
235
|
} catch (error) {
|
|
183
236
|
console.error("[@flairjs/webpack-loader]", error);
|
package/dist/types/index.js
CHANGED
|
@@ -3982,8 +3982,33 @@ function tokensToCSSVars(tokens, prefix = []) {
|
|
|
3982
3982
|
}
|
|
3983
3983
|
return css$1;
|
|
3984
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();
|
|
3985
4009
|
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
3986
4010
|
const getUserTheme = async () => {
|
|
4011
|
+
if (store.getUserTheme()) return store.getUserTheme();
|
|
3987
4012
|
try {
|
|
3988
4013
|
let userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.ts");
|
|
3989
4014
|
if (!existsSync$1(userThemeFilePath)) userThemeFilePath = path$1.resolve(process.cwd(), "flair.theme.js");
|
|
@@ -3999,10 +4024,17 @@ const getUserTheme = async () => {
|
|
|
3999
4024
|
});
|
|
4000
4025
|
const cacheBuster = Date.now();
|
|
4001
4026
|
const userTheme = await import(`${pathToFileURL(outFile).href}?update=${cacheBuster}`);
|
|
4002
|
-
if (userTheme.default)
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
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);
|
|
4006
4038
|
return null;
|
|
4007
4039
|
} catch (error) {
|
|
4008
4040
|
console.error("Error loading user theme:", error);
|
|
@@ -4010,57 +4042,64 @@ const getUserTheme = async () => {
|
|
|
4010
4042
|
}
|
|
4011
4043
|
};
|
|
4012
4044
|
const require$1 = module$1.createRequire(import.meta.url);
|
|
4013
|
-
|
|
4014
|
-
* Initialize the shared plugin context
|
|
4015
|
-
*/
|
|
4016
|
-
async function initializeSharedContext(options = {}) {
|
|
4017
|
-
const { buildThemeFile } = options;
|
|
4018
|
-
const fileNameToGeneratedCssNameMap = /* @__PURE__ */ new Map();
|
|
4045
|
+
const getGeneratedCssDir = () => {
|
|
4019
4046
|
const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4047
|
+
return path.resolve(flairThemeFile, "../generated-css");
|
|
4048
|
+
};
|
|
4049
|
+
const setupGeneratedCssDir = async () => {
|
|
4050
|
+
const flairGeneratedCssDir = getGeneratedCssDir();
|
|
4051
|
+
try {
|
|
4052
|
+
if (!existsSync(flairGeneratedCssDir)) await mkdir(flairGeneratedCssDir);
|
|
4053
|
+
else {
|
|
4054
|
+
await rm(flairGeneratedCssDir, {
|
|
4055
|
+
recursive: true,
|
|
4056
|
+
force: true
|
|
4057
|
+
});
|
|
4058
|
+
await mkdir(flairGeneratedCssDir);
|
|
4059
|
+
}
|
|
4060
|
+
} catch (err) {
|
|
4061
|
+
if (err?.code === "EEXIST") return flairGeneratedCssDir;
|
|
4062
|
+
else if (existsSync(flairGeneratedCssDir)) return flairGeneratedCssDir;
|
|
4063
|
+
console.error(`[flairjs] Could not create generated CSS directory: ${flairGeneratedCssDir}`, err);
|
|
4064
|
+
return null;
|
|
4028
4065
|
}
|
|
4066
|
+
return flairGeneratedCssDir;
|
|
4067
|
+
};
|
|
4068
|
+
const setupUserThemeFile = async ({ buildThemeFile }) => {
|
|
4069
|
+
const flairThemeFile = require$1.resolve("@flairjs/client/theme.css");
|
|
4029
4070
|
let userTheme = await getUserTheme();
|
|
4030
4071
|
const buildThemeCSS = buildThemeFile ?? buildThemeTokens;
|
|
4031
4072
|
if (userTheme) {
|
|
4032
4073
|
const themeCSS = buildThemeCSS(userTheme.theme);
|
|
4074
|
+
store.setLastThemeUpdate(Date.now());
|
|
4033
4075
|
await writeFile(flairThemeFile, themeCSS, "utf-8");
|
|
4034
4076
|
watch(userTheme.originalPath, async () => {
|
|
4035
4077
|
userTheme = await getUserTheme();
|
|
4078
|
+
store.setLastThemeUpdate(Date.now());
|
|
4036
4079
|
if (!userTheme) return;
|
|
4037
4080
|
const themeCSS$1 = buildThemeCSS(userTheme.theme);
|
|
4038
4081
|
await writeFile(flairThemeFile, themeCSS$1, "utf-8");
|
|
4039
4082
|
});
|
|
4040
4083
|
}
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
flairThemeFile,
|
|
4051
|
-
flairGeneratedCssDir,
|
|
4052
|
-
userTheme,
|
|
4053
|
-
buildThemeCSS,
|
|
4054
|
-
refreshCssFile
|
|
4055
|
-
};
|
|
4056
|
-
}
|
|
4084
|
+
return userTheme;
|
|
4085
|
+
};
|
|
4086
|
+
const removeOutdatedCssFiles = async (sourceFilePath, cssFilePath, { flairGeneratedCssDir }) => {
|
|
4087
|
+
const previousGeneratedCssName = store.getGeneratedCssName(sourceFilePath);
|
|
4088
|
+
if (previousGeneratedCssName && previousGeneratedCssName !== cssFilePath) setTimeout(() => {
|
|
4089
|
+
rm(path.join(flairGeneratedCssDir, previousGeneratedCssName), { force: true });
|
|
4090
|
+
}, 2e3);
|
|
4091
|
+
else store.setFileNameToGeneratedCssNameMap(sourceFilePath, cssFilePath);
|
|
4092
|
+
};
|
|
4057
4093
|
function shouldProcessFile(id, include, exclude) {
|
|
4058
|
-
const isIncluded = (0, import_picomatch.default)(include
|
|
4059
|
-
const isExcluded = (0, import_picomatch.default)(exclude
|
|
4060
|
-
if (!isIncluded(id)) return false;
|
|
4061
|
-
if (isExcluded(id)) return false;
|
|
4094
|
+
const isIncluded = (0, import_picomatch.default)(include ?? ["**/*.{js,ts,jsx,tsx}"]);
|
|
4095
|
+
const isExcluded = (0, import_picomatch.default)(exclude ?? ["node_modules/**"]);
|
|
4096
|
+
if (!isIncluded(normalizeFilePath(id))) return false;
|
|
4097
|
+
if (isExcluded(normalizeFilePath(id))) return false;
|
|
4062
4098
|
return true;
|
|
4063
4099
|
}
|
|
4100
|
+
function normalizeFilePath(filePath) {
|
|
4101
|
+
return filePath.replace(/\\/g, "/");
|
|
4102
|
+
}
|
|
4064
4103
|
const colors = {
|
|
4065
4104
|
reset: "\x1B[0m",
|
|
4066
4105
|
fg: {
|
|
@@ -4102,24 +4141,44 @@ const transformCode = (code, filePath, options) => {
|
|
|
4102
4141
|
|
|
4103
4142
|
//#endregion
|
|
4104
4143
|
//#region src/index.ts
|
|
4144
|
+
var initialized = false;
|
|
4105
4145
|
function flairJsLoader(source, sourceMap) {
|
|
4106
4146
|
return __awaiter(this, void 0, void 0, function() {
|
|
4107
|
-
var callback, options,
|
|
4108
|
-
var _a$1
|
|
4109
|
-
return __generator(this, function(
|
|
4110
|
-
switch (
|
|
4147
|
+
var callback, options, cssGeneratedDir, userTheme, fileName, result;
|
|
4148
|
+
var _a$1;
|
|
4149
|
+
return __generator(this, function(_b) {
|
|
4150
|
+
switch (_b.label) {
|
|
4111
4151
|
case 0:
|
|
4112
4152
|
callback = this.async();
|
|
4153
|
+
options = this.getOptions() || {};
|
|
4113
4154
|
if (!callback) {
|
|
4114
4155
|
console.error("@flairjs/webpack-loader requires async support");
|
|
4115
4156
|
return [2];
|
|
4116
4157
|
}
|
|
4117
|
-
|
|
4118
|
-
|
|
4158
|
+
cssGeneratedDir = null;
|
|
4159
|
+
userTheme = null;
|
|
4160
|
+
if (!!initialized) return [3, 3];
|
|
4161
|
+
return [4, setupGeneratedCssDir()];
|
|
4119
4162
|
case 1:
|
|
4120
|
-
|
|
4163
|
+
cssGeneratedDir = _b.sent();
|
|
4164
|
+
return [4, setupUserThemeFile({ buildThemeFile: options.buildThemeFile })];
|
|
4165
|
+
case 2:
|
|
4166
|
+
userTheme = _b.sent();
|
|
4167
|
+
initialized = true;
|
|
4168
|
+
return [3, 5];
|
|
4169
|
+
case 3:
|
|
4170
|
+
cssGeneratedDir = getGeneratedCssDir();
|
|
4171
|
+
return [4, getUserTheme()];
|
|
4172
|
+
case 4:
|
|
4173
|
+
userTheme = _b.sent();
|
|
4174
|
+
_b.label = 5;
|
|
4175
|
+
case 5:
|
|
4121
4176
|
fileName = this.resourcePath;
|
|
4122
4177
|
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)];
|
|
4178
|
+
if (!cssGeneratedDir) {
|
|
4179
|
+
console.error("[flairjs] Could not find generated CSS directory. Skipping processing.");
|
|
4180
|
+
return [2, callback(null, source, sourceMap)];
|
|
4181
|
+
}
|
|
4123
4182
|
try {
|
|
4124
4183
|
result = transformCode(source, fileName, {
|
|
4125
4184
|
appendTimestampToCssFile: true,
|
|
@@ -4127,13 +4186,13 @@ function flairJsLoader(source, sourceMap) {
|
|
|
4127
4186
|
cssPreprocessor: (options === null || options === void 0 ? void 0 : options.cssPreprocessor) ? function(css) {
|
|
4128
4187
|
return options.cssPreprocessor(css, fileName);
|
|
4129
4188
|
} : void 0,
|
|
4130
|
-
theme:
|
|
4131
|
-
useTheme: !!
|
|
4132
|
-
cssOutDir:
|
|
4189
|
+
theme: userTheme === null || userTheme === void 0 ? void 0 : userTheme.theme,
|
|
4190
|
+
useTheme: !!userTheme,
|
|
4191
|
+
cssOutDir: cssGeneratedDir
|
|
4133
4192
|
});
|
|
4134
4193
|
if (!result) return [2, callback(null, source, sourceMap)];
|
|
4135
|
-
if (result.generatedCssName)
|
|
4136
|
-
callback(null, result.code, result.sourcemap ? JSON.parse((
|
|
4194
|
+
if (result.generatedCssName) removeOutdatedCssFiles(fileName, result.generatedCssName, { flairGeneratedCssDir: cssGeneratedDir });
|
|
4195
|
+
callback(null, result.code, result.sourcemap ? JSON.parse((_a$1 = result.sourcemap) !== null && _a$1 !== void 0 ? _a$1 : "{}") : sourceMap);
|
|
4137
4196
|
} catch (error) {
|
|
4138
4197
|
console.error("[@flairjs/webpack-loader]", error);
|
|
4139
4198
|
callback(error, source, sourceMap);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flairjs/webpack-loader",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.4",
|
|
4
4
|
"main": "./dist/cjs/index.js",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"webpack": ">=5.0.0",
|
|
16
|
-
"@flairjs/core": "0.0.1-beta.
|
|
16
|
+
"@flairjs/core": "0.0.1-beta.5"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@biomejs/biome": "^1.9.4",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"rolldown": "1.0.0-beta.37",
|
|
23
23
|
"typescript": "^5.8.2",
|
|
24
24
|
"webpack": "^5.101.0",
|
|
25
|
-
"@flairjs/bundler-shared": "0.0.1-beta.
|
|
26
|
-
"@flairjs/core": "0.0.1-beta.
|
|
25
|
+
"@flairjs/bundler-shared": "0.0.1-beta.7",
|
|
26
|
+
"@flairjs/core": "0.0.1-beta.5"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"esbuild": "^0.25.10",
|