vanilla-jet 1.4.2 → 1.4.3

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.
@@ -41,7 +41,6 @@ async function createFileIfnotExists(content) {
41
41
  // -- Helpers
42
42
  function processCwd() {
43
43
  return process.cwd()
44
- .replace('/.grunt', '')
45
44
  .replace('/.scripts', '');
46
45
  }
47
46
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@ All notable project changes are documented in this file.
4
4
 
5
5
  The format follows a structure inspired by Keep a Changelog and semantic versioning.
6
6
 
7
+ ## [1.4.3] - 2026-02-19
8
+
9
+ ### Removed
10
+
11
+ - Grunt build artifacts: removed `.grunt/` folder, `build_styles_task.js`, and `compile_html.js`.
12
+ - Build pipeline now uses only Gulp; template compilation moved to `scripts/compile_html.js`.
13
+
14
+ ### Changed
15
+
16
+ - `gulpfile.js`: `compileTemplates` now invokes `node scripts/compile_html.js` instead of `.grunt/compile_html.js`.
17
+ - `framework/dipper.js`, `.scripts/generate_packages_json.js`: removed `.grunt` references from `processCwd` helpers.
18
+
19
+ ### Fixed
20
+
21
+ - **Reliability under rapid reloads (F5)**: server no longer stops responding after repeated refreshes.
22
+ - Removed `fs.watch` per static file (`staticFileWatchers`); could exhaust resources with prolonged use.
23
+ - Added fallback to `404` for routes without a handled static extension (avoids hanging requests).
24
+ - Destroy file streams when client disconnects (`res.on('close')`) to avoid orphaned streams.
25
+ - Applied same stream cleanup in `response.render()` for HTML template delivery.
26
+ - Added defensive server timeouts: `requestTimeout`, `headersTimeout`, `keepAliveTimeout` (configurable via `settings.profile`).
27
+
28
+ ### Compatibility notes
29
+
30
+ - No public API changes.
31
+ - Build output and route behavior unchanged; only internal reliability improvements.
32
+
7
33
  ## [1.4.2] - 2026-02-19
8
34
 
9
35
  ### Changed
@@ -112,4 +138,5 @@ The format follows a structure inspired by Keep a Changelog and semantic version
112
138
  [1.3.5]: https://github.com/nalancer08/VanillaJet/releases/tag/v1.3.5
113
139
  [1.3.6]: https://github.com/nalancer08/VanillaJet/releases/tag/v1.3.6
114
140
  [1.4.2]: https://github.com/nalancer08/VanillaJet/releases/tag/v1.4.2
141
+ [1.4.3]: https://github.com/nalancer08/VanillaJet/releases/tag/v1.4.3
115
142
  [1.4.1]: https://github.com/nalancer08/VanillaJet/releases/tag/v1.4.1
package/README.md CHANGED
@@ -6,7 +6,7 @@ Node.js framework for building SPA applications with a JS/CSS/HTML build pipelin
6
6
 
7
7
  ## Current version
8
8
 
9
- - Version: `1.4.2`
9
+ - Version: `1.4.3`
10
10
  - Changelog: see [`CHANGELOG.md`](./CHANGELOG.md)
11
11
  - Improvement plan (performance and backward compatibility): see `ROADMAP_INTEGRAL.md`
12
12
 
@@ -93,6 +93,8 @@ VanillaJet expects a structure similar to:
93
93
 
94
94
  ## Build pipeline (summary)
95
95
 
96
+ Gulp-based pipeline (no Grunt):
97
+
96
98
  - Minifies JS and concatenates into `public/scripts/vanilla.min.js`
97
99
  - Compiles LESS and generates `public/styles/app.min.css`
98
100
  - Compiles templates and generates `public/pages/home.html`
@@ -545,7 +545,6 @@ Dipper.prototype.includeEnvironment = function() {
545
545
  Dipper.prototype.processCwd = function() {
546
546
 
547
547
  let cwd = process.cwd()
548
- .replace('/.grunt', '')
549
548
  .replace('/.scripts', '')
550
549
  .replace('/node_modules', '')
551
550
  .replace('/vanilla-jet', '');
@@ -111,6 +111,11 @@ class Response {
111
111
  fileStream.on('error', () => {
112
112
  obj.error404();
113
113
  });
114
+ obj.res.on('close', () => {
115
+ if (!obj.res.writableEnded) {
116
+ fileStream.destroy();
117
+ }
118
+ });
114
119
  fileStream.pipe(obj.res);
115
120
  });
116
121
  }
@@ -19,7 +19,6 @@ class Router {
19
19
  this.staticBasePath = this.cwd.replace('core/framework', '');
20
20
  this.staticMetadataCache = new Map();
21
21
  this.staticResolutionCache = new Map();
22
- this.staticFileWatchers = new Map();
23
22
  this.staticStreamChunkSize = 128 * 1024;
24
23
  this.mimes = {
25
24
  'png': 'image/png',
@@ -149,12 +148,18 @@ class Router {
149
148
  res.writeHead(500);
150
149
  res.end('Server Error');
151
150
  });
151
+ res.on('close', () => {
152
+ if (!res.writableEnded) {
153
+ fileStream.destroy();
154
+ }
155
+ });
152
156
 
153
157
  res.writeHead(200, staticHeaders);
154
158
  fileStream.pipe(res);
155
- res.on('close', () => {});
156
159
  });
