@nitronjs/framework 0.3.2 → 0.3.4
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/cli/njs.js +1 -1
- package/lib/Build/CssBuilder.js +152 -136
- package/lib/Build/FileAnalyzer.js +52 -35
- package/lib/Build/Manager.js +144 -41
- package/lib/Build/ModuleGraph.js +84 -0
- package/lib/Build/PropUsageAnalyzer.js +2 -2
- package/lib/Build/plugins.js +35 -0
- package/lib/Console/Commands/DevCommand.js +301 -258
- package/lib/Date/DateTime.js +22 -2
- package/lib/Dev/DevIndicator.js +2 -1
- package/lib/HMR/Server.js +93 -170
- package/lib/Runtime/Entry.js +3 -0
- package/lib/View/Client/hmr-client.js +217 -219
- package/lib/View/Client/refresh-entry.cjs +1 -0
- package/lib/View/View.js +12 -7
- package/lib/index.d.ts +2 -0
- package/package.json +8 -6
- /package/skeleton/database/migrations/{2025_01_01_00_00_users.js → 2025_01_01_00_00_create_users.js} +0 -0
|
@@ -1,219 +1,217 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
function escapeHtml(str) {
|
|
204
|
-
return String(str || "")
|
|
205
|
-
.replace(/&/g, "&")
|
|
206
|
-
.replace(/</g, "<")
|
|
207
|
-
.replace(/>/g, ">");
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
})();
|
|
1
|
+
(function() {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var RSC_ENDPOINT = "/__nitron/rsc";
|
|
5
|
+
var ws = null;
|
|
6
|
+
var reconnectTimer = null;
|
|
7
|
+
|
|
8
|
+
function connect() {
|
|
9
|
+
if (ws) return;
|
|
10
|
+
|
|
11
|
+
var protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
|
12
|
+
var url = protocol + "//" + location.host + "/__nitron_hmr";
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
ws = new WebSocket(url);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
ws.onopen = function() {
|
|
22
|
+
window.__nitron_hmr_connected__ = true;
|
|
23
|
+
hideErrorOverlay();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
ws.onclose = function() {
|
|
27
|
+
window.__nitron_hmr_connected__ = false;
|
|
28
|
+
ws = null;
|
|
29
|
+
|
|
30
|
+
clearTimeout(reconnectTimer);
|
|
31
|
+
reconnectTimer = setTimeout(connect, 1000);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
ws.onerror = function() {
|
|
35
|
+
window.__nitron_hmr_connected__ = false;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
ws.onmessage = function(event) {
|
|
39
|
+
var msg;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
msg = JSON.parse(event.data);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (msg.type === "change") {
|
|
49
|
+
hideErrorOverlay();
|
|
50
|
+
|
|
51
|
+
if (msg.changeType === "css") {
|
|
52
|
+
refreshCss();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
refetchRSC(msg.cssChanged);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (msg.type === "fast-refresh") {
|
|
60
|
+
hideErrorOverlay();
|
|
61
|
+
handleFastRefresh(msg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (msg.type === "reload") {
|
|
65
|
+
location.reload();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (msg.type === "error") {
|
|
69
|
+
showErrorOverlay(msg.message || "Unknown error", msg.file);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseLengthPrefixed(text) {
|
|
75
|
+
var nl = text.indexOf("\n");
|
|
76
|
+
if (nl === -1) return null;
|
|
77
|
+
|
|
78
|
+
var len = parseInt(text.substring(0, nl), 10);
|
|
79
|
+
if (isNaN(len) || len < 0) return null;
|
|
80
|
+
|
|
81
|
+
var flight = text.substring(nl + 1, nl + 1 + len);
|
|
82
|
+
var jsonStr = text.substring(nl + 1 + len);
|
|
83
|
+
var data;
|
|
84
|
+
|
|
85
|
+
try { data = JSON.parse(jsonStr); }
|
|
86
|
+
catch (e) { return null; }
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
payload: flight,
|
|
90
|
+
meta: data.meta || null,
|
|
91
|
+
css: data.css || null,
|
|
92
|
+
translations: data.translations || null
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function refetchRSC(cssChanged) {
|
|
97
|
+
var rsc = window.__NITRON_RSC__;
|
|
98
|
+
|
|
99
|
+
if (!rsc || !rsc.root) {
|
|
100
|
+
location.reload();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
var url = location.pathname + location.search;
|
|
105
|
+
|
|
106
|
+
fetch(RSC_ENDPOINT + "?url=" + encodeURIComponent(url), {
|
|
107
|
+
headers: { "X-Nitron-SPA": "1" },
|
|
108
|
+
credentials: "same-origin"
|
|
109
|
+
})
|
|
110
|
+
.then(function(r) {
|
|
111
|
+
if (!r.ok) throw new Error("HTTP " + r.status);
|
|
112
|
+
|
|
113
|
+
return r.text().then(function(text) {
|
|
114
|
+
return parseLengthPrefixed(text);
|
|
115
|
+
});
|
|
116
|
+
})
|
|
117
|
+
.then(function(d) {
|
|
118
|
+
if (!d || !d.payload) {
|
|
119
|
+
location.reload();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (d.translations) {
|
|
124
|
+
var prev = window.__NITRON_TRANSLATIONS__;
|
|
125
|
+
|
|
126
|
+
window.__NITRON_TRANSLATIONS__ = prev
|
|
127
|
+
? Object.assign({}, prev, d.translations)
|
|
128
|
+
: d.translations;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
rsc.navigate(d.payload);
|
|
132
|
+
|
|
133
|
+
if (d.meta && d.meta.title) document.title = d.meta.title;
|
|
134
|
+
|
|
135
|
+
if (cssChanged) refreshCss();
|
|
136
|
+
})
|
|
137
|
+
.catch(function() {
|
|
138
|
+
location.reload();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function refreshCss() {
|
|
143
|
+
var links = document.querySelectorAll('link[rel="stylesheet"]');
|
|
144
|
+
var timestamp = Date.now();
|
|
145
|
+
|
|
146
|
+
for (var i = 0; i < links.length; i++) {
|
|
147
|
+
var href = (links[i].href || "").split("?")[0];
|
|
148
|
+
links[i].href = href + "?t=" + timestamp;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function showErrorOverlay(message, file) {
|
|
153
|
+
hideErrorOverlay();
|
|
154
|
+
|
|
155
|
+
var overlay = document.createElement("div");
|
|
156
|
+
overlay.id = "__nitron_error__";
|
|
157
|
+
overlay.innerHTML =
|
|
158
|
+
'<div style="position:fixed;inset:0;background:rgba(0,0,0,.95);color:#ff4444;padding:32px;font-family:monospace;z-index:999999;overflow:auto">' +
|
|
159
|
+
'<div style="font-size:24px;font-weight:bold;margin-bottom:16px">Build Error</div>' +
|
|
160
|
+
'<div style="color:#888;margin-bottom:16px">' + escapeHtml(file || "") + '</div>' +
|
|
161
|
+
'<pre style="white-space:pre-wrap;background:#1a1a2e;padding:16px;border-radius:8px">' + escapeHtml(message) + '</pre>' +
|
|
162
|
+
'<button onclick="this.parentNode.parentNode.remove()" style="position:absolute;top:16px;right:16px;background:#333;color:#fff;border:none;padding:8px 16px;cursor:pointer;border-radius:4px">Close</button>' +
|
|
163
|
+
'</div>';
|
|
164
|
+
|
|
165
|
+
document.body.appendChild(overlay);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function hideErrorOverlay() {
|
|
169
|
+
var el = document.getElementById("__nitron_error__");
|
|
170
|
+
|
|
171
|
+
if (el) {
|
|
172
|
+
el.remove();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function handleFastRefresh(msg) {
|
|
177
|
+
const chunks = msg.chunks || [];
|
|
178
|
+
const timestamp = msg.timestamp || Date.now();
|
|
179
|
+
const cssChanged = msg.cssChanged || false;
|
|
180
|
+
|
|
181
|
+
const promises = chunks.map(function(chunk) {
|
|
182
|
+
if (chunk.includes("..") || chunk.includes("://")) return Promise.resolve();
|
|
183
|
+
|
|
184
|
+
return import("/storage/" + chunk + "?t=" + timestamp);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
Promise.all(promises)
|
|
188
|
+
.then(function() {
|
|
189
|
+
if (window.$RefreshRuntime$) {
|
|
190
|
+
window.$RefreshRuntime$.performReactRefresh();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (cssChanged) {
|
|
194
|
+
refreshCss();
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
.catch(function(err) {
|
|
198
|
+
console.warn("[HMR] Fast Refresh failed, full reload:", err.message);
|
|
199
|
+
location.reload();
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function escapeHtml(str) {
|
|
204
|
+
return String(str || "")
|
|
205
|
+
.replace(/&/g, "&")
|
|
206
|
+
.replace(/</g, "<")
|
|
207
|
+
.replace(/>/g, ">");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (document.readyState === "loading") {
|
|
211
|
+
document.addEventListener("DOMContentLoaded", connect);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
connect();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("react-refresh/runtime");
|
package/lib/View/View.js
CHANGED
|
@@ -723,11 +723,6 @@ class View {
|
|
|
723
723
|
|
|
724
724
|
let runtimeScript = `<script${nonceAttr}>window.__NITRON_RUNTIME__=${JSON.stringify(runtimeData)};`;
|
|
725
725
|
|
|
726
|
-
if (hasFlightPayload) {
|
|
727
|
-
const escapedPayload = flightPayload.replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
728
|
-
runtimeScript += `window.__NITRON_FLIGHT__=${JSON.stringify(escapedPayload)};`;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
726
|
if (translations && Object.keys(translations).length > 0) {
|
|
732
727
|
const escapedTranslations = JSON.stringify(translations).replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
733
728
|
runtimeScript += `window.__NITRON_TRANSLATIONS__=${escapedTranslations};`;
|
|
@@ -735,10 +730,20 @@ class View {
|
|
|
735
730
|
|
|
736
731
|
runtimeScript += `</script>`;
|
|
737
732
|
|
|
733
|
+
if (hasFlightPayload) {
|
|
734
|
+
const escapedPayload = flightPayload.replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
735
|
+
runtimeScript += `<script${nonceAttr}>window.__NITRON_FLIGHT__=${JSON.stringify(escapedPayload)};</script>`;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
const refreshScript = this.#isDev
|
|
739
|
+
? `<script src="/storage/js/react-refresh-runtime.js"${nonceAttr}></script>`
|
|
740
|
+
+ `<script${nonceAttr}>$RefreshRuntime$.injectIntoGlobalHook(window);window.$RefreshReg$=function(t,i){$RefreshRuntime$.register(t,"__mod__ "+i)};window.$RefreshSig$=function(){return $RefreshRuntime$.createSignatureFunctionForTransform()};</script>`
|
|
741
|
+
: "";
|
|
742
|
+
|
|
738
743
|
const vendorScript = `<script src="/storage/js/vendor.js"${nonceAttr}></script>`;
|
|
739
744
|
|
|
740
745
|
const hmrScript = this.#isDev
|
|
741
|
-
? `<script src="/
|
|
746
|
+
? `<script src="/storage/js/hmr.js"${nonceAttr}></script>`
|
|
742
747
|
: "";
|
|
743
748
|
|
|
744
749
|
const consumerScript = hasFlightPayload
|
|
@@ -757,7 +762,7 @@ ${this.#generateHead(meta, css)}
|
|
|
757
762
|
<body>
|
|
758
763
|
<div id="app">${html}</div>
|
|
759
764
|
${runtimeScript}
|
|
760
|
-
${vendorScript}${hmrScript}${consumerScript}${spaScript}${devIndicator}
|
|
765
|
+
${refreshScript}${vendorScript}${hmrScript}${consumerScript}${spaScript}${devIndicator}
|
|
761
766
|
</body>
|
|
762
767
|
</html>`;
|
|
763
768
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -273,8 +273,10 @@ export class DateTime {
|
|
|
273
273
|
static getDate(timestamp?: string | number | null, format?: string): string;
|
|
274
274
|
static addDays(days: number): string;
|
|
275
275
|
static addHours(hours: number): string;
|
|
276
|
+
static addMinutes(minutes: number): string;
|
|
276
277
|
static subDays(days: number): string;
|
|
277
278
|
static subHours(hours: number): string;
|
|
279
|
+
static subMinutes(minutes: number): string;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
export class Str {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitronjs/framework",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "NitronJS is a modern and extensible Node.js MVC framework built on Fastify. It focuses on clean architecture, modular structure, and developer productivity, offering built-in routing, middleware, configuration management, CLI tooling, and native React integration for scalable full-stack applications.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"njs": "./cli/njs.js"
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"@fastify/helmet": "^13.0.2",
|
|
22
22
|
"@fastify/multipart": "^9.3.0",
|
|
23
23
|
"@fastify/static": "^8.3.0",
|
|
24
|
-
"@
|
|
24
|
+
"@parcel/watcher": "^2.5.6",
|
|
25
|
+
"@tailwindcss/node": "^4.2.2",
|
|
25
26
|
"@types/react": "^19.2.7",
|
|
26
27
|
"@types/react-dom": "^19.2.3",
|
|
27
28
|
"bcrypt": "^5.1.1",
|
|
28
|
-
"chokidar": "^5.0.0",
|
|
29
29
|
"dotenv": "^17.2.3",
|
|
30
30
|
"es-module-lexer": "^2.0.0",
|
|
31
31
|
"esbuild": "^0.27.2",
|
|
@@ -33,15 +33,17 @@
|
|
|
33
33
|
"mysql2": "^3.16.0",
|
|
34
34
|
"nodemailer": "^7.0.11",
|
|
35
35
|
"otpauth": "^9.5.0",
|
|
36
|
-
"
|
|
36
|
+
"oxc-parser": "^0.121.0",
|
|
37
|
+
"oxc-transform": "^0.121.0",
|
|
37
38
|
"qrcode": "^1.5.4",
|
|
38
39
|
"react": "^19.2.3",
|
|
39
40
|
"react-dom": "^19.2.3",
|
|
41
|
+
"react-refresh": "^0.18.0",
|
|
40
42
|
"react-server-dom-webpack": "^19.2.4",
|
|
41
43
|
"redis": "^5.6.0",
|
|
42
|
-
"socket.io": "^4.8.1",
|
|
43
44
|
"tailwindcss": "^4.1.18",
|
|
44
|
-
"typescript": "^5.9.3"
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"ws": "^8.18.3"
|
|
45
47
|
},
|
|
46
48
|
"keywords": [
|
|
47
49
|
"nitronjs",
|
/package/skeleton/database/migrations/{2025_01_01_00_00_users.js → 2025_01_01_00_00_create_users.js}
RENAMED
|
File without changes
|