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.
- package/.scripts/generate_packages_json.js +0 -1
- package/CHANGELOG.md +27 -0
- package/README.md +3 -1
- package/framework/dipper.js +0 -1
- package/framework/response.js +5 -0
- package/framework/router.js +8 -39
- package/framework/server.js +7 -1
- package/gulpfile.js +1 -1
- package/package.json +1 -1
- package/{.grunt → scripts}/compile_html.js +7 -6
- package/.grunt/build_styles_task.js +0 -30
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.
|
|
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`
|
package/framework/dipper.js
CHANGED
|
@@ -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', '');
|
package/framework/response.js
CHANGED
package/framework/router.js
CHANGED
|
@@ -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) {
|
package/framework/server.js
CHANGED
|
@@ -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
package/package.json
CHANGED
|
@@ -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 =
|
|
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 ===
|
|
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('
|
|
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
|
-
};
|