vaderjs 2.3.4 → 2.3.5

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.
Files changed (2) hide show
  1. package/main.js +101 -52
  2. package/package.json +1 -1
package/main.js CHANGED
@@ -1,15 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- /**
3
- * VaderJS Build & Development Script
4
- *
5
- * This script handles building the VaderJS framework, your application code,
6
- * and serving it in a local development environment with live reloading.
7
- *
8
- * Commands:
9
- * bun run vaderjs build - Builds the project for production.
10
- * bun run vaderjs dev - Starts the dev server with HMR and file watching.
11
- * bun run vaderjs serve - Builds and serves the production output.
12
- */
2
+
13
3
 
14
4
  import { build, serve } from "bun";
15
5
  import fs from "fs/promises";
@@ -93,9 +83,10 @@ const vaderAPI = {
93
83
 
94
84
  async function loadConfig() {
95
85
  try {
96
- const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
86
+ const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
97
87
  return configModule.default || configModule;
98
88
  } catch {
89
+ console.log(path.join(PROJECT_ROOT, "vaderjs.config.js"))
99
90
  logger.warn("No 'vader.config.js' found, using defaults.");
100
91
  return {};
101
92
  }
@@ -149,10 +140,43 @@ async function buildVaderCore() {
149
140
  function patchHooksUsage(code) {
150
141
  return code.replace(/import\s+{[^}]*use(State|Effect|Memo|Navigation)[^}]*}\s+from\s+['"]vaderjs['"];?\n?/g, "");
151
142
  }
143
+ function publicAssetPlugin() {
144
+ return {
145
+ name: "public-asset-replacer",
146
+ setup(build) {
147
+ build.onLoad({ filter: /\.(js|ts|jsx|tsx|html)$/ }, async (args) => {
148
+ let code = await fs.readFile(args.path, "utf8");
149
+
150
+ code = code.replace(/\{\{public:(.+?)\}\}/g, (_, relPath) => {
151
+ const absPath = path.join(PUBLIC_DIR, relPath.trim());
152
+ if (fsSync.existsSync(absPath)) {
153
+ return "/" + relPath.trim().replace(/\\/g, "/");
154
+ }
155
+ logger.warn(`Public asset not found: ${relPath}`);
156
+ return relPath;
157
+ });
158
+
159
+ return {
160
+ contents: code,
161
+ loader: args.path.endsWith(".html")
162
+ ? "text"
163
+ : args.path.endsWith(".tsx")
164
+ ? "tsx"
165
+ : args.path.endsWith(".jsx")
166
+ ? "jsx"
167
+ : args.path.endsWith(".ts")
168
+ ? "ts"
169
+ : "js",
170
+ };
171
+ });
172
+ },
173
+ };
174
+ }
152
175
 
153
176
  /**
154
177
  * Step 3: Pre-processes all files in `/src` into a temporary directory.
155
178
  */
179
+
156
180
  async function preprocessSources(srcDir, tempDir) {
157
181
  await fs.mkdir(tempDir, { recursive: true });
158
182
  for (const entry of await fs.readdir(srcDir, { withFileTypes: true })) {
@@ -163,7 +187,7 @@ async function preprocessSources(srcDir, tempDir) {
163
187
  await preprocessSources(srcPath, destPath);
164
188
  } else if (/\.(tsx|jsx|ts|js)$/.test(entry.name)) {
165
189
  let content = await fs.readFile(srcPath, "utf8");
166
- content = patchHooksUsage(content);
190
+ content = patchHooksUsage(content);
167
191
  await fs.writeFile(destPath, content);
168
192
  } else {
169
193
  await fs.copyFile(srcPath, destPath);
@@ -201,6 +225,9 @@ async function buildSrc() {
201
225
  jsxImportSource: "vaderjs",
202
226
  target: "browser",
203
227
  minify: false,
228
+ plugins: [
229
+ publicAssetPlugin(),
230
+ ],
204
231
  external: ["vaderjs"],
205
232
  });
206
233
  }
@@ -222,57 +249,61 @@ async function copyPublicAssets() {
222
249
  return;
223
250
  }
224
251
 
225
- // Ensure the dist directory exists
226
252
  if (!fsSync.existsSync(DIST_DIR)) {
227
253
  await fs.mkdir(DIST_DIR, { recursive: true });
228
254
  }
229
255
 
230
- const devClientScript = isDev ? `
231
- <script>
232
- new WebSocket("ws://" + location.host + "/__hmr").onmessage = (msg) => {
233
- if (msg.data === "reload") location.reload();
234
- };
235
- </script>` : "";
256
+ const devClientScript = isDev
257
+ ? `<script>
258
+ new WebSocket("ws://" + location.host + "/__hmr").onmessage = (msg) => {
259
+ if (msg.data === "reload") location.reload();
260
+ };
261
+ </script>`
262
+ : "";
236
263
 
237
264
  const entries = fsSync.readdirSync(APP_DIR, { recursive: true })
238
265
  .filter(file => /index\.(jsx|tsx)$/.test(file))
239
266
  .map(file => ({
240
- name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
241
- path: path.join(APP_DIR, file)
267
+ name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
268
+ path: path.join(APP_DIR, file)
242
269
  }));
243
270
 
271
+ // Helper to resolve any asset path from /public
272
+ function resolvePublicPath(p) {
273
+ const assetPath = p.replace(/^(\.\/|\/)/, ""); // strip leading ./ or /
274
+ const absPath = path.join(PUBLIC_DIR, assetPath);
275
+ if (fsSync.existsSync(absPath)) {
276
+ return "/" + assetPath.replace(/\\/g, "/");
277
+ }
278
+ return p; // leave unchanged if not in public
279
+ }
280
+
244
281
  for (const { name, path: entryPath } of entries) {
245
- // Check for the specific case where 'name' could be 'index.js' and prevent duplication
246
282
  const outDir = path.join(DIST_DIR, name === 'index' ? '' : name);
247
- const outJsPath = path.join(outDir, 'index.js'); // Output JavaScript file path
248
-
249
- // Ensure the output directory exists
283
+ const outJsPath = path.join(outDir, 'index.js');
250
284
  await fs.mkdir(outDir, { recursive: true });
251
285
 
252
- // **FIXED CSS HANDLING**: Find, copy, and correctly link CSS files
286
+ // --- CSS HANDLING ---
253
287
  const cssLinks = [];
254
- const cssContent = await fs.readFile(entryPath, "utf8");
255
- const cssImports = [...cssContent.matchAll(/import\s+['"](.*\.css)['"]/g)];
256
-
288
+ let content = await fs.readFile(entryPath, "utf8");
289
+ const cssImports = [...content.matchAll(/import\s+['"](.*\.css)['"]/g)];
257
290
  for (const match of cssImports) {
258
- const cssImportPath = match[1]; // e.g., './styles.css'
259
- const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
260
- if (fsSync.existsSync(sourceCssPath)) {
261
- const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
262
- const destCssPath = path.join(DIST_DIR, relativeCssPath);
263
-
264
- await fs.mkdir(path.dirname(destCssPath), { recursive: true });
265
- await fs.copyFile(sourceCssPath, destCssPath);
266
-
267
- const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
268
- cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
269
- } else {
270
- logger.warn(`CSS file not found: ${sourceCssPath}`);
271
- }
291
+ const cssImportPath = match[1];
292
+ const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
293
+ if (fsSync.existsSync(sourceCssPath)) {
294
+ const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
295
+ const destCssPath = path.join(DIST_DIR, relativeCssPath);
296
+ await fs.mkdir(path.dirname(destCssPath), { recursive: true });
297
+ await fs.copyFile(sourceCssPath, destCssPath);
298
+ const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
299
+ cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
300
+ } else {
301
+ logger.warn(`CSS file not found: ${sourceCssPath}`);
302
+ }
272
303
  }
273
304
 
274
- // Update the script tag to use relative paths for index.js
275
- const htmlContent = `<!DOCTYPE html>
305
+ // --- HTML GENERATION ---
306
+ let htmlContent = `<!DOCTYPE html>
276
307
  <html lang="en">
277
308
  <head>
278
309
  <meta charset="UTF-8" />
@@ -286,37 +317,54 @@ async function copyPublicAssets() {
286
317
  <script type="module">
287
318
  import App from '${name !== 'index' ? "/" + name : ''}/index.js';
288
319
  import * as Vader from '/src/vader/index.js';
289
- window.Vader = Vader
320
+ window.Vader = Vader;
290
321
  Vader.render(Vader.createElement(App, null), document.getElementById("app"));
291
322
  </script>
292
323
  ${devClientScript}
293
324
  </body>
294
325
  </html>`;
295
326
 
296
- await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
327
+ // --- FIX ASSET PATHS IN HTML ---
328
+ htmlContent = htmlContent.replace(
329
+ /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
330
+ (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
331
+ );
297
332
 
298
- // Log for debugging
333
+ await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
299
334
 
300
- // Build the JavaScript file and ensure it uses the correct paths
335
+ // --- JS BUILD ---
301
336
  await build({
302
337
  entrypoints: [entryPath],
303
- outdir: outDir, // Pass the directory path to outdir
338
+ outdir: outDir,
304
339
  target: "browser",
305
340
  minify: false,
306
341
  sourcemap: "external",
307
342
  external: ["vaderjs"],
308
343
  jsxFactory: "e",
309
344
  jsxFragment: "Fragment",
345
+ plugins: [
346
+ publicAssetPlugin(),
347
+ ],
310
348
  jsxImportSource: "vaderjs",
311
349
  });
312
350
 
313
- // After build, replace the 'vaderjs' import to the correct path
351
+ // --- FIX IMPORT PATHS IN JS ---
314
352
  let jsContent = await fs.readFile(outJsPath, "utf8");
353
+
354
+ // Vader import fix
315
355
  jsContent = jsContent.replace(/from\s+['"]vaderjs['"]/g, `from '/src/vader/index.js'`);
356
+
357
+ // Asset path fix for JS
358
+ jsContent = jsContent.replace(
359
+ /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
360
+ (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
361
+ );
362
+
316
363
  await fs.writeFile(outJsPath, jsContent);
317
364
  }
318
365
  }
319
366
 
367
+
320
368
 
321
369
 
322
370
  async function buildAll(isDev = false) {
@@ -442,6 +490,7 @@ console.log(banner);
442
490
  const command = process.argv[2];
443
491
 
444
492
  if (command === "dev") {
493
+ globalThis.isDev = true
445
494
  await runDevServer();
446
495
  } else if (command === "build") {
447
496
  await buildAll(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"