157
- }
160
+ } else {
161
+ return obj.onNotFound(response);
162
+ }
158
163
  }
159
164
  }
160
165
  }), handled = false;
@@ -181,7 +186,6 @@ class Router {
181
186
  };
182
187
 
183
188
  obj.staticMetadataCache.set(filename, metadata);
184
- obj.watchStaticFile(filename);
185
189
  callback(null, metadata);
186
190
  });
187
191
  }
@@ -310,41 +314,6 @@ class Router {
310
314
  });
311
315
  }
312
316
 
313
- watchStaticFile(filename) {
314
- let obj = this;
315
- if (obj.staticFileWatchers.has(filename)) {
316
- return;
317
- }
318
-
319
- try {
320
- let watcher = fs.watch(filename, (eventType) => {
321
- obj.staticMetadataCache.delete(filename);
322
- obj.staticResolutionCache.clear();
323
- if (eventType === 'rename') {
324
- let renamedWatcher = obj.staticFileWatchers.get(filename);
325
- if (renamedWatcher) {
326
- renamedWatcher.close();
327
- }
328
- obj.staticFileWatchers.delete(filename);
329
- }
330
- });
331
-
332
- watcher.on('error', () => {
333
- obj.staticMetadataCache.delete(filename);
334
- obj.staticResolutionCache.clear();
335
- let activeWatcher = obj.staticFileWatchers.get(filename);
336
- if (activeWatcher) {
337
- activeWatcher.close();
338
- }
339
- obj.staticFileWatchers.delete(filename);
340
- });
341
-
342
- obj.staticFileWatchers.set(filename, watcher);
343
- } catch (err) {
344
- // If watch cannot be created, keep runtime behavior and continue.
345
- }
346
- }
347
-
348
317
  isNotModified(req, metadata) {
349
318
  let ifNoneMatch = req.headers['if-none-match'];
350
319
  if (ifNoneMatch) {
@@ -32,7 +32,10 @@ class Server {
32
32
  _.defaults(opts, {
33
33
  https_server: false,
34
34
  wsServer: false,
35
- enable_precompressed_negotiation: false
35
+ enable_precompressed_negotiation: false,
36
+ request_timeout_ms: 30000,
37
+ headers_timeout_ms: 35000,
38
+ keep_alive_timeout_ms: 5000
36
39
  });
37
40
  obj.options = opts;
38
41
 
@@ -91,6 +94,9 @@ class Server {
91
94
  }
92
95
 
93
96
  // -- Set the port
97
+ obj.httpx.requestTimeout = Number(obj.options.request_timeout_ms) || 30000;
98
+ obj.httpx.headersTimeout = Number(obj.options.headers_timeout_ms) || 35000;
99
+ obj.httpx.keepAliveTimeout = Number(obj.options.keep_alive_timeout_ms) || 5000;
94
100
  obj.httpx.listen(obj.options.port || 8080);
95
101
  }
96
102
 
package/gulpfile.js CHANGED
@@ -113,7 +113,7 @@ function compressCss() {
113
113
  // Template compilation
114
114
  function compileTemplates() {
115
115
  return gulp.src('.')
116
- .pipe(shell([`node .grunt/compile_html.js`]));
116
+ .pipe(shell([`node scripts/compile_html.js`]));
117
117
  }
118
118
 
119
119
  // Watch task
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-jet",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "VannilaJet framework",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -2,7 +2,6 @@
2
2
  const path = require("path"),
3
3
  fs = require("fs"),
4
4
  nunjucks = require('nunjucks'),
5
- identifier = 'templates',
6
5
  chalk = require('chalk'),
7
6
  zlib = require('zlib');
8
7
 
@@ -43,9 +42,11 @@ function main() {
43
42
  // -- Get home.html
44
43
  let homePageName = 'home.html';
45
44
  getHtmlFromPage(homePageName).then((htmlContent) => {
46
- if (htmlContent) {
45
+ if (htmlContent) {
46
+ // -- Compile the htmlContent
47
+ const compiledHtmlContent = compileTemplate(htmlContent);
47
48
  // -- Divide content line by line
48
- const htmlContentLines = htmlContent.split('\n');
49
+ const htmlContentLines = compiledHtmlContent.split('\n');
49
50
  let lines = Array.from(htmlContentLines);
50
51
  // -- Iterate over each line
51
52
  for (let line of htmlContentLines) {
@@ -58,7 +59,7 @@ function main() {
58
59
  // -- Get template name
59
60
  var templateName = line.replace('include::', '');
60
61
  // -- Check if its name "templates" add all templates if not add specific one
61
- if (templateName === identifier) {
62
+ if (templateName === 'templates') {
62
63
 
63
64
  let allTemplatesCompiled = '';
64
65
  for (let templateName in templates) {
@@ -211,7 +212,7 @@ function cleanALine(line) {
211
212
 
212
213
  function processCwd() {
213
214
  return process.cwd()
214
- .replace('/.grunt', '')
215
+ .replace('/scripts', '')
215
216
  .replace('/gulp', '')
216
217
  .replace('/node_modules/vanilla-jet', '');
217
- }
218
+ }
@@ -1,30 +0,0 @@
1
- module.exports = function(grunt) {
2
- grunt.registerTask('buildLess', 'Compile admin.less and add .section.less', function() {
3
-
4
- // -- Functions
5
- function getCleanedCWD() {
6
- const cwd = process.cwd();
7
- return cwd
8
- .replace('/node_modules', '')
9
- .replace('/vanilla-jet', '')
10
- .replace('/.grunt', '');
11
- }
12
-
13
- // -- Content
14
- let adminContent = grunt.file.read(`${getCleanedCWD()}/assets/styles/less/admin.less`);
15
- let sectionFiles = grunt.file.expand([
16
- `${getCleanedCWD()}/assets/styles/less/sections/**/*.section.less`,
17
- `${getCleanedCWD()}/assets/styles/less/sections/*.section.less`
18
- ]);
19
-
20
- let combinedContent = adminContent + '\n';
21
- sectionFiles.forEach(function(filePath) {
22
- let sectionContent = grunt.file.read(filePath);
23
- combinedContent += `\n/* ${filePath} */\n` + sectionContent;
24
- });
25
-
26
- // -- New file
27
- grunt.file.write(`${getCleanedCWD()}/assets/styles/less/admin_build.less`, combinedContent);
28
- grunt.task.run(['less']);
29
- });
30
- };