mtrl-addons 0.2.1 → 0.2.2

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/build.js CHANGED
@@ -1,201 +1,377 @@
1
1
  // build.js
2
- import { mkdir } from 'fs/promises'
3
- import { existsSync } from 'fs'
4
- import { join, dirname } from 'path'
5
- import { fileURLToPath } from 'url'
2
+ import { mkdir } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import { join, dirname, extname } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { watch } from "fs";
6
7
 
7
- const __dirname = dirname(fileURLToPath(import.meta.url))
8
- const isWatch = process.argv.includes('--watch')
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const isWatch = process.argv.includes("--watch");
9
10
  const isProduction =
10
- process.argv.includes('--production') ||
11
- process.env.NODE_ENV === 'production'
11
+ process.argv.includes("--production") ||
12
+ process.env.NODE_ENV === "production";
12
13
 
13
14
  // Define consistent output paths
14
- const DIST_DIR = join(__dirname, 'dist')
15
- const JS_OUTPUT = join(DIST_DIR, 'index.js')
16
- const MJS_OUTPUT = join(DIST_DIR, 'index.mjs')
15
+ const DIST_DIR = join(__dirname, "dist");
16
+ const JS_OUTPUT = join(DIST_DIR, "index.js");
17
+ const MJS_OUTPUT = join(DIST_DIR, "index.mjs");
18
+ const CSS_OUTPUT = join(DIST_DIR, "styles.css");
19
+ const STYLES_ENTRY = join(__dirname, "src/styles/index.scss");
17
20
 
18
21
  // Log build mode
19
- console.log(`Building in ${isProduction ? 'PRODUCTION' : 'DEVELOPMENT'} mode`)
22
+ console.log(`Building in ${isProduction ? "PRODUCTION" : "DEVELOPMENT"} mode`);
23
+
24
+ const buildStyles = async () => {
25
+ console.log("┌─────────────────────────────────────────");
26
+ console.log("│ SCSS Build");
27
+ console.log("│ Mode:", isProduction ? "PRODUCTION" : "DEVELOPMENT");
28
+ console.log("└─────────────────────────────────────────");
29
+
30
+ try {
31
+ // Check if source file exists
32
+ if (!existsSync(STYLES_ENTRY)) {
33
+ console.log("⚠️ No SCSS entry found at", STYLES_ENTRY);
34
+ return true; // Not an error, just no styles to build
35
+ }
36
+
37
+ // Build sass arguments
38
+ const sassArgs = [
39
+ "sass",
40
+ STYLES_ENTRY,
41
+ CSS_OUTPUT,
42
+ isProduction ? "--style=compressed" : "--style=expanded",
43
+ ];
44
+
45
+ // Add source map in development
46
+ if (!isProduction) {
47
+ sassArgs.push("--source-map");
48
+ } else {
49
+ sassArgs.push("--no-source-map");
50
+ }
51
+
52
+ const sassProcess = Bun.spawn(["npx", ...sassArgs], {
53
+ cwd: __dirname,
54
+ stdio: ["inherit", "pipe", "pipe"],
55
+ });
56
+
57
+ const stdout = await new Response(sassProcess.stdout).text();
58
+ const stderr = await new Response(sassProcess.stderr).text();
59
+ const exitCode = await sassProcess.exited;
60
+
61
+ if (exitCode !== 0) {
62
+ console.error("❌ SCSS build failed");
63
+ if (stdout.trim()) console.error("STDOUT:", stdout);
64
+ if (stderr.trim()) console.error("STDERR:", stderr);
65
+ return false;
66
+ }
67
+
68
+ // Get file size
69
+ const cssSize = existsSync(CSS_OUTPUT)
70
+ ? (await Bun.file(CSS_OUTPUT).size) / 1024
71
+ : 0;
72
+
73
+ console.log("✓ SCSS build successful");
74
+ console.log(` CSS bundle: ${cssSize.toFixed(2)} KB`);
75
+
76
+ return true;
77
+ } catch (error) {
78
+ console.error("❌ SCSS build error:", error.message);
79
+
80
+ // Check if sass is available
81
+ try {
82
+ const checkSass = Bun.spawn(["npx", "sass", "--version"], {
83
+ stdio: ["inherit", "pipe", "pipe"],
84
+ });
85
+ const versionExitCode = await checkSass.exited;
86
+
87
+ if (versionExitCode !== 0) {
88
+ console.error("💡 Sass compiler not found. Install it with:");
89
+ console.error(" npm install -D sass");
90
+ console.error(" or");
91
+ console.error(" bun add -D sass");
92
+ }
93
+ } catch {
94
+ console.error("💡 Sass compiler not found. Install it with:");
95
+ console.error(" npm install -D sass");
96
+ console.error(" or");
97
+ console.error(" bun add -D sass");
98
+ }
99
+
100
+ return false;
101
+ }
102
+ };
20
103
 
