jetfast 0.0.1

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/package.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "jetfast",
3
+ "dependencies": {
4
+ "chokidar": "^5.0.0"
5
+ },
6
+ "version": "0.0.1",
7
+ "description": "Ultra-fast CSS engine with purge and arbitrary values",
8
+ "bin": {
9
+ "jetfast": "tools/cli.js"
10
+ },
11
+ "files": ["tools", "dist"],
12
+ "license": "MIT"
13
+ }
package/tools/cli.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("path");
4
+ const command = process.argv[2];
5
+
6
+ if (command === "init") {
7
+ require(path.join(__dirname, "init.js"));
8
+ } else if (command === "dev") {
9
+ require(path.join(__dirname, "watcher.js"));
10
+ } else if (command === "build") {
11
+ require(path.join(__dirname, "generate-output.js"));
12
+ } else {
13
+ console.log("Usage: jetfast <init|dev|build>");
14
+ }
@@ -0,0 +1,39 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const defaultConfig = {
5
+ input: ["**/*.html"],
6
+ output: "JetFast/output/output.css",
7
+
8
+ classPrefix: "",
9
+ separator: "-",
10
+
11
+ theme: {
12
+ colors: {},
13
+ spacing: {},
14
+ fontSize: {},
15
+ },
16
+
17
+ debug: false,
18
+ };
19
+
20
+ function loadUserConfig() {
21
+ const configPath = path.resolve(process.cwd(), "jetfast.config.js");
22
+
23
+ if (!fs.existsSync(configPath)) {
24
+ return {};
25
+ }
26
+
27
+ try {
28
+ return require(configPath);
29
+ } catch (err) {
30
+ console.error("\nāŒ JetFast config error");
31
+ console.error(err.message);
32
+ process.exit(1);
33
+ }
34
+ }
35
+
36
+ module.exports = {
37
+ defaultConfig,
38
+ loadUserConfig,
39
+ };
@@ -0,0 +1,120 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ // const { defaultConfig, loadUserConfig } = require("./config");
5
+ // const deepMerge = require("../core/merge.js");
6
+
7
+ // const userConfig = loadUserConfig();
8
+ // const config = deepMerge(structuredClone(defaultConfig), userConfig);
9
+
10
+ // if (config.debug) {
11
+ // console.log("🧠 JetFast Config Loaded:");
12
+ // console.log(JSON.stringify(config, null, 2));
13
+ // }
14
+
15
+ const HTML_ROOT = path.join(__dirname, "../../");
16
+ const OUTPUT_FILE = path.join(__dirname, "../outputDev/arbitrary-jet.css");
17
+
18
+ const IGNORED_DIRS = new Set([
19
+ "node_modules",
20
+ ".git",
21
+ "dist",
22
+ "build",
23
+ ]);
24
+
25
+ function readIfExists(file) {
26
+ try {
27
+ return fs.readFileSync(file, "utf-8");
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ let output = [];
34
+ const globalSeen = new Set();
35
+
36
+ const regexs = {
37
+ classRegex: /(class|className)="([^"]+)"/gi,
38
+ };
39
+
40
+ function getAllSourceFiles(dir, results = []) {
41
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
42
+
43
+ for (const entry of entries) {
44
+ if (IGNORED_DIRS.has(entry.name)) continue;
45
+
46
+ const fullPath = path.join(dir, entry.name);
47
+
48
+ if (entry.isDirectory()) {
49
+ getAllSourceFiles(fullPath, results);
50
+ } else if (/\.(html|jsx|tsx)$/.test(entry.name)) {
51
+ results.push(fullPath);
52
+ }
53
+ }
54
+
55
+ return results;
56
+ }
57
+
58
+ function escapeClassNames(cls) {
59
+ return cls.replace(/([!#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
60
+ }
61
+
62
+ output.length = 0;
63
+ globalSeen.clear();
64
+
65
+ const sourceFiles = getAllSourceFiles(HTML_ROOT);
66
+
67
+ for (const file of sourceFiles) {
68
+ const content = fs.readFileSync(file, "utf-8");
69
+
70
+ if (!content.includes("AJ-")) continue;
71
+
72
+ for (const match of content.matchAll(regexs.classRegex)) {
73
+ const classList = match[2];
74
+
75
+ for (const className of classList.split(/\s+/)) {
76
+ if (!className) continue;
77
+ if (globalSeen.has(className)) continue;
78
+ if (!className.startsWith("AJ-")) continue;
79
+ if (!className.includes(":")) continue;
80
+
81
+ globalSeen.add(className);
82
+
83
+ const step1 = className.indexOf(":");
84
+ if (step1 === -1) continue;
85
+
86
+ const step2 = className.slice(0, step1);
87
+ const step3 = className.slice(step1 + 1);
88
+
89
+ const property = step2.split("-").slice(1).join("-");
90
+ let value = step3;
91
+
92
+ if (
93
+ property === "background-image" &&
94
+ !value.startsWith("url(") &&
95
+ !value.endsWith(")")
96
+ ) {
97
+ value = `url("${value}")`;
98
+ }
99
+
100
+ output.push(
101
+ `.${escapeClassNames(className)}{\n\t${property}:${value};\n}`,
102
+ );
103
+ }
104
+ }
105
+ }
106
+
107
+ const css = output.join("\n\n") + "\n";
108
+ const prev = readIfExists(OUTPUT_FILE);
109
+
110
+ if (prev === css) {
111
+ console.log("ā­ļø No CSS changes, skipped write");
112
+ process.exit(0);
113
+ }
114
+
115
+ const TEMP_FILE = OUTPUT_FILE + ".tmp";
116
+
117
+ fs.writeFileSync(TEMP_FILE, css);
118
+ fs.renameSync(TEMP_FILE, OUTPUT_FILE);
119
+
120
+ console.log(`āœ… Generated ${output.length} Classes`);
@@ -0,0 +1,46 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const JETS_DIR = path.join(__dirname, "../Jets");
5
+
6
+ // output file
7
+ const OUTPUT = path.join(__dirname, "../jetfast.css-data.json");
8
+
9
+ const CLASS_REGEX = /\.([a-zA-Z0-9_-]+)\s*\{/g;
10
+
11
+ const classes = [];
12
+ const globalSeen = new Set();
13
+
14
+ const files = fs.readdirSync(JETS_DIR).filter(f => f.endsWith(".css"));
15
+
16
+ for (const file of files) {
17
+ const filePath = path.join(JETS_DIR, file);
18
+ const content = fs.readFileSync(filePath, "utf8");
19
+
20
+ let match;
21
+
22
+ while ((match = CLASS_REGEX.exec(content)) !== null) {
23
+ const className = match[1];
24
+
25
+ if (globalSeen.has(className)) continue;
26
+ globalSeen.add(className);
27
+
28
+ classes.push({
29
+ name: className,
30
+ description: `JetFast class from ${file}`
31
+ });
32
+ }
33
+ }
34
+
35
+ const json = {
36
+ version: 1.1,
37
+ atDirectives: [],
38
+ pseudoClasses: [],
39
+ pseudoElements: [],
40
+ properties: [],
41
+ classes
42
+ };
43
+
44
+ fs.writeFileSync(OUTPUT, JSON.stringify(json, null, 2));
45
+
46
+ console.log(`āœ… Generated ${classes.length} IntelliSense classes`);
@@ -0,0 +1,6 @@
1
+ const fs = require("fs")
2
+
3
+ const arbitrary=fs.readFileSync("./outputDev/arbitrary-jet.css","utf-8")
4
+ const purge=fs.readFileSync("./outputDev/output.css","utf-8")
5
+
6
+ const output=fs.writeFileSync("./output/output.css",([arbitrary,purge].join("\n")))
@@ -0,0 +1,97 @@
1
+ let fs = require("fs");
2
+ let path = require("path");
3
+
4
+ let allCssClassName = new Set();
5
+ let jetsPath = path.join(__dirname, "../Jets");
6
+ let allClasses = {};
7
+
8
+ let HTML_ROOT = path.join(__dirname, "../../");
9
+ let globalSeen = new Set();
10
+
11
+ let regexs = {
12
+ htmlClassRegex: /class(Name)?="([^"]+)"/g,
13
+ cssClassNameRegex: /\.([a-zA-Z_][a-zA-Z0-9_:\-]*)\s*\{/g,
14
+ cssBlockRegex: /\.([a-zA-Z_][a-zA-Z0-9_:\-]*)\s*\{([\s\S]*?)\}/g,
15
+ };
16
+
17
+ function getAllCssFiles(dir) {
18
+ let results = [];
19
+ let entries = fs.readdirSync(dir, { withFileTypes: true });
20
+
21
+ for (let entry of entries) {
22
+ let fullPath = path.join(dir, entry.name);
23
+
24
+ if (entry.isDirectory()) {
25
+ results = results.concat(getAllCssFiles(fullPath));
26
+ } else if (entry.name.endsWith(".css")) {
27
+ results.push(fullPath);
28
+ }
29
+ }
30
+
31
+ return results;
32
+ }
33
+
34
+ let allCssFiles = getAllCssFiles(jetsPath);
35
+
36
+ let outputFilePath = path.join(__dirname, "../outputDev/output.css");
37
+
38
+ fs.writeFileSync(outputFilePath, "");
39
+
40
+ function getAllSourceFiles(dir) {
41
+ let results = [];
42
+ let entries = fs.readdirSync(dir, { withFileTypes: true });
43
+
44
+ for (let entry of entries) {
45
+ let fullPath = path.join(dir, entry.name);
46
+
47
+ if (entry.isDirectory()) {
48
+ results = results.concat(getAllSourceFiles(fullPath));
49
+ } else if (
50
+ entry.name.endsWith(".html") ||
51
+ entry.name.endsWith(".jsx") ||
52
+ entry.name.endsWith(".tsx")
53
+ ) {
54
+ results.push(fullPath);
55
+ }
56
+ }
57
+
58
+ return results;
59
+ }
60
+
61
+ let sourceFiles = getAllSourceFiles(HTML_ROOT);
62
+
63
+ for (let file of sourceFiles) {
64
+ let content = fs.readFileSync(file, "utf-8");
65
+
66
+ for (let match of content.matchAll(regexs.htmlClassRegex)) {
67
+ let classList = match[2];
68
+
69
+ for (let className of classList.split(/\s+/)) {
70
+ if (!className) continue;
71
+ globalSeen.add(className);
72
+ }
73
+ }
74
+ }
75
+
76
+ for (let file of allCssFiles) {
77
+ let content = fs.readFileSync(file, "utf-8");
78
+
79
+ for (let match of content.matchAll(regexs.cssBlockRegex)) {
80
+ let className = match[1];
81
+ let body = match[2];
82
+
83
+ if (!globalSeen.has(className)) continue;
84
+ if (allClasses[className]) continue;
85
+
86
+ allClasses[className] = {};
87
+
88
+ for (let decl of body.split(";")) {
89
+ let [prop, value] = decl.split(":");
90
+ if (!prop || !value) continue;
91
+ allClasses[className][prop.trim()] = value.trim();
92
+ }
93
+
94
+ allCssClassName.add(className);
95
+ fs.appendFileSync(outputFilePath, `.${className}{${body}}\n`);
96
+ }
97
+ }
package/tools/init.js ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const projectRoot = process.cwd();
7
+ const pkgPath = path.join(projectRoot, "package.json");
8
+
9
+ if (!fs.existsSync(pkgPath)) {
10
+ console.log("āŒ No package.json found in this directory.");
11
+ process.exit(1);
12
+ }
13
+
14
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
15
+
16
+ pkg.scripts = pkg.scripts || {};
17
+
18
+ let addedSomething = false;
19
+
20
+ if (!pkg.scripts.dev) {
21
+ pkg.scripts.dev = "JetFast dev";
22
+ console.log("āœ… Added 'dev' script");
23
+ addedSomething = true;
24
+ } else {
25
+ console.log("āš ļø 'dev' script already exists — not modifying");
26
+ }
27
+
28
+ if (!pkg.scripts.build) {
29
+ pkg.scripts.build = "JetFast build";
30
+ console.log("āœ… Added 'build' script");
31
+ addedSomething = true;
32
+ } else {
33
+ console.log("āš ļø 'build' script already exists — not modifying");
34
+ }
35
+
36
+ if (addedSomething) {
37
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
38
+ console.log("šŸŽ‰ package.json updated successfully");
39
+ } else {
40
+ console.log("šŸ‘ Nothing to change — JetFast already configured");
41
+ }
@@ -0,0 +1,54 @@
1
+ const chokidar = require("chokidar");
2
+ const { exec } = require("child_process");
3
+ const path = require("path");
4
+
5
+ const ROOT = path.resolve(__dirname, "../../");
6
+
7
+ console.log("🧐 Watching HTML files in:", ROOT);
8
+
9
+ let timer = null;
10
+
11
+ function isIgnored(file) {
12
+ const normalized = file.replace(/\\/g, "/");
13
+
14
+ return (
15
+ normalized.includes("/node_modules/") ||
16
+ normalized.includes("/.git/") ||
17
+ normalized.includes("/JetFast/outputDev/") ||
18
+ normalized.includes("/JetFast/output/") ||
19
+ normalized.includes("/JetFast/Jets/") ||
20
+ normalized.endsWith(".tmp")
21
+ );
22
+ }
23
+
24
+ const watcher = chokidar.watch(ROOT, {
25
+ ignored: isIgnored,
26
+ ignoreInitial: true,
27
+ awaitWriteFinish: {
28
+ stabilityThreshold: 300,
29
+ pollInterval: 100,
30
+ },
31
+ });
32
+
33
+ function runGenerator(reason, file) {
34
+ console.log(`šŸ” ${reason}: ${file}`);
35
+
36
+ clearTimeout(timer);
37
+ timer = setTimeout(() => {
38
+ exec(
39
+ `node "${path.join(__dirname, "generate-arbitrary.js")}"`,
40
+ (err, stdout, stderr) => {
41
+ if (err) {
42
+ console.error("āŒ arbitrary error", err);
43
+ return;
44
+ }
45
+ },
46
+ );
47
+ }, 300);
48
+ }
49
+
50
+ watcher.on("add", (file) => runGenerator("add", file));
51
+ watcher.on("change", (file) => runGenerator("change", file));
52
+ watcher.on("unlink", (file) => runGenerator("unlink", file));
53
+
54
+ console.log("āœ… Watcher ready");