svelteesp32 3.0.1 → 3.1.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 CHANGED
@@ -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=always --gzip=always --cachetime-html=0 --cachetime-assets=31536000
82
+ > --etag=always --gzip=always --cachetimehtml=0 --cachetimeassets=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,10 +88,10 @@ void setup() {
88
88
 
89
89
  ## What's New
90
90
 
91
- - **v3.0.1** — Vite plugin now reads RC file automatically; `output` is optional when `outputfile` is in the RC file; option names aligned to lowercase to match RC file keys (`cachetimehtml`, `cachetimeassets`, `noindexcheck`, `maxsize`, `maxgzipsize`); new `config` option to point at a custom RC file
92
- - **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
+ - **v3.1.0** — Removed `handlebars` dependency; C++ generation is now pure TypeScript. `--cachetime-html` `--cachetimehtml`, `--cachetime-assets` `--cachetimeassets` (CLI now matches RC file keys); `--dry-run` alias removed use `--dryrun`
92
+ - **v3.0.0** — **Vite plugin** (`import { svelteESP32 } from 'svelteesp32/vite'`) generates the header automatically after every build — call with no argument for RC file mode or pass an options object for plugin-options mode; `npx svelteesp32 init` interactive RC file wizard; Node.js >= 22 required
93
93
  - **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
94
- - **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)
94
+ - **v2.3.0** — `--cachetimehtml` and `--cachetimeassets` for per-type cache control (e.g. `no-cache` for HTML, 1-year for content-hashed JS/CSS)
95
95
  - **v2.2.0** — SPA routing catch-all (`--spa`) for client-side routers on all four engines
96
96
  - **v2.1.0** — New Arduino WebServer engine (`-e webserver`), dependency updates
97
97
  - **v2.0.0** — **BREAKING**: PsychicHttpServer V2 is now the default `psychic` engine. The `psychic2` engine has been removed. Dry run mode, C++ identifier validation, improved MIME type warnings
@@ -133,13 +133,27 @@ It asks for engine, source path, output path, and ETag preference, writes the RC
133
133
 
134
134
  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`.
135
135
 
136
- **`vite.config.ts`**
136
+ The plugin has two exclusive modes — pick one:
137
+
138
+ **RC file mode** — call with no argument (or a string path to a custom RC file). All settings come from `.svelteesp32rc.json`; `outputfile` in the RC file is required.
137
139
 
138
140
  ```ts
139
141
  import { svelteKit } from '@sveltejs/kit/vite';
140
142
  import { svelteESP32 } from 'svelteesp32/vite';
141
143
  import { defineConfig } from 'vite';
142
144
 