21
104
  const buildApp = async () => {
22
105
  try {
23
- console.log('┌─────────────────────────────────────────')
24
- console.log('│ JavaScript Build')
25
- console.log('│ Mode:', isProduction ? 'PRODUCTION' : 'DEVELOPMENT')
26
- console.log('│ Minify:', isProduction ? 'Yes' : 'No')
27
- console.log('│ Sourcemaps:', isProduction ? 'No' : 'Yes (inline)')
28
- console.log('└─────────────────────────────────────────')
106
+ console.log("┌─────────────────────────────────────────");
107
+ console.log("│ JavaScript Build");
108
+ console.log("│ Mode:", isProduction ? "PRODUCTION" : "DEVELOPMENT");
109
+ console.log("│ Minify:", isProduction ? "Yes" : "No");
110
+ console.log("│ Sourcemaps:", isProduction ? "No" : "Yes (inline)");
111
+ console.log("└─────────────────────────────────────────");
29
112
 
30
113
  // Create dist directory if it doesn't exist
31
- await mkdir(DIST_DIR, { recursive: true })
114
+ await mkdir(DIST_DIR, { recursive: true });
32
115
 
33
116
  // Build CJS version
34
117
  const cjsResult = await Bun.build({
35
- entrypoints: [join(__dirname, 'src/index.ts')],
118
+ entrypoints: [join(__dirname, "src/index.ts")],
36
119
  outdir: DIST_DIR,
37
120
  minify: isProduction,
38
- sourcemap: isProduction ? 'none' : 'inline',
39
- format: 'cjs',
40
- target: 'node',
41
- external: ['mtrl']
42
- })
121
+ sourcemap: isProduction ? "none" : "inline",
122
+ format: "cjs",
123
+ target: "node",
124
+ external: ["mtrl"],
125
+ });
43
126
 
44
127
  // Build ESM version
45
128
  const esmResult = await Bun.build({
46
- entrypoints: [join(__dirname, 'src/index.ts')],
129
+ entrypoints: [join(__dirname, "src/index.ts")],
47
130
  outdir: DIST_DIR,
48
131
  minify: isProduction,
49
- sourcemap: isProduction ? 'none' : 'inline',
50
- format: 'esm',
51
- target: 'node',
132
+ sourcemap: isProduction ? "none" : "inline",
133
+ format: "esm",
134
+ target: "node",
52
135
  naming: {
53
- entry: 'index.mjs'
136
+ entry: "index.mjs",
54
137
  },
55
- external: ['mtrl']
56
- })
138
+ external: ["mtrl"],
139
+ });
57
140
 
58
141
  if (!cjsResult.success || !esmResult.success) {
59
- console.error('❌ JavaScript build failed')
60
- console.error(cjsResult.logs)
61
- console.error(esmResult.logs)
62
- return false
142
+ console.error("❌ JavaScript build failed");
143
+ console.error(cjsResult.logs);
144
+ console.error(esmResult.logs);
145
+ return false;
63
146
  }
64
147
 
