pulse-js-framework 1.7.2 → 1.7.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/build.js +97 -21
- package/cli/dev.js +20 -5
- package/package.json +8 -2
- package/runtime/async.js +619 -0
- package/runtime/devtools.js +619 -0
- package/runtime/dom.js +254 -40
- package/runtime/form.js +659 -0
- package/runtime/pulse.js +36 -3
- package/runtime/router.js +51 -5
- package/runtime/store.js +45 -0
package/cli/build.js
CHANGED
|
@@ -185,28 +185,104 @@ function readRuntimeFile(filename) {
|
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
187
|
* Minify JavaScript code (simple minification)
|
|
188
|
-
* String-aware: preserves content inside string literals
|
|
188
|
+
* String and regex-aware: preserves content inside string and regex literals
|
|
189
189
|
*/
|
|
190
190
|
export function minifyJS(code) {
|
|
191
|
-
// Extract strings to protect them from minification
|
|
192
|
-
const
|
|
193
|
-
const placeholder = '\
|
|
194
|
-
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
191
|
+
// Extract strings and regexes to protect them from minification
|
|
192
|
+
const preserved = [];
|
|
193
|
+
const placeholder = '\x00PRE';
|
|
194
|
+
|
|
195
|
+
// State machine to properly handle strings and regexes
|
|
196
|
+
let result = '';
|
|
197
|
+
let i = 0;
|
|
198
|
+
|
|
199
|
+
while (i < code.length) {
|
|
200
|
+
const char = code[i];
|
|
201
|
+
const next = code[i + 1];
|
|
202
|
+
|
|
203
|
+
// Skip single-line comments
|
|
204
|
+
if (char === '/' && next === '/') {
|
|
205
|
+
while (i < code.length && code[i] !== '\n') i++;
|
|
206
|
+
continue;
|
|
201
207
|
}
|
|
202
|
-
);
|
|
203
208
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
// Skip multi-line comments
|
|
210
|
+
if (char === '/' && next === '*') {
|
|
211
|
+
i += 2;
|
|
212
|
+
while (i < code.length - 1 && !(code[i] === '*' && code[i + 1] === '/')) i++;
|
|
213
|
+
i += 2;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Handle string literals
|
|
218
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
219
|
+
const quote = char;
|
|
220
|
+
let str = char;
|
|
221
|
+
i++;
|
|
222
|
+
while (i < code.length) {
|
|
223
|
+
const c = code[i];
|
|
224
|
+
str += c;
|
|
225
|
+
if (c === '\\' && i + 1 < code.length) {
|
|
226
|
+
i++;
|
|
227
|
+
str += code[i];
|
|
228
|
+
} else if (c === quote) {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
i++;
|
|
232
|
+
}
|
|
233
|
+
i++;
|
|
234
|
+
preserved.push(str);
|
|
235
|
+
result += placeholder + (preserved.length - 1) + '\x00';
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Handle regex literals (after = : ( , [ ! & | ? ; { or keywords)
|
|
240
|
+
if (char === '/') {
|
|
241
|
+
// Look back to determine if this is a regex
|
|
242
|
+
const lookback = result.slice(-20).trim();
|
|
243
|
+
const isRegexContext = lookback === '' ||
|
|
244
|
+
/[=:(\[,!&|?;{]$/.test(lookback) ||
|
|
245
|
+
/\breturn$/.test(lookback) ||
|
|
246
|
+
/\bthrow$/.test(lookback) ||
|
|
247
|
+
/\btypeof$/.test(lookback);
|
|
248
|
+
|
|
249
|
+
if (isRegexContext && next !== '/' && next !== '*') {
|
|
250
|
+
let regex = char;
|
|
251
|
+
i++;
|
|
252
|
+
let inCharClass = false;
|
|
253
|
+
while (i < code.length) {
|
|
254
|
+
const c = code[i];
|
|
255
|
+
regex += c;
|
|
256
|
+
if (c === '\\' && i + 1 < code.length) {
|
|
257
|
+
i++;
|
|
258
|
+
regex += code[i];
|
|
259
|
+
} else if (c === '[') {
|
|
260
|
+
inCharClass = true;
|
|
261
|
+
} else if (c === ']') {
|
|
262
|
+
inCharClass = false;
|
|
263
|
+
} else if (c === '/' && !inCharClass) {
|
|
264
|
+
// End of regex, collect flags
|
|
265
|
+
i++;
|
|
266
|
+
while (i < code.length && /[gimsuvy]/.test(code[i])) {
|
|
267
|
+
regex += code[i];
|
|
268
|
+
i++;
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
i++;
|
|
273
|
+
}
|
|
274
|
+
preserved.push(regex);
|
|
275
|
+
result += placeholder + (preserved.length - 1) + '\x00';
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
result += char;
|
|
281
|
+
i++;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Apply minification to non-preserved parts
|
|
285
|
+
let minified = result
|
|
210
286
|
// Remove leading/trailing whitespace per line
|
|
211
287
|
.split('\n')
|
|
212
288
|
.map(line => line.trim())
|
|
@@ -214,7 +290,7 @@ export function minifyJS(code) {
|
|
|
214
290
|
.join('\n')
|
|
215
291
|
// Collapse multiple newlines
|
|
216
292
|
.replace(/\n{2,}/g, '\n')
|
|
217
|
-
// Remove spaces around operators
|
|
293
|
+
// Remove spaces around operators
|
|
218
294
|
.replace(/\s*([{};,:])\s*/g, '$1')
|
|
219
295
|
.replace(/\s*=\s*/g, '=')
|
|
220
296
|
.replace(/\s*\(\s*/g, '(')
|
|
@@ -223,10 +299,10 @@ export function minifyJS(code) {
|
|
|
223
299
|
.replace(/\s+/g, ' ')
|
|
224
300
|
.trim();
|
|
225
301
|
|
|
226
|
-
// Restore strings
|
|
302
|
+
// Restore preserved strings and regexes
|
|
227
303
|
minified = minified.replace(
|
|
228
304
|
new RegExp(placeholder.replace('\x00', '\\x00') + '(\\d+)\\x00', 'g'),
|
|
229
|
-
(_, index) =>
|
|
305
|
+
(_, index) => preserved[parseInt(index)]
|
|
230
306
|
);
|
|
231
307
|
|
|
232
308
|
return minified;
|
package/cli/dev.js
CHANGED
|
@@ -128,7 +128,10 @@ export async function startDevServer(args) {
|
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
if (result.success) {
|
|
131
|
-
res.writeHead(200, {
|
|
131
|
+
res.writeHead(200, {
|
|
132
|
+
'Content-Type': 'application/javascript',
|
|
133
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
134
|
+
});
|
|
132
135
|
res.end(result.code);
|
|
133
136
|
} else {
|
|
134
137
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
@@ -146,7 +149,10 @@ export async function startDevServer(args) {
|
|
|
146
149
|
if (pathname.endsWith('.js') || pathname.endsWith('.mjs')) {
|
|
147
150
|
if (existsSync(filePath)) {
|
|
148
151
|
const content = readFileSync(filePath, 'utf-8');
|
|
149
|
-
res.writeHead(200, {
|
|
152
|
+
res.writeHead(200, {
|
|
153
|
+
'Content-Type': 'application/javascript',
|
|
154
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
155
|
+
});
|
|
150
156
|
res.end(content);
|
|
151
157
|
return;
|
|
152
158
|
}
|
|
@@ -164,7 +170,10 @@ export async function startDevServer(args) {
|
|
|
164
170
|
});
|
|
165
171
|
|
|
166
172
|
if (result.success) {
|
|
167
|
-
res.writeHead(200, {
|
|
173
|
+
res.writeHead(200, {
|
|
174
|
+
'Content-Type': 'application/javascript',
|
|
175
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
176
|
+
});
|
|
168
177
|
res.end(result.code);
|
|
169
178
|
} else {
|
|
170
179
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
@@ -183,7 +192,10 @@ export async function startDevServer(args) {
|
|
|
183
192
|
const modulePath = join(root, '..', 'pulse', pathname.replace('/node_modules/pulse-js-framework/', ''));
|
|
184
193
|
if (existsSync(modulePath)) {
|
|
185
194
|
const content = readFileSync(modulePath, 'utf-8');
|
|
186
|
-
res.writeHead(200, {
|
|
195
|
+
res.writeHead(200, {
|
|
196
|
+
'Content-Type': 'application/javascript',
|
|
197
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
198
|
+
});
|
|
187
199
|
res.end(content);
|
|
188
200
|
return;
|
|
189
201
|
}
|
|
@@ -203,7 +215,10 @@ export async function startDevServer(args) {
|
|
|
203
215
|
for (const runtimePath of possiblePaths) {
|
|
204
216
|
if (existsSync(runtimePath)) {
|
|
205
217
|
const content = readFileSync(runtimePath, 'utf-8');
|
|
206
|
-
res.writeHead(200, {
|
|
218
|
+
res.writeHead(200, {
|
|
219
|
+
'Content-Type': 'application/javascript',
|
|
220
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
221
|
+
});
|
|
207
222
|
res.end(content);
|
|
208
223
|
return;
|
|
209
224
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulse-js-framework",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"description": "A declarative DOM framework with CSS selector-based structure and reactive pulsations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -52,6 +52,9 @@
|
|
|
52
52
|
},
|
|
53
53
|
"./runtime/lru-cache": "./runtime/lru-cache.js",
|
|
54
54
|
"./runtime/utils": "./runtime/utils.js",
|
|
55
|
+
"./runtime/async": "./runtime/async.js",
|
|
56
|
+
"./runtime/form": "./runtime/form.js",
|
|
57
|
+
"./runtime/devtools": "./runtime/devtools.js",
|
|
55
58
|
"./compiler": {
|
|
56
59
|
"types": "./types/index.d.ts",
|
|
57
60
|
"default": "./compiler/index.js"
|
|
@@ -80,7 +83,7 @@
|
|
|
80
83
|
"LICENSE"
|
|
81
84
|
],
|
|
82
85
|
"scripts": {
|
|
83
|
-
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:lru-cache && npm run test:utils && npm run test:docs",
|
|
86
|
+
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:lru-cache && npm run test:utils && npm run test:docs && npm run test:async && npm run test:form && npm run test:devtools",
|
|
84
87
|
"test:compiler": "node test/compiler.test.js",
|
|
85
88
|
"test:sourcemap": "node test/sourcemap.test.js",
|
|
86
89
|
"test:pulse": "node test/pulse.test.js",
|
|
@@ -94,6 +97,9 @@
|
|
|
94
97
|
"test:lru-cache": "node test/lru-cache.test.js",
|
|
95
98
|
"test:utils": "node test/utils.test.js",
|
|
96
99
|
"test:docs": "node test/docs.test.js",
|
|
100
|
+
"test:async": "node test/async.test.js",
|
|
101
|
+
"test:form": "node test/form.test.js",
|
|
102
|
+
"test:devtools": "node test/devtools.test.js",
|
|
97
103
|
"build:netlify": "node scripts/build-netlify.js",
|
|
98
104
|
"version": "node scripts/sync-version.js",
|
|
99
105
|
"docs": "node cli/index.js dev docs"
|