pulse-js-framework 1.7.30 → 1.7.32
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 +34 -1
- package/cli/dev.js +54 -3
- package/cli/index.js +20 -5
- package/compiler/preprocessor.js +819 -0
- package/loader/vite-plugin.js +57 -12
- package/package.json +14 -2
- package/runtime/async.js +14 -26
- package/runtime/devtools/diagnostics.js +51 -3
- package/runtime/devtools.js +58 -1
- package/runtime/errors.js +159 -0
- package/runtime/graphql.js +83 -113
- package/runtime/http.js +18 -100
- package/runtime/interceptor-manager.js +242 -0
- package/runtime/router.js +80 -15
- package/runtime/utils.js +121 -5
- package/runtime/websocket.js +62 -73
package/cli/build.js
CHANGED
|
@@ -7,9 +7,13 @@
|
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, copyFileSync } from 'fs';
|
|
8
8
|
import { join, extname, relative, dirname } from 'path';
|
|
9
9
|
import { compile } from '../compiler/index.js';
|
|
10
|
+
import { preprocessStylesSync, isSassAvailable, getSassVersion } from '../compiler/preprocessor.js';
|
|
10
11
|
import { log } from './logger.js';
|
|
11
12
|
import { createTimer, createProgressBar, formatDuration, createSpinner } from './utils/cli-ui.js';
|
|
12
13
|
|
|
14
|
+
// SASS availability (checked once at build start)
|
|
15
|
+
let sassAvailable = false;
|
|
16
|
+
|
|
13
17
|
/**
|
|
14
18
|
* Build project for production
|
|
15
19
|
*/
|
|
@@ -34,6 +38,13 @@ export async function buildProject(args) {
|
|
|
34
38
|
|
|
35
39
|
log.info('Building with Pulse compiler...\n');
|
|
36
40
|
|
|
41
|
+
// Check for SASS availability
|
|
42
|
+
sassAvailable = isSassAvailable();
|
|
43
|
+
if (sassAvailable) {
|
|
44
|
+
const version = getSassVersion();
|
|
45
|
+
log.info(` SASS support enabled (sass ${version || 'unknown'})`);
|
|
46
|
+
}
|
|
47
|
+
|
|
37
48
|
// Create output directory
|
|
38
49
|
if (!existsSync(outDir)) {
|
|
39
50
|
mkdirSync(outDir, { recursive: true });
|
|
@@ -140,8 +151,30 @@ function processDirectory(srcDir, outDir, progress = null) {
|
|
|
140
151
|
});
|
|
141
152
|
|
|
142
153
|
if (result.success) {
|
|
154
|
+
let code = result.code;
|
|
155
|
+
|
|
156
|
+
// Preprocess SASS/SCSS in style blocks if sass is available
|
|
157
|
+
if (sassAvailable) {
|
|
158
|
+
const stylesMatch = code.match(/const styles = `([\s\S]*?)`;/);
|
|
159
|
+
if (stylesMatch) {
|
|
160
|
+
try {
|
|
161
|
+
const preprocessed = preprocessStylesSync(stylesMatch[1], {
|
|
162
|
+
filename: srcPath,
|
|
163
|
+
loadPaths: [dirname(srcPath)],
|
|
164
|
+
compressed: true
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (preprocessed.wasSass) {
|
|
168
|
+
code = code.replace(stylesMatch[0], `const styles = \`${preprocessed.css}\`;`);
|
|
169
|
+
}
|
|
170
|
+
} catch (sassError) {
|
|
171
|
+
log.warn(` SASS warning in ${file}: ${sassError.message}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
143
176
|
const outPath = join(outDir, file.replace('.pulse', '.js'));
|
|
144
|
-
writeFileSync(outPath,
|
|
177
|
+
writeFileSync(outPath, code);
|
|
145
178
|
} else {
|
|
146
179
|
log.error(` Error compiling ${file}:`);
|
|
147
180
|
for (const error of result.errors) {
|
package/cli/dev.js
CHANGED
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
import { createServer } from 'http';
|
|
8
8
|
import { readFileSync, existsSync, statSync, watch } from 'fs';
|
|
9
|
-
import { join, extname, resolve } from 'path';
|
|
9
|
+
import { join, extname, resolve, dirname } from 'path';
|
|
10
10
|
import { compile } from '../compiler/index.js';
|
|
11
|
+
import { preprocessStylesSync, isSassAvailable, getSassVersion } from '../compiler/preprocessor.js';
|
|
11
12
|
import { log } from './logger.js';
|
|
12
13
|
|
|
14
|
+
// SASS availability (checked once at server start)
|
|
15
|
+
let sassAvailable = false;
|
|
16
|
+
|
|
13
17
|
const MIME_TYPES = {
|
|
14
18
|
'.html': 'text/html',
|
|
15
19
|
'.js': 'application/javascript',
|
|
@@ -87,6 +91,13 @@ export async function startDevServer(args) {
|
|
|
87
91
|
// Vite not available, use built-in server
|
|
88
92
|
}
|
|
89
93
|
|
|
94
|
+
// Check for SASS availability
|
|
95
|
+
sassAvailable = isSassAvailable();
|
|
96
|
+
if (sassAvailable) {
|
|
97
|
+
const version = getSassVersion();
|
|
98
|
+
log.info(`SASS support enabled (sass ${version || 'unknown'})`);
|
|
99
|
+
}
|
|
100
|
+
|
|
90
101
|
// Built-in development server
|
|
91
102
|
const server = createServer(async (req, res) => {
|
|
92
103
|
const url = new URL(req.url, `http://localhost:${port}`);
|
|
@@ -128,11 +139,31 @@ export async function startDevServer(args) {
|
|
|
128
139
|
});
|
|
129
140
|
|
|
130
141
|
if (result.success) {
|
|
142
|
+
let code = result.code;
|
|
143
|
+
|
|
144
|
+
// Preprocess SASS/SCSS if available
|
|
145
|
+
if (sassAvailable) {
|
|
146
|
+
const stylesMatch = code.match(/const styles = `([\s\S]*?)`;/);
|
|
147
|
+
if (stylesMatch) {
|
|
148
|
+
try {
|
|
149
|
+
const preprocessed = preprocessStylesSync(stylesMatch[1], {
|
|
150
|
+
filename: filePath,
|
|
151
|
+
loadPaths: [dirname(filePath)]
|
|
152
|
+
});
|
|
153
|
+
if (preprocessed.wasSass) {
|
|
154
|
+
code = code.replace(stylesMatch[0], `const styles = \`${preprocessed.css}\`;`);
|
|
155
|
+
}
|
|
156
|
+
} catch (sassError) {
|
|
157
|
+
console.warn(`[Pulse] SASS warning: ${sassError.message}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
131
162
|
res.writeHead(200, {
|
|
132
163
|
'Content-Type': 'application/javascript',
|
|
133
164
|
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
134
165
|
});
|
|
135
|
-
res.end(
|
|
166
|
+
res.end(code);
|
|
136
167
|
} else {
|
|
137
168
|
const errorDetails = result.errors.map(e => `${e.message} at line ${e.line || '?'}:${e.column || '?'}`).join('\n');
|
|
138
169
|
console.error(`[Pulse] Compilation error in ${filePath}:`, result.errors);
|
|
@@ -173,11 +204,31 @@ export async function startDevServer(args) {
|
|
|
173
204
|
});
|
|
174
205
|
|
|
175
206
|
if (result.success) {
|
|
207
|
+
let code = result.code;
|
|
208
|
+
|
|
209
|
+
// Preprocess SASS/SCSS if available
|
|
210
|
+
if (sassAvailable) {
|
|
211
|
+
const stylesMatch = code.match(/const styles = `([\s\S]*?)`;/);
|
|
212
|
+
if (stylesMatch) {
|
|
213
|
+
try {
|
|
214
|
+
const preprocessed = preprocessStylesSync(stylesMatch[1], {
|
|
215
|
+
filename: pulseFilePath,
|
|
216
|
+
loadPaths: [dirname(pulseFilePath)]
|
|
217
|
+
});
|
|
218
|
+
if (preprocessed.wasSass) {
|
|
219
|
+
code = code.replace(stylesMatch[0], `const styles = \`${preprocessed.css}\`;`);
|
|
220
|
+
}
|
|
221
|
+
} catch (sassError) {
|
|
222
|
+
console.warn(`[Pulse] SASS warning: ${sassError.message}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
176
227
|
res.writeHead(200, {
|
|
177
228
|
'Content-Type': 'application/javascript',
|
|
178
229
|
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
179
230
|
});
|
|
180
|
-
res.end(
|
|
231
|
+
res.end(code);
|
|
181
232
|
} else {
|
|
182
233
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
183
234
|
res.end(`Compilation error: ${result.errors.map(e => e.message).join('\n')}`);
|
package/cli/index.js
CHANGED
|
@@ -15,8 +15,14 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
15
15
|
const __dirname = dirname(__filename);
|
|
16
16
|
|
|
17
17
|
// Version - read dynamically from package.json
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
let VERSION = '0.0.0';
|
|
19
|
+
try {
|
|
20
|
+
const pkgContent = readFileSync(join(__dirname, '..', 'package.json'), 'utf-8');
|
|
21
|
+
const pkg = JSON.parse(pkgContent);
|
|
22
|
+
VERSION = pkg.version || VERSION;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
log.warn(`Could not read package.json: ${err.message}`);
|
|
25
|
+
}
|
|
20
26
|
|
|
21
27
|
// Available example templates
|
|
22
28
|
const TEMPLATES = {
|
|
@@ -683,10 +689,19 @@ async function initProject(args) {
|
|
|
683
689
|
|
|
684
690
|
if (existsSync(pkgPath)) {
|
|
685
691
|
try {
|
|
686
|
-
|
|
687
|
-
|
|
692
|
+
const pkgContent = readFileSync(pkgPath, 'utf-8');
|
|
693
|
+
if (!pkgContent.trim()) {
|
|
694
|
+
log.warn('Existing package.json is empty, creating new one.');
|
|
695
|
+
} else {
|
|
696
|
+
pkg = JSON.parse(pkgContent);
|
|
697
|
+
log.info('Found existing package.json, merging...');
|
|
698
|
+
}
|
|
688
699
|
} catch (e) {
|
|
689
|
-
|
|
700
|
+
if (e instanceof SyntaxError) {
|
|
701
|
+
log.warn(`Invalid JSON in package.json: ${e.message}. Creating new one.`);
|
|
702
|
+
} else {
|
|
703
|
+
log.warn(`Could not read package.json: ${e.message}. Creating new one.`);
|
|
704
|
+
}
|
|
690
705
|
}
|
|
691
706
|
}
|
|
692
707
|
|