65
- console.log('✓ JavaScript build successful')
148
+ console.log("✓ JavaScript build successful");
66
149
  console.log(
67
- ` CJS bundle: ${((await Bun.file(JS_OUTPUT).size) / 1024).toFixed(2)} KB`
68
- )
150
+ ` CJS bundle: ${((await Bun.file(JS_OUTPUT).size) / 1024).toFixed(2)} KB`,
151
+ );
69
152
  console.log(
70
153
  ` ESM bundle: ${((await Bun.file(MJS_OUTPUT).size) / 1024).toFixed(
71
- 2
72
- )} KB`
73
- )
154
+ 2,
155
+ )} KB`,
156
+ );
74
157
 
75
158
  // Generate type definitions with better error handling
76
- console.log('Generating TypeScript declarations...')
159
+ console.log("Generating TypeScript declarations...");
77
160
 
78
161
  try {
79
162
  const tscProcess = Bun.spawn(
80
- ['tsc', '--emitDeclarationOnly', '--outDir', DIST_DIR],
163
+ ["tsc", "--emitDeclarationOnly", "--outDir", DIST_DIR],
81
164
  {
82
165
  cwd: __dirname,
83
- stdio: ['inherit', 'pipe', 'pipe']
84
- }
85
- )
166
+ stdio: ["inherit", "pipe", "pipe"],
167
+ },
168
+ );
86
169
 
87
170
  // Capture stdout and stderr
88
- const stdout = await new Response(tscProcess.stdout).text()
89
- const stderr = await new Response(tscProcess.stderr).text()
171
+ const stdout = await new Response(tscProcess.stdout).text();
172
+ const stderr = await new Response(tscProcess.stderr).text();
90
173
 
91
- const tscExitCode = await tscProcess.exited
174
+ const tscExitCode = await tscProcess.exited;
92
175
 
93
176
  if (tscExitCode !== 0) {
94
- console.error('❌ TypeScript declaration generation failed')
95
- console.error('Exit code:', tscExitCode)
177
+ console.warn(
178
+ "⚠️ TypeScript declaration generation had errors (non-blocking)",
179
+ );
96
180
  if (stdout.trim()) {
97
- console.error('STDOUT:', stdout)
181
+ console.warn(
182
+ "STDOUT:",
183
+ stdout.slice(0, 500) + (stdout.length > 500 ? "..." : ""),
184
+ );
98
185
  }
99
186
  if (stderr.trim()) {
100
- console.error('STDERR:', stderr)
187
+ console.warn(
188
+ "STDERR:",
189
+ stderr.slice(0, 500) + (stderr.length > 500 ? "..." : ""),
190
+ );
101
191
  }
102
192
 
103
193
  // Check if tsc is available
104
- const whichResult = Bun.spawn(['which', 'tsc'], { stdio: ['inherit', 'pipe', 'pipe'] })
105
- const tscPath = await new Response(whichResult.stdout).text()
194
+ const whichResult = Bun.spawn(["which", "tsc"], {
195
+ stdio: ["inherit", "pipe", "pipe"],
196
+ });
197
+ const tscPath = await new Response(whichResult.stdout).text();
106
198
  if (!tscPath.trim()) {
107
- console.error('💡 TypeScript compiler (tsc) not found. Install it with:')
108
- console.error(' npm install -g typescript')
109
- console.error(' or')
110
- console.error(' bun add -g typescript')
199
+ console.error(
200
+ "💡 TypeScript compiler (tsc) not found. Install it with:",
201
+ );
202
+ console.error(" npm install -g typescript");
203
+ console.error(" or");
204
+ console.error(" bun add -g typescript");
111
205
  }
112
206
 
113
- return false
207
+ // Continue build despite tsc errors (JS bundles are still valid)
208
+ return true;
114
209
  }
115
210
 
116
- console.log('✓ TypeScript declarations generated')
211
+ console.log("✓ TypeScript declarations generated");
117
212
  if (stdout.trim()) {
118
- console.log('TSC output:', stdout)
213
+ console.log("TSC output:", stdout);
119
214
  }
120
215
 
121
- return true
216
+ return true;
122
217
  } catch (tscError) {
123
- console.error('❌ Error running TypeScript compiler:', tscError.message)
218
+ console.warn("⚠️ Error running TypeScript compiler:", tscError.message);
124
219
 
125
220
  // Check if TypeScript is installed
126
221
  try {
127
- const checkTsc = Bun.spawn(['tsc', '--version'], { stdio: ['inherit', 'pipe', 'pipe'] })
128
- const versionOutput = await new Response(checkTsc.stdout).text()
129
- const versionExitCode = await checkTsc.exited
222
+ const checkTsc = Bun.spawn(["tsc", "--version"], {
223
+ stdio: ["inherit", "pipe", "pipe"],
224
+ });
225
+ const versionOutput = await new Response(checkTsc.stdout).text();
226
+ const versionExitCode = await checkTsc.exited;
130
227
 
131
228
  if (versionExitCode === 0) {
132
- console.log('TypeScript version:', versionOutput.trim())
229
+ console.log("TypeScript version:", versionOutput.trim());
133
230
  } else {
134
- console.error('💡 TypeScript compiler not properly installed. Install with:')
135
- console.error(' npm install -g typescript')
136
- console.error(' or')
137
- console.error(' bun add -g typescript')
231
+ console.warn(
232
+ "💡 TypeScript compiler not properly installed. Install with:",
233
+ );
234
+ console.warn(" npm install -g typescript");
235
+ console.warn(" or");
236
+ console.warn(" bun add -g typescript");
138
237
  }
139
238
  } catch (versionError) {
140
- console.error('💡 TypeScript compiler not found. Install it with:')
141
- console.error(' npm install -g typescript')
142
- console.error(' or')
143
- console.error(' bun add -g typescript')
239
+ console.warn("💡 TypeScript compiler not found. Install it with:");
240
+ console.warn(" npm install -g typescript");
241
+ console.warn(" or");
242
+ console.warn(" bun add -g typescript");
144
243
  }
145
244
 
146
- return false
245
+ // Continue build despite tsc errors (JS bundles are still valid)
246
+ return true;
147
247
  }
148
248
  } catch (error) {
149
- console.error('❌ JavaScript build error:', error)
150
- console.error(error.stack)
151
- return false
249
+ console.error("❌ JavaScript build error:", error);
250
+ console.error(error.stack);
251
+ return false;
152
252
  }
153
- }
253
+ };
254
+
255
+ const buildAll = async () => {
256
+ const jsSuccess = await buildApp();
257
+ const cssSuccess = await buildStyles();
258
+ return jsSuccess && cssSuccess;
259
+ };
154
260
 
155
261
  const build = async () => {
156
262
  try {
157
- const startTime = Date.now()
263
+ const startTime = Date.now();
158
264
 
159
- console.log('┌───────────────────────────────────────────────')
160
- console.log('│ 🚀 MTRL-Addons Build Process')
161
- console.log('│ Mode:', isProduction ? '🏭 PRODUCTION' : '🔧 DEVELOPMENT')
162
- console.log('│ Watch:', isWatch ? '✓ Enabled' : '✗ Disabled')
163
- console.log('└───────────────────────────────────────────────')
164
- console.log('')
265
+ console.log("┌───────────────────────────────────────────────");
266
+ console.log("│ 🚀 MTRL-Addons Build Process");
267
+ console.log("│ Mode:", isProduction ? "🏭 PRODUCTION" : "🔧 DEVELOPMENT");
268
+ console.log("│ Watch:", isWatch ? "✓ Enabled" : "✗ Disabled");
269
+ console.log("└───────────────────────────────────────────────");
270
+ console.log("");
165
271
 
166
272
  // Create output directory
167
- await mkdir(DIST_DIR, { recursive: true })
273
+ await mkdir(DIST_DIR, { recursive: true });
168
274
 
169
- // Build JavaScript
170
- const jsSuccess = await buildApp()
275
+ // Build JavaScript and CSS
276
+ const buildSuccess = await buildAll();
171
277
 
172
- const buildTime = ((Date.now() - startTime) / 1000).toFixed(2)
278
+ const buildTime = ((Date.now() - startTime) / 1000).toFixed(2);
173
279
 
174
280
  if (isWatch && !isProduction) {
175
- console.log('')
176
- console.log('┌───────────────────────────────────────────────')
177
- console.log('│ 👀 Watching for changes...')
178
- console.log('└───────────────────────────────────────────────')
281
+ console.log("");
282
+ console.log("┌───────────────────────────────────────────────");
283
+ console.log("│ 👀 Watching for changes...");
284
+ console.log("└───────────────────────────────────────────────");
285
+
286
+ // Watch src directory for changes
287
+ const srcDir = join(__dirname, "src");
288
+ let debounceTimer = null;
289
+ let isBuilding = false;
290
+
291
+ const rebuild = async (changedFile) => {
292
+ if (isBuilding) return;
293
+ isBuilding = true;
294
+
295
+ const ext = changedFile ? extname(changedFile) : "";
296
+ const isStyleChange = [".scss", ".css"].includes(ext);
297
+ const isJsChange = [".ts", ".tsx"].includes(ext);
298
+
299
+ console.log("");
300
+ console.log("┌───────────────────────────────────────────────");
301
+ console.log(
302
+ `│ 🔄 Change detected${changedFile ? ` (${changedFile})` : ""}, rebuilding...`,
303
+ );
304
+ console.log("└───────────────────────────────────────────────");
305
+
306
+ const rebuildStart = Date.now();
307
+ let success;
308
+
309
+ // Selective rebuild based on file type
310
+ if (isStyleChange) {
311
+ success = await buildStyles();
312
+ } else if (isJsChange) {
313
+ success = await buildApp();
314
+ } else {
315
+ success = await buildAll();
316
+ }
317
+
318
+ const rebuildTime = ((Date.now() - rebuildStart) / 1000).toFixed(2);
319
+
320
+ console.log("");
321
+ console.log(
322
+ `│ ${success ? "✅" : "⚠️"} Rebuild completed in ${rebuildTime}s`,
323
+ );
324
+ console.log("│ 👀 Watching for changes...");
325
+ console.log("└───────────────────────────────────────────────");
326
+
327
+ isBuilding = false;
328
+ };
329
+
330
+ const watchHandler = (eventType, filename) => {
331
+ if (!filename) return;
332
+
333
+ // Only watch .ts, .tsx, .scss and .css files
334
+ const ext = extname(filename);
335
+ if (![".ts", ".tsx", ".scss", ".css"].includes(ext)) return;
336
+
337
+ // Debounce rapid changes
338
+ if (debounceTimer) clearTimeout(debounceTimer);
339
+ debounceTimer = setTimeout(() => {
340
+ rebuild(filename);
341
+ }, 100);
342
+ };
343
+
344
+ // Watch recursively using fs.watch
345
+ const watchDir = (dir) => {
346
+ watch(dir, { recursive: true }, watchHandler);
347
+ };
348
+
349
+ watchDir(srcDir);
350
+ console.log(`│ Watching: ${srcDir}`);
179
351
 
180
- // Watch implementation would go here
352
+ // Keep process alive
353
+ process.on("SIGINT", () => {
354
+ console.log("\n│ 👋 Stopping watch mode...");
355
+ process.exit(0);
356
+ });
181
357
  } else {
182
- console.log('')
183
- console.log('┌───────────────────────────────────────────────')
184
- console.log(`│ ✅ Build completed in ${buildTime}s`)
185
- if (!jsSuccess) {
186
- console.log('│ ⚠️ Build completed with some errors')
358
+ console.log("");
359
+ console.log("┌───────────────────────────────────────────────");
360
+ console.log(`│ ✅ Build completed in ${buildTime}s`);
361
+ if (!buildSuccess) {
362
+ console.log("│ ⚠️ Build completed with some errors");
187
363
  }
188
- console.log('└───────────────────────────────────────────────')
364
+ console.log("└───────────────────────────────────────────────");
189
365
 
190
366
  // Only exit with error code in non-watch mode if there were failures
191
- if (!isWatch && !jsSuccess) {
192
- process.exit(1)
367
+ if (!isWatch && !buildSuccess) {
368
+ process.exit(1);
193
369
  }
194
370
  }
195
371
  } catch (error) {
196
- console.error('❌ Build failed with error:', error)
197
- process.exit(1)
372
+ console.error("❌ Build failed with error:", error);
373
+ process.exit(1);
198
374
  }
199
- }
375
+ };
200
376
 
201
- build()
377
+ build();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mtrl-addons",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Additional components and utilities for the mtrl system, featuring forms, specialized elements, and extended functionality for modern applications",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -43,6 +43,7 @@
43
43
  "jsdom": "^26.1.0",
44
44
  "madge": "^8.0.0",
45
45
  "mtrl": "^0.2.8",
46
+ "sass": "^1.94.2",
46
47
  "standard": "^17.0.0",
47
48
  "typescript": "^5.0.0"
48
49
  }