145
+ export default defineConfig({
146
+ plugins: [
147
+ svelteKit(),
148
+ svelteESP32() // auto-discover .svelteesp32rc.json
149
+ // svelteESP32('/path/to/custom.rc.json') // or specify path explicitly
150
+ ]
151
+ });
152
+ ```
153
+
154
+ **Plugin options mode** — call with an options object. The RC file is completely ignored; `output` is required.
155
+
156
+ ```ts
143
157
  export default defineConfig({
144
158
  plugins: [
145
159
  svelteKit(),
@@ -155,7 +169,7 @@ export default defineConfig({
155
169
  });
156
170
  ```
157
171
 
158
- `output` can be omitted when `outputfile` is set in an RC file. `sourcepath` defaults to Vite's `build.outDir`. All other options mirror CLI flags and fall back to the RC file before applying built-in defaults.
172
+ `sourcepath` defaults to Vite's `build.outDir` in both modes.
159
173
 
160
174
  **Plugin options**
161
175
 
@@ -180,7 +194,6 @@ export default defineConfig({
180
194
  | `noindexcheck` | `boolean` | `false` | Skip `index.html` validation |
181
195
  | `maxsize` | `number` | (none) | Max total uncompressed size in bytes |
182
196
  | `maxgzipsize` | `number` | (none) | Max total gzip size in bytes |
183
- | `config` | `string` | auto-discover | Path to a custom RC file |
184
197
 
185
198
  ### Generate Header File (CLI)
186
199
 
@@ -397,22 +410,22 @@ Fine-tune how browsers cache your content:
397
410
 
398
411
  - **Default:** `no-cache` — browsers always validate with server (ETag check)
399
412
  - **Long-term caching:** `--cachetime=86400` — cache for 24 hours without any server requests
400
- - **Per-type caching:** Use `--cachetime-html` and `--cachetime-assets` independently
413
+ - **Per-type caching:** Use `--cachetimehtml` and `--cachetimeassets` independently
401
414
 
402
415
  Vite and webpack produce content-hashed filenames for JS/CSS (e.g., `app.a1b2c3.js`). Those can be cached for up to a year because the hash changes with every build, but `index.html` must stay `no-cache` since it's the entry point that references them:
403
416
 
404
417
  ```bash
405
418
  npx svelteesp32 -e psychic -s ./dist -o ./output.h \
406
- --etag=always --cachetime-html=0 --cachetime-assets=31536000
419
+ --etag=always --cachetimehtml=0 --cachetimeassets=31536000
407
420
  ```
408
421
 
409
422
  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.
410
423
 
411
- | Option | Applies to | Falls back to |
412
- | -------------------- | -------------------------------- | -------------- |
413
- | `--cachetime-html` | `text/html` only | `--cachetime` |
414
- | `--cachetime-assets` | everything else | `--cachetime` |
415
- | `--cachetime` | all files (when no override set) | `0` (no-cache) |
424
+ | Option | Applies to | Falls back to |
425
+ | ------------------- | -------------------------------- | -------------- |
426
+ | `--cachetimehtml` | `text/html` only | `--cachetime` |
427
+ | `--cachetimeassets` | everything else | `--cachetime` |
428
+ | `--cachetime` | all files (when no override set) | `0` (no-cache) |
416
429
 
417
430
  ### Automatic Index Handling
418
431
 
@@ -596,31 +609,31 @@ Called for every response (200 = content served, 304 = cache hit).
596
609
 
597
610
  ## CLI Reference
598
611
 
599
- | Option | Description | Default |
600
- | -------------------- | -------------------------------------------------------------------------------------- | ----------------------- |
601
- | `-s` | Source folder with compiled web files | (required) |
602
- | `-e` | Web server engine (psychic/async/espidf/webserver) | `psychic` |
603
- | `-o` | Output header file path | `svelteesp32.h` |
604
- | `--etag` | ETag caching (always/never/compiler) | `never` |
605
- | `--gzip` | Gzip compression (always/never/compiler) | `always` |
606
- | `--created` | Include creation timestamp in header | `false` |
607
- | `--exclude` | Exclude files by glob pattern | (none) |
608
- | `--basepath` | URL prefix for all routes | (none) |
609
- | `--maxsize` | Max total uncompressed size (e.g., `400k`, `1m`) | (none) |
610
- | `--maxgzipsize` | Max total gzip size (e.g., `150k`, `500k`) | (none) |
611
- | `--cachetime` | Cache-Control max-age in seconds (all files) | `0` |
612
- | `--cachetime-html` | max-age for HTML files (overrides `--cachetime`) | (unset) |
613
- | `--cachetime-assets` | max-age for non-HTML files (overrides `--cachetime`) | (unset) |
614
- | `--version` | Version string in header | (none) |
615
- | `--define` | C++ define prefix | `SVELTEESP32` |
616
- | `--espmethod` | Init function name | `initSvelteStaticFiles` |
617
- | `--config` | Custom RC file path | `.svelteesp32rc.json` |
618
- | `--dryrun` | Show route table + summary without writing output | `false` |
619
- | `--analyze` | Print per-file size table and budget status, no output written; exits 1 if over budget | `false` |
620
- | `--manifest` | Write companion `.manifest.json` alongside the header | `false` |
621
- | `--spa` | Serve index.html for unmatched routes (SPA routing) | `false` |
622
- | `--noindexcheck` | Skip index.html validation | `false` |
623
- | `-h` | Show help | |
612
+ | Option | Description | Default |
613
+ | ------------------- | -------------------------------------------------------------------------------------- | ----------------------- |
614
+ | `-s` | Source folder with compiled web files | (required) |
615
+ | `-e` | Web server engine (psychic/async/espidf/webserver) | `psychic` |
616
+ | `-o` | Output header file path | `svelteesp32.h` |
617
+ | `--etag` | ETag caching (always/never/compiler) | `never` |
618
+ | `--gzip` | Gzip compression (always/never/compiler) | `always` |
619
+ | `--created` | Include creation timestamp in header | `false` |
620
+ | `--exclude` | Exclude files by glob pattern | (none) |
621
+ | `--basepath` | URL prefix for all routes | (none) |
622
+ | `--maxsize` | Max total uncompressed size (e.g., `400k`, `1m`) | (none) |
623
+ | `--maxgzipsize` | Max total gzip size (e.g., `150k`, `500k`) | (none) |
624
+ | `--cachetime` | Cache-Control max-age in seconds (all files) | `0` |
625
+ | `--cachetimehtml` | max-age for HTML files (overrides `--cachetime`) | (unset) |
626
+ | `--cachetimeassets` | max-age for non-HTML files (overrides `--cachetime`) | (unset) |
627
+ | `--version` | Version string in header | (none) |
628
+ | `--define` | C++ define prefix | `SVELTEESP32` |
629
+ | `--espmethod` | Init function name | `initSvelteStaticFiles` |
630
+ | `--config` | Custom RC file path | `.svelteesp32rc.json` |
631
+ | `--dryrun` | Show route table + summary without writing output | `false` |
632
+ | `--analyze` | Print per-file size table and budget status, no output written; exits 1 if over budget | `false` |
633
+ | `--manifest` | Write companion `.manifest.json` alongside the header | `false` |
634
+ | `--spa` | Serve index.html for unmatched routes (SPA routing) | `false` |
635
+ | `--noindexcheck` | Skip index.html validation | `false` |
636
+ | `-h` | Show help | |
624
637
 
625
638
  ---
626
639
 
@@ -751,7 +764,7 @@ def build_frontend(source, target, env):
751
764
  "-s", "frontend/dist",
752
765
  "-o", "src/svelteesp32.h",
753
766
  "--etag=always", "--gzip=always",
754
- "--cachetime-html=0", "--cachetime-assets=31536000"
767
+ "--cachetimehtml=0", "--cachetimeassets=31536000"
755
768
  ], check=True)
756
769
 
757
770
  env.AddPreAction("buildprog", build_frontend)
@@ -776,7 +789,7 @@ add_custom_command(
776
789
  -s ${CMAKE_CURRENT_SOURCE_DIR}/frontend/dist
777
790
  -o ${CMAKE_CURRENT_SOURCE_DIR}/main/svelteesp32.h
778
791
  --etag=always --gzip=always
779
- --cachetime-html=0 --cachetime-assets=31536000
792
+ --cachetimehtml=0 --cachetimeassets=31536000
780
793
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
781
794
  COMMENT "Generating svelteesp32.h from frontend build"
782
795
  VERBATIM
@@ -805,7 +818,7 @@ void app_main(void) {
805
818
  }
806
819
  ```
807
820
 
808
- The `--cachetime-html=0 --cachetime-assets=31536000` combination gives you `no-cache` for `index.html` (so browser always checks for updates) and a 1-year `max-age` for content-hashed JS/CSS bundles.
821
+ The `--cachetimehtml=0 --cachetimeassets=31536000` combination gives you `no-cache` for `index.html` (so browser always checks for updates) and a 1-year `max-age` for content-hashed JS/CSS bundles.
809
822
 
810
823
  ---
811
824
 
@@ -21,6 +21,7 @@ export interface ICopyFilesArguments {
21
21
  spa?: boolean;
22
22
  manifest?: boolean;
23
23
  help?: boolean;
24
+ configSource: 'cli' | 'rcfile' | 'vite';
24
25
  }
25
26
  export interface IRcFileConfig {
26
27
  engine?: 'psychic' | 'async' | 'espidf' | 'webserver';
@@ -39,8 +39,8 @@ Options:
39
39
  --espmethod <name> Name of generated method (default: "initSvelteStaticFiles")
40
40
  --define <prefix> Prefix of c++ defines (default: "SVELTEESP32")
41
41
  --cachetime <seconds> max-age cache time in seconds (default: 0)
42
- --cachetime-html <sec> Cache-Control max-age for HTML files (overrides --cachetime)
43
- --cachetime-assets <sec> Cache-Control max-age for non-HTML assets (overrides --cachetime)
42
+ --cachetimehtml <sec> Cache-Control max-age for HTML files (overrides --cachetime)
43
+ --cachetimeassets <sec> Cache-Control max-age for non-HTML assets (overrides --cachetime)
44
44
  --exclude <pattern> Exclude files matching glob pattern (repeatable or comma-separated)
45
45
  Examples: --exclude="*.map" --exclude="test/**/*.ts"
46
46
  --basepath <path> URL prefix for all routes (e.g., "/ui") (default: "")
@@ -412,7 +412,8 @@ function parseArguments() {
412
412
  define: 'SVELTEESP32',
413
413
  cachetime: 0,
414
414
  exclude: [],
415
- basePath: ''
415
+ basePath: '',
416
+ configSource: 'cli'
416
417
  };
417
418
  if (rcConfig.engine)
418
419
  result.engine = rcConfig.engine;
@@ -492,20 +493,20 @@ function parseArguments() {
492
493
  if (result.cachetime < 0)
493
494
  throw new TypeError(`Invalid cachetime: ${value} (must be non-negative)`);
494
495
  break;
495
- case 'cachetime-html': {
496
+ case 'cachetimehtml': {
496
497
  result.cachetimeHtml = Number.parseInt(value, 10);
497
498
  if (Number.isNaN(result.cachetimeHtml))
498
- throw new TypeError(`Invalid cachetime-html: ${value}`);
499
+ throw new TypeError(`Invalid cachetimehtml: ${value}`);
499
500
  if (result.cachetimeHtml < 0)
500
- throw new TypeError(`Invalid cachetime-html: ${value} (must be non-negative)`);
501
+ throw new TypeError(`Invalid cachetimehtml: ${value} (must be non-negative)`);
501
502
  break;
502
503
  }
503
- case 'cachetime-assets': {
504
+ case 'cachetimeassets': {
504
505
  result.cachetimeAssets = Number.parseInt(value, 10);
505
506
  if (Number.isNaN(result.cachetimeAssets))
506
- throw new TypeError(`Invalid cachetime-assets: ${value}`);
507
+ throw new TypeError(`Invalid cachetimeassets: ${value}`);
507
508
  if (result.cachetimeAssets < 0)
508
- throw new TypeError(`Invalid cachetime-assets: ${value} (must be non-negative)`);
509
+ throw new TypeError(`Invalid cachetimeassets: ${value} (must be non-negative)`);
509
510
  break;
510
511
  }
511
512
  case 'exclude': {
@@ -554,7 +555,7 @@ function parseArguments() {
554
555
  result.noIndexCheck = true;
555
556
  continue;
556
557
  }
557
- if (argument === '--dryrun' || argument === '--dry-run') {
558
+ if (argument === '--dryrun') {
558
559
  result.dryRun = true;
559
560
  continue;
560
561
  }
@@ -615,10 +616,12 @@ function parseArguments() {
615
616
  return result;
616
617
  }
617
618
  function formatConfiguration(cmdLine) {
619
+ const relativeOutput = node_path_1.default.relative(process.cwd(), cmdLine.outputfile);
618
620
  const parts = [
621
+ `source=${cmdLine.configSource}`,
619
622
  `engine=${cmdLine.engine}`,
620
623
  `sourcepath=${cmdLine.sourcepath}`,
621
- `outputfile=${cmdLine.outputfile}`,
624
+ `outputfile=${relativeOutput}`,
622
625
  `etag=${cmdLine.etag}`,
623
626
  `gzip=${cmdLine.gzip}`,
624
627
  `cachetime=${cmdLine.cachetime}`
package/dist/cppCode.d.ts CHANGED
@@ -15,4 +15,53 @@ export type ExtensionGroup = {
15
15
  count: number;
16
16
  };
17
17
  export type ExtensionGroups = ExtensionGroup[];
18
+ export declare const sw: (value: string, cases: Partial<Record<"always" | "never" | "compiler", string>>) => string;
19
+ declare const transformSourceToTemplateData: (s: CppCodeSource, etag: string, effectiveCacheTime: number) => {
20
+ length: number;
21
+ bytes: string;
22
+ lengthGzip: number;
23
+ bytesGzip: string;
24
+ isDefault: boolean;
25
+ gzipSizeForManifest: number;
26
+ etagForManifest: string;
27
+ cacheTime: {
28
+ value: number;
29
+ } | undefined;
30
+ filename: string;
31
+ dataname: string;
32
+ datanameUpperCase: string;
33
+ mime: string;
34
+ content: Buffer;
35
+ contentGzip: Buffer;
36
+ isGzip: boolean;
37
+ sha256: string;
38
+ };
39
+ export type TransformedSource = ReturnType<typeof transformSourceToTemplateData>;
40
+ export type TemplateData = {
41
+ config: string;
42
+ now: string;
43
+ fileCount: string;
44
+ fileSize: string;
45
+ fileGzipSize: string;
46
+ sources: TransformedSource[];
47
+ filesByExtension: ExtensionGroups;
48
+ etag: string;
49
+ gzip: string;
50
+ created: boolean | undefined;
51
+ version: string | undefined;
52
+ methodName: string;
53
+ definePrefix: string;
54
+ basePath: string;
55
+ spa: boolean;
56
+ spaSource: TransformedSource | undefined;
57
+ isPsychic: boolean;
58
+ maxUriHandlers: string;
59
+ };
60
+ export declare const cacheCtrl: (source: TransformedSource) => string;
61
+ export declare const genCommonHeader: (d: TemplateData) => string;
62
+ export declare const genDataArrays: (d: TemplateData, progmem: boolean) => string;
63
+ export declare const genEtagArrays: (d: TemplateData) => string;
64
+ export declare const genManifest: (d: TemplateData) => string;
65
+ export declare const genHook: (d: TemplateData) => string;
18
66
  export declare const getCppCode: (sources: CppCodeSources, filesByExtension: ExtensionGroups, options: ICopyFilesArguments) => string;
67
+ export {};