svelteesp32 2.4.1 → 3.0.0
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/README.md +87 -24
- package/bin/index.js +10 -1
- package/dist/commandLine.d.ts +6 -5
- package/dist/commandLine.js +10 -7
- package/dist/consoleColor.d.ts +1 -0
- package/dist/cppCode.d.ts +1 -0
- package/dist/cppCode.js +48 -48
- package/dist/cppCodeEspIdf.d.ts +2 -1
- package/dist/cppCodeEspIdf.js +13 -13
- package/dist/errorMessages.d.ts +1 -0
- package/dist/errorMessages.js +1 -1
- package/dist/file.d.ts +3 -1
- package/dist/file.js +8 -11
- package/dist/index.d.ts +2 -16
- package/dist/index.js +22 -227
- package/dist/initCommand.d.ts +2 -0
- package/dist/initCommand.js +55 -0
- package/dist/pipeline.d.ts +29 -0
- package/dist/pipeline.js +278 -0
- package/dist/vitePlugin.d.ts +34 -0
- package/dist/vitePlugin.js +56 -0
- package/package.json +31 -14
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ npm install -D svelteesp32
|
|
|
56
56
|
After building your frontend (Vite/Rollup/Webpack):
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=
|
|
59
|
+
npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
Include in your ESP32 project:
|
|
@@ -79,7 +79,7 @@ void setup() {
|
|
|
79
79
|
>
|
|
80
80
|
> ```bash
|
|
81
81
|
> npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h \
|
|
82
|
-
> --etag=
|
|
82
|
+
> --etag=always --gzip=always --cachetime-html=0 --cachetime-assets=31536000
|
|
83
83
|
> ```
|
|
84
84
|
>
|
|
85
85
|
> ETags for instant 304s, gzip for smaller transfers, `no-cache` for HTML so updates are always picked up, and 1-year caching for content-hashed JS/CSS assets.
|
|
@@ -88,6 +88,7 @@ void setup() {
|
|
|
88
88
|
|
|
89
89
|
## What's New
|
|
90
90
|
|
|
91
|
+
- **v3.0.0** — **Vite plugin** (`import { svelteESP32 } from 'svelteesp32/vite'`) generates the header automatically after every build; `npx svelteesp32 init` interactive RC file wizard; Node.js >= 22 required
|
|
91
92
|
- **v2.4.0** — `--analyze` for CI size budget checks (per-file table, exits 1 on over-budget); `--manifest` to write a companion JSON manifest alongside the header
|
|
92
93
|
- **v2.3.0** — `--cachetime-html` and `--cachetime-assets` for per-type cache control (e.g. `no-cache` for HTML, 1-year for content-hashed JS/CSS)
|
|
93
94
|
- **v2.2.0** — SPA routing catch-all (`--spa`) for client-side routers on all four engines
|
|
@@ -104,8 +105,8 @@ void setup() {
|
|
|
104
105
|
|
|
105
106
|
## Requirements
|
|
106
107
|
|
|
107
|
-
- Node.js >=
|
|
108
|
-
- npm >=
|
|
108
|
+
- Node.js >= 22
|
|
109
|
+
- npm >= 10
|
|
109
110
|
|
|
110
111
|
---
|
|
111
112
|
|
|
@@ -117,22 +118,84 @@ void setup() {
|
|
|
117
118
|
npm install -D svelteesp32
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
###
|
|
121
|
+
### Quick Setup with `init`
|
|
122
|
+
|
|
123
|
+
The `init` command creates a `.svelteesp32rc.json` configuration file interactively so you never have to remember CLI flags:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx svelteesp32 init
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
It asks for engine, source path, output path, and ETag preference, writes the RC file, and optionally runs the tool immediately.
|
|
130
|
+
|
|
131
|
+
### Vite Plugin
|
|
132
|
+
|
|
133
|
+
For Vite-based projects (SvelteKit, React, Vue, Vanilla) you can skip the manual CLI step entirely — the plugin hooks into the build pipeline and regenerates the C++ header automatically after every `vite build`.
|
|
134
|
+
|
|
135
|
+
**`vite.config.ts`**
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { svelteKit } from '@sveltejs/kit/vite';
|
|
139
|
+
import { svelteESP32 } from 'svelteesp32/vite';
|
|
140
|
+
import { defineConfig } from 'vite';
|
|
141
|
+
|
|
142
|
+
export default defineConfig({
|
|
143
|
+
plugins: [
|
|
144
|
+
svelteKit(),
|
|
145
|
+
svelteESP32({
|
|
146
|
+
output: '../firmware/include/svelteesp32.h',
|
|
147
|
+
engine: 'psychic',
|
|
148
|
+
etag: 'always',
|
|
149
|
+
gzip: 'always',
|
|
150
|
+
cachetimeHtml: 0,
|
|
151
|
+
cachetimeAssets: 31536000
|
|
152
|
+
})
|
|
153
|
+
]
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The `output` path is required; all other options mirror the CLI flags and have the same defaults. `sourcepath` defaults to Vite's `build.outDir` when omitted.
|
|
158
|
+
|
|
159
|
+
**Plugin options**
|
|
160
|
+
|
|
161
|
+
| Option | Type | Default | Description |
|
|
162
|
+
| ----------------- | ------------------------------------------- | ------------------------- | -------------------------------------------------- |
|
|
163
|
+
| `output` | `string` | (required) | Output `.h` file path |
|
|
164
|
+
| `sourcepath` | `string` | Vite's `build.outDir` | Source directory (compiled web files) |
|
|
165
|
+
| `engine` | `'psychic'\|'async'\|'espidf'\|'webserver'` | `'psychic'` | Target web server engine |
|
|
166
|
+
| `etag` | `'always'\|'never'\|'compiler'` | `'never'` | ETag generation mode |
|
|
167
|
+
| `gzip` | `'always'\|'never'\|'compiler'` | `'always'` | Gzip compression mode |
|
|
168
|
+
| `cachetime` | `number` | `0` | `Cache-Control: max-age` in seconds (all files) |
|
|
169
|
+
| `cachetimeHtml` | `number` | (unset) | max-age for HTML files (overrides `cachetime`) |
|
|
170
|
+
| `cachetimeAssets` | `number` | (unset) | max-age for non-HTML files (overrides `cachetime`) |
|
|
171
|
+
| `exclude` | `string[]` | `[]` | Glob patterns to exclude |
|
|
172
|
+
| `basepath` | `string` | (none) | URL prefix for all routes |
|
|
173
|
+
| `espmethod` | `string` | `'initSvelteStaticFiles'` | Generated init function name |
|
|
174
|
+
| `define` | `string` | `'SVELTEESP32'` | C++ `#define` prefix |
|
|
175
|
+
| `version` | `string` | (none) | Version string embedded in header |
|
|
176
|
+
| `created` | `boolean` | `false` | Include creation timestamp |
|
|
177
|
+
| `spa` | `boolean` | `false` | Serve `index.html` for unmatched routes |
|
|
178
|
+
| `manifest` | `boolean` | `false` | Write companion `.manifest.json` |
|
|
179
|
+
| `noIndexCheck` | `boolean` | `false` | Skip `index.html` validation |
|
|
180
|
+
| `maxSize` | `number` | (none) | Max total uncompressed size in bytes |
|
|
181
|
+
| `maxGzipSize` | `number` | (none) | Max total gzip size in bytes |
|
|
182
|
+
|
|
183
|
+
### Generate Header File (CLI)
|
|
121
184
|
|
|
122
185
|
Choose your web server engine:
|
|
123
186
|
|
|
124
187
|
```bash
|
|
125
188
|
# PsychicHttpServer (recommended for ESP32)
|
|
126
|
-
npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=
|
|
189
|
+
npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always
|
|
127
190
|
|
|
128
191
|
# ESPAsyncWebServer (ESP32 + ESP8266)
|
|
129
|
-
npx svelteesp32 -e async -s ./dist -o ./esp32/svelteesp32.h --etag=
|
|
192
|
+
npx svelteesp32 -e async -s ./dist -o ./esp32/svelteesp32.h --etag=always
|
|
130
193
|
|
|
131
194
|
# Arduino WebServer (ESP32, synchronous, no dependencies)
|
|
132
|
-
npx svelteesp32 -e webserver -s ./dist -o ./esp32/svelteesp32.h --etag=
|
|
195
|
+
npx svelteesp32 -e webserver -s ./dist -o ./esp32/svelteesp32.h --etag=always
|
|
133
196
|
|
|
134
197
|
# Native ESP-IDF
|
|
135
|
-
npx svelteesp32 -e espidf -s ./dist -o ./esp32/svelteesp32.h --etag=
|
|
198
|
+
npx svelteesp32 -e espidf -s ./dist -o ./esp32/svelteesp32.h --etag=always
|
|
136
199
|
```
|
|
137
200
|
|
|
138
201
|
### Build Output
|
|
@@ -227,7 +290,7 @@ The generated header file includes everything your ESP needs:
|
|
|
227
290
|
|
|
228
291
|
```c
|
|
229
292
|
//engine: PsychicHttpServer V2
|
|
230
|
-
//config: engine=psychic sourcepath=./dist outputfile=./output.h etag=
|
|
293
|
+
//config: engine=psychic sourcepath=./dist outputfile=./output.h etag=always gzip=always cachetime=0 espmethod=initSvelteStaticFiles define=SVELTEESP32
|
|
231
294
|
//
|
|
232
295
|
#define SVELTEESP32_COUNT 5
|
|
233
296
|
#define SVELTEESP32_SIZE 468822
|
|
@@ -311,20 +374,20 @@ void initSvelteStaticFiles(PsychicHttpServer * server) {
|
|
|
311
374
|
|
|
312
375
|
Your JS, CSS, and HTML files are automatically compressed at build time — not on the ESP32. Files are gzipped when they're >1KB and achieve >15% size reduction.
|
|
313
376
|
|
|
314
|
-
- **Enabled by default** — disable with `--gzip=
|
|
377
|
+
- **Enabled by default** — disable with `--gzip=never`
|
|
315
378
|
- **Compiler mode** — use `--gzip=compiler` and control via `-D SVELTEESP32_ENABLE_GZIP` in PlatformIO
|
|
316
379
|
|
|
317
380
|
### Smart ETag Caching
|
|
318
381
|
|
|
319
382
|
Reduce bandwidth dramatically with HTTP 304 "Not Modified" responses. When a browser has a cached file, the ESP32 sends just a status code instead of the entire file — perfect for bandwidth-constrained IoT devices.
|
|
320
383
|
|
|
321
|
-
- **Enable with** `--etag=
|
|
384
|
+
- **Enable with** `--etag=always` (recommended)
|
|
322
385
|
- **Minimal overhead** — adds ~1-3% code size for significant bandwidth savings
|
|
323
386
|
- **Compiler mode** — use `--etag=compiler` and control via `-D SVELTEESP32_ENABLE_ETAG`
|
|
324
387
|
|
|
325
388
|
All four engines support full ETag validation.
|
|
326
389
|
|
|
327
|
-
> **Browser compatibility note:** ETags and `Cache-Control: max-age` are universally supported in all modern browsers. Very old clients (IE6/7, early Android 2.x WebViews) may ignore `must-revalidate` or mishandle 304 responses. If you target these environments, set `--etag=
|
|
390
|
+
> **Browser compatibility note:** ETags and `Cache-Control: max-age` are universally supported in all modern browsers. Very old clients (IE6/7, early Android 2.x WebViews) may ignore `must-revalidate` or mishandle 304 responses. If you target these environments, set `--etag=never` and `--cachetime=0` to force full downloads on every request.
|
|
328
391
|
|
|
329
392
|
### Browser Cache Control
|
|
330
393
|
|
|
@@ -338,7 +401,7 @@ Vite and webpack produce content-hashed filenames for JS/CSS (e.g., `app.a1b2c3.
|
|
|
338
401
|
|
|
339
402
|
```bash
|
|
340
403
|
npx svelteesp32 -e psychic -s ./dist -o ./output.h \
|
|
341
|
-
--etag=
|
|
404
|
+
--etag=always --cachetime-html=0 --cachetime-assets=31536000
|
|
342
405
|
```
|
|
343
406
|
|
|
344
407
|
This emits `Cache-Control: no-cache` for every `text/html` file and `Cache-Control: max-age=31536000` for all other assets in the same header, with no per-file configuration needed.
|
|
@@ -465,8 +528,8 @@ The manifest records build metadata and per-file details for tooling and dashboa
|
|
|
465
528
|
{
|
|
466
529
|
"generated": "2026-04-26T12:00:00.000Z",
|
|
467
530
|
"engine": "psychic",
|
|
468
|
-
"etag": "
|
|
469
|
-
"gzip": "
|
|
531
|
+
"etag": "never",
|
|
532
|
+
"gzip": "always",
|
|
470
533
|
"filecount": 4,
|
|
471
534
|
"size": 104960,
|
|
472
535
|
"gzipSize": 51507,
|
|
@@ -536,8 +599,8 @@ Called for every response (200 = content served, 304 = cache hit).
|
|
|
536
599
|
| `-s` | Source folder with compiled web files | (required) |
|
|
537
600
|
| `-e` | Web server engine (psychic/async/espidf/webserver) | `psychic` |
|
|
538
601
|
| `-o` | Output header file path | `svelteesp32.h` |
|
|
539
|
-
| `--etag` | ETag caching (
|
|
540
|
-
| `--gzip` | Gzip compression (
|
|
602
|
+
| `--etag` | ETag caching (always/never/compiler) | `never` |
|
|
603
|
+
| `--gzip` | Gzip compression (always/never/compiler) | `always` |
|
|
541
604
|
| `--created` | Include creation timestamp in header | `false` |
|
|
542
605
|
| `--exclude` | Exclude files by glob pattern | (none) |
|
|
543
606
|
| `--basepath` | URL prefix for all routes | (none) |
|
|
@@ -568,8 +631,8 @@ Store your settings in `.svelteesp32rc.json` for zero-argument builds:
|
|
|
568
631
|
"engine": "psychic",
|
|
569
632
|
"sourcepath": "./dist",
|
|
570
633
|
"outputfile": "./esp32/svelteesp32.h",
|
|
571
|
-
"etag": "
|
|
572
|
-
"gzip": "
|
|
634
|
+
"etag": "always",
|
|
635
|
+
"gzip": "always",
|
|
573
636
|
"exclude": ["*.map", "*.md"],
|
|
574
637
|
"basepath": "/ui",
|
|
575
638
|
"maxsize": "400k",
|
|
@@ -630,10 +693,10 @@ npm run build
|
|
|
630
693
|
|
|
631
694
|
# 2. Generate the header
|
|
632
695
|
npx svelteesp32 -e webserver -s ./dist -o ./MyProject/svelteesp32.h \
|
|
633
|
-
--gzip=
|
|
696
|
+
--gzip=always --etag=never
|
|
634
697
|
```
|
|
635
698
|
|
|
636
|
-
> **Note:** The Arduino `WebServer` library does not support ETag validation, so `--etag=
|
|
699
|
+
> **Note:** The Arduino `WebServer` library does not support ETag validation, so `--etag=never` is the correct setting here. Remember to call `server.handleClient()` in your `loop()`.
|
|
637
700
|
|
|
638
701
|
```c
|
|
639
702
|
#include <WebServer.h>
|
|
@@ -685,7 +748,7 @@ def build_frontend(source, target, env):
|
|
|
685
748
|
"-e", "async",
|
|
686
749
|
"-s", "frontend/dist",
|
|
687
750
|
"-o", "src/svelteesp32.h",
|
|
688
|
-
"--etag=
|
|
751
|
+
"--etag=always", "--gzip=always",
|
|
689
752
|
"--cachetime-html=0", "--cachetime-assets=31536000"
|
|
690
753
|
], check=True)
|
|
691
754
|
|
|
@@ -710,7 +773,7 @@ add_custom_command(
|
|
|
710
773
|
-e espidf
|
|
711
774
|
-s ${CMAKE_CURRENT_SOURCE_DIR}/frontend/dist
|
|
712
775
|
-o ${CMAKE_CURRENT_SOURCE_DIR}/main/svelteesp32.h
|
|
713
|
-
--etag=
|
|
776
|
+
--etag=always --gzip=always
|
|
714
777
|
--cachetime-html=0 --cachetime-assets=31536000
|
|
715
778
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
716
779
|
COMMENT "Generating svelteesp32.h from frontend build"
|
package/bin/index.js
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
|
|
2
|
+
if (process.argv[2] === 'init') {
|
|
3
|
+
require('../dist/initCommand.js')
|
|
4
|
+
.runInit()
|
|
5
|
+
.catch((err) => {
|
|
6
|
+
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
require('../dist/index.js').main();
|
|
11
|
+
}
|
package/dist/commandLine.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
interface ICopyFilesArguments {
|
|
1
|
+
export interface ICopyFilesArguments {
|
|
2
2
|
engine: 'psychic' | 'async' | 'espidf' | 'webserver';
|
|
3
3
|
sourcepath: string;
|
|
4
4
|
outputfile: string;
|
|
5
5
|
espmethod: string;
|
|
6
6
|
define: string;
|
|
7
|
-
gzip: '
|
|
8
|
-
etag: '
|
|
7
|
+
gzip: 'always' | 'never' | 'compiler';
|
|
8
|
+
etag: 'always' | 'never' | 'compiler';
|
|
9
9
|
cachetime: number;
|
|
10
10
|
cachetimeHtml?: number;
|
|
11
11
|
cachetimeAssets?: number;
|
|
@@ -28,8 +28,8 @@ interface IRcFileConfig {
|
|
|
28
28
|
outputfile?: string;
|
|
29
29
|
espmethod?: string;
|
|
30
30
|
define?: string;
|
|
31
|
-
gzip?: '
|
|
32
|
-
etag?: '
|
|
31
|
+
gzip?: 'always' | 'never' | 'compiler';
|
|
32
|
+
etag?: 'always' | 'never' | 'compiler';
|
|
33
33
|
cachetime?: number;
|
|
34
34
|
cachetimehtml?: number;
|
|
35
35
|
cachetimeassets?: number;
|
|
@@ -53,3 +53,4 @@ declare function interpolateNpmVariables(config: IRcFileConfig, rcFilePath: stri
|
|
|
53
53
|
export { getNpmPackageVariable, hasNpmVariables, interpolateNpmVariables, parseSize, validateCppIdentifier };
|
|
54
54
|
export declare function formatConfiguration(cmdLine: ICopyFilesArguments): string;
|
|
55
55
|
export declare const cmdLine: ICopyFilesArguments;
|
|
56
|
+
//# sourceMappingURL=commandLine.d.ts.map
|
package/dist/commandLine.js
CHANGED
|
@@ -19,6 +19,9 @@ function showHelp() {
|
|
|
19
19
|
console.log(`
|
|
20
20
|
svelteesp32 - Svelte JS to ESP32 converter
|
|
21
21
|
|
|
22
|
+
Commands:
|
|
23
|
+
init Create .svelteesp32rc.json interactively
|
|
24
|
+
|
|
22
25
|
Configuration:
|
|
23
26
|
--config <path> Use custom RC file (default: search for .svelteesp32rc.json)
|
|
24
27
|
|
|
@@ -27,8 +30,8 @@ Options:
|
|
|
27
30
|
(psychic|async|espidf|webserver) (default: "psychic")
|
|
28
31
|
-s, --sourcepath <path> Source dist folder with compiled web files (required)
|
|
29
32
|
-o, --outputfile <path> Generated output file with path (default: "svelteesp32.h")
|
|
30
|
-
--etag <value> Use ETAG header for cache (
|
|
31
|
-
--gzip <value> Compress content with gzip (
|
|
33
|
+
--etag <value> Use ETAG header for cache (always|never|compiler) (default: "never")
|
|
34
|
+
--gzip <value> Compress content with gzip (always|never|compiler) (default: "always")
|
|
32
35
|
--created Include creation time in the output file (default: false)
|
|
33
36
|
--version <value> Include version info in the output file (default: "")
|
|
34
37
|
--espmethod <name> Name of generated method (default: "initSvelteStaticFiles")
|
|
@@ -57,8 +60,8 @@ RC File:
|
|
|
57
60
|
"engine": "psychic",
|
|
58
61
|
"sourcepath": "./dist",
|
|
59
62
|
"outputfile": "./output.h",
|
|
60
|
-
"etag": "
|
|
61
|
-
"gzip": "
|
|
63
|
+
"etag": "always",
|
|
64
|
+
"gzip": "always",
|
|
62
65
|
"exclude": ["*.map", "*.md"],
|
|
63
66
|
"basepath": "/ui",
|
|
64
67
|
"maxsize": "400k",
|
|
@@ -78,7 +81,7 @@ function validateEngine(value) {
|
|
|
78
81
|
process.exit(1);
|
|
79
82
|
}
|
|
80
83
|
function validateTriState(value, name) {
|
|
81
|
-
if (value === '
|
|
84
|
+
if (value === 'always' || value === 'never' || value === 'compiler')
|
|
82
85
|
return value;
|
|
83
86
|
throw new Error(`Invalid ${name}: ${value}`);
|
|
84
87
|
}
|
|
@@ -393,8 +396,8 @@ function parseArguments() {
|
|
|
393
396
|
const result = {
|
|
394
397
|
engine: 'psychic',
|
|
395
398
|
outputfile: 'svelteesp32.h',
|
|
396
|
-
etag: '
|
|
397
|
-
gzip: '
|
|
399
|
+
etag: 'never',
|
|
400
|
+
gzip: 'always',
|
|
398
401
|
created: false,
|
|
399
402
|
version: '',
|
|
400
403
|
espmethod: 'initSvelteStaticFiles',
|
package/dist/consoleColor.d.ts
CHANGED
package/dist/cppCode.d.ts
CHANGED