svelteesp32 1.4.1 → 1.5.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
@@ -12,12 +12,10 @@ In order to be able to easily update OTA, it is important - from the users' poin
12
12
 
13
13
  This npm package provides a solution for **inserting any JS client application into the ESP web server** (PsychicHttp and also ESPAsyncWebServer available, PsychicHttp is the default). For this, JS, html, css, font, assets, etc. files must be converted to binary byte array. Npm mode is easy to use and easy to **integrate into your CI/CD pipeline**.
14
14
 
15
+ > Starting with version v1.5.0, PsychicHttp v2 is also supported.
15
16
  > Version v1.4.0 has a breaking change! --no-gzip changed to --gzip. Starting with this version c++ compiler directives are available to setup operation in project level.
16
-
17
17
  > Starting with version v1.3.0, c++ defines can be used.
18
-
19
18
  > Starting with version v1.2.0, ESP8266/ESP8285 is also supported.
20
-
21
19
  > Starting with version v1.1.0, the ETag header is also supported.
22
20
 
23
21
  ### Usage
@@ -34,6 +32,9 @@ After a successful Svelte build (rollup/webpack/vite) **create an includeable c+
34
32
  // for PsychicHttpServer
35
33
  npx svelteesp32 -e psychic -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
36
34
 
35
+ // for PsychicHttpServer V2
36
+ npx svelteesp32 -e psychic2 -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
37
+
37
38
  // for ESPAsyncWebServer
38
39
  npx svelteesp32 -e async -s ../svelteapp/dist -o ../esp32project/svelteesp32.h --etag=true
39
40
  ```
@@ -217,18 +218,18 @@ You can use the following c++ directives at the project level if you want to con
217
218
 
218
219
  ### Command line options
219
220
 
220
- | Option | Description | default |
221
- | ------------- | ---------------------------------------------------------------- | ----------------------- |
222
- | `-s` | **Source dist folder contains compiled web files** | |
223
- | `-e` | The engine for which the include file is created (psychic/async) | psychic |
224
- | `-o` | Generated output file with path | `svelteesp32.h` |
225
- | `--etag` | Use ETag header for cache (true/false/compiler) | false |
226
- | `--gzip` | Compress content with gzip (true/false/compiler) | true |
227
- | `--created` | Include creation time | false |
228
- | `--version` | Include a version string, `--version=v$npm_package_version` | '' |
229
- | `--espmethod` | Name of generated method | `initSvelteStaticFiles` |
230
- | `--define` | Prefix of c++ defines | `SVELTEESP32` |
231
- | `-h` | Show help | |
221
+ | Option | Description | default |
222
+ | ------------- | ------------------------------------------------------------------------- | ----------------------- |
223
+ | `-s` | **Source dist folder contains compiled web files** | |
224
+ | `-e` | The engine for which the include file is created (psychic/psychic2/async) | psychic |
225
+ | `-o` | Generated output file with path | `svelteesp32.h` |
226
+ | `--etag` | Use ETag header for cache (true/false/compiler) | false |
227
+ | `--gzip` | Compress content with gzip (true/false/compiler) | true |
228
+ | `--created` | Include creation time | false |
229
+ | `--version` | Include a version string, `--version=v$npm_package_version` | '' |
230
+ | `--espmethod` | Name of generated method | `initSvelteStaticFiles` |
231
+ | `--define` | Prefix of c++ defines | `SVELTEESP32` |
232
+ | `-h` | Show help | |
232
233
 
233
234
  ### Q&A
234
235
 
@@ -1,5 +1,5 @@
1
1
  interface ICopyFilesArguments {
2
- engine: 'psychic' | 'async';
2
+ engine: 'psychic' | 'psychic2' | 'async';
3
3
  sourcepath: string;
4
4
  outputfile: string;
5
5
  espmethod: string;
@@ -8,12 +8,14 @@ exports.cmdLine = (0, ts_command_line_args_1.parse)({
8
8
  type: (value) => {
9
9
  if (value === 'psychic')
10
10
  return 'psychic';
11
+ if (value === 'psychic2')
12
+ return 'psychic2';
11
13
  if (value === 'async')
12
14
  return 'async';
13
15
  throw new Error(`Invalid engine: ${value}`);
14
16
  },
15
17
  alias: 'e',
16
- description: 'The engine for which the include file is created (psychic|async)',
18
+ description: 'The engine for which the include file is created (psychic|psychic2|async)',
17
19
  defaultValue: 'psychic'
18
20
  },
19
21
  sourcepath: {
package/dist/cppCode.js CHANGED
@@ -150,10 +150,12 @@ void {{methodName}}(PsychicHttpServer * server) {
150
150
 
151
151
  {{#switch ../etag}}
152
152
  {{#case "true"}}
153
+ response.addHeader("cache-control", "no-cache");
153
154
  response.addHeader("ETag", etag_{{this.dataname}});
154
155
  {{/case}}
155
156
  {{#case "compiler"}}
156
157
  #ifdef {{../definePrefix}}_ENABLE_ETAG
158
+ response.addHeader("cache-control", "no-cache");
157
159
  response.addHeader("ETag", etag_{{this.dataname}});
158
160
  #endif
159
161
  {{/case}}
@@ -178,6 +180,182 @@ void {{methodName}}(PsychicHttpServer * server) {
178
180
  return response.send();
179
181
  });
180
182
 
183
+ {{/each}}
184
+ }`;
185
+ const psychic2Template = `
186
+ //engine: PsychicHttpServerV2
187
+ //cmdline: {{{commandLine}}}
188
+ {{#if created }}
189
+ //created: {{now}}
190
+ {{/if}}
191
+ //
192
+
193
+ {{#switch etag}}
194
+ {{#case "true"}}
195
+ #ifdef {{definePrefix}}_ENABLE_ETAG
196
+ #warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched ON
197
+ #endif
198
+ {{/case}}
199
+ {{#case "false"}}
200
+ #ifdef {{definePrefix}}_ENABLE_ETAG
201
+ #warning {{definePrefix}}_ENABLE_ETAG has no effect because it is permanently switched OFF
202
+ #endif
203
+ {{/case}}
204
+ {{/switch}}
205
+
206
+ {{#switch gzip}}
207
+ {{#case "true"}}
208
+ #ifdef {{definePrefix}}_ENABLE_GZIP
209
+ #warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched ON
210
+ #endif
211
+ {{/case}}
212
+ {{#case "false"}}
213
+ #ifdef {{definePrefix}}_ENABLE_GZIP
214
+ #warning {{definePrefix}}_ENABLE_GZIP has no effect because it is permanently switched OFF
215
+ #endif
216
+ {{/case}}
217
+ {{/switch}}
218
+
219
+ //
220
+ {{#if version }}
221
+ #define {{definePrefix}}_VERSION "{{version}}"
222
+ {{/if}}
223
+ #define {{definePrefix}}_COUNT {{fileCount}}
224
+ #define {{definePrefix}}_SIZE {{fileSize}}
225
+ #define {{definePrefix}}_SIZE_GZIP {{fileGzipSize}}
226
+
227
+ //
228
+ {{#each sources}}
229
+ #define {{../definePrefix}}_FILE_{{this.datanameUpperCase}}
230
+ {{/each}}
231
+
232
+ //
233
+ {{#each filesByExtension}}
234
+ #define {{../definePrefix}}_{{this.extension}}_FILES {{this.count}}
235
+ {{/each}}
236
+
237
+ //
238
+ #include <Arduino.h>
239
+ #include <PsychicHttp.h>
240
+ #include <PsychicHttpsServer.h>
241
+
242
+ //
243
+ {{#switch gzip}}
244
+ {{#case "true"}}
245
+ {{#each sources}}
246
+ const uint8_t datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };
247
+ {{/each}}
248
+ {{/case}}
249
+ {{#case "false"}}
250
+ {{#each sources}}
251
+ const uint8_t data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };
252
+ {{/each}}
253
+ {{/case}}
254
+ {{#case "compiler"}}
255
+ #ifdef {{definePrefix}}_ENABLE_GZIP
256
+ {{#each sources}}
257
+ const uint8_t datagzip_{{this.dataname}}[{{this.lengthGzip}}] = { {{this.bytesGzip}} };
258
+ {{/each}}
259
+ #else
260
+ {{#each sources}}
261
+ const uint8_t data_{{this.dataname}}[{{this.length}}] = { {{this.bytes}} };
262
+ {{/each}}
263
+ #endif
264
+ {{/case}}
265
+ {{/switch}}
266
+
267
+ //
268
+ {{#switch etag}}
269
+ {{#case "true"}}
270
+ {{#each sources}}
271
+ const char * etag_{{this.dataname}} = "{{this.md5}}";
272
+ {{/each}}
273
+ {{/case}}
274
+ {{#case "false"}}
275
+ {{/case}}
276
+ {{#case "compiler"}}
277
+ #ifdef {{definePrefix}}_ENABLE_ETAG
278
+ {{#each sources}}
279
+ const char * etag_{{this.dataname}} = "{{this.md5}}";
280
+ {{/each}}
281
+ #endif
282
+ {{/case}}
283
+ {{/switch}}
284
+
285
+ //
286
+ // Http Handlers
287
+ void {{methodName}}(PsychicHttpServer * server) {
288
+ {{#each sources}}
289
+ //
290
+ // {{this.filename}}
291
+ {{#if this.isDefault}}server->defaultEndpoint = {{/if}}server->on("/{{this.filename}}", HTTP_GET, [](PsychicRequest * request, PsychicResponse * response) {
292
+
293
+ {{#switch ../etag}}
294
+ {{#case "true"}}
295
+ if (request->hasHeader("If-None-Match") && request->header("If-None-Match") == String(etag_{{this.dataname}})) {
296
+ response->setCode(304);
297
+ return response->send();
298
+ }
299
+ {{/case}}
300
+ {{#case "compiler"}}
301
+ #ifdef {{../definePrefix}}_ENABLE_ETAG
302
+ if (request->hasHeader("If-None-Match") && request->header("If-None-Match") == String(etag_{{this.dataname}})) {
303
+ response->setCode(304);
304
+ return response->send();
305
+ }
306
+ #endif
307
+ {{/case}}
308
+ {{/switch}}
309
+
310
+ response->setContentType("{{this.mime}}");
311
+
312
+ {{#switch ../gzip}}
313
+ {{#case "true"}}
314
+ {{#if this.isGzip}}
315
+ response->addHeader("Content-Encoding", "gzip");
316
+ {{/if}}
317
+ {{/case}}
318
+ {{#case "compiler"}}
319
+ {{#if this.isGzip}}
320
+ #ifdef {{../definePrefix}}_ENABLE_GZIP
321
+ response->addHeader("Content-Encoding", "gzip");
322
+ #endif
323
+ {{/if}}
324
+ {{/case}}
325
+ {{/switch}}
326
+
327
+ {{#switch ../etag}}
328
+ {{#case "true"}}
329
+ response->addHeader("cache-control", "no-cache");
330
+ response->addHeader("ETag", etag_{{this.dataname}});
331
+ {{/case}}
332
+ {{#case "compiler"}}
333
+ #ifdef {{../definePrefix}}_ENABLE_ETAG
334
+ response->addHeader("cache-control", "no-cache");
335
+ response->addHeader("ETag", etag_{{this.dataname}});
336
+ #endif
337
+ {{/case}}
338
+ {{/switch}}
339
+
340
+ {{#switch ../gzip}}
341
+ {{#case "true"}}
342
+ response->setContent(datagzip_{{this.dataname}}, {{this.lengthGzip}});
343
+ {{/case}}
344
+ {{#case "false"}}
345
+ response->setContent(data_{{this.dataname}}, {{this.length}});
346
+ {{/case}}
347
+ {{#case "compiler"}}
348
+ #ifdef {{../definePrefix}}_ENABLE_GZIP
349
+ response->setContent(datagzip_{{this.dataname}}, {{this.lengthGzip}});
350
+ #else
351
+ response->setContent(data_{{this.dataname}}, {{this.length}});
352
+ #endif
353
+ {{/case}}
354
+ {{/switch}}
355
+
356
+ return response->send();
357
+ });
358
+
181
359
  {{/each}}
182
360
  }`;
183
361
  const asyncTemplate = `
@@ -328,10 +506,12 @@ void {{methodName}}(AsyncWebServer * server) {
328
506
 
329
507
  {{#switch ../etag}}
330
508
  {{#case "true"}}
509
+ response->addHeader("cache-control", "no-cache");
331
510
  response->addHeader("ETag", etag_{{this.dataname}});
332
511
  {{/case}}
333
512
  {{#case "compiler"}}
334
513
  #ifdef {{../definePrefix}}_ENABLE_ETAG
514
+ response->addHeader("cache-control", "no-cache");
335
515
  response->addHeader("ETag", etag_{{this.dataname}});
336
516
  #endif
337
517
  {{/case}}
@@ -347,7 +527,7 @@ void {{methodName}}(AsyncWebServer * server) {
347
527
  {{/each}}
348
528
  }`;
349
529
  let switchValue;
350
- const getCppCode = (sources, filesByExtension) => (0, handlebars_1.compile)(commandLine_1.cmdLine.engine === 'psychic' ? psychicTemplate : asyncTemplate)({
530
+ const getCppCode = (sources, filesByExtension) => (0, handlebars_1.compile)(commandLine_1.cmdLine.engine === 'psychic' ? psychicTemplate : commandLine_1.cmdLine.engine === 'psychic2' ? psychic2Template : asyncTemplate)({
351
531
  commandLine: process.argv.slice(2).join(' '),
352
532
  now: `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`,
353
533
  fileCount: sources.length.toString(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteesp32",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Convert Svelte (or any frontend) JS application to serve it from ESP32 webserver (PsychicHttp)",
5
5
  "author": "BCsabaEngine",
6
6
  "license": "ISC",
@@ -30,6 +30,7 @@
30
30
  "scripts": {
31
31
  "dev:async": "nodemon src/index.ts -- -e async -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=true --gzip=true --version=v$npm_package_version",
32
32
  "dev:psychic": "nodemon src/index.ts -- -e psychic -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=false --gzip=false --version=v$npm_package_version",
33
+ "dev:psychic2": "nodemon src/index.ts -- -e psychic2 -s ./demo/svelte/dist -o ./demo/esp32/include/svelteesp32.h --etag=false --gzip=false --version=v$npm_package_version",
33
34
  "test:all": "./package.script && ~/.platformio/penv/bin/pio run -d ./demo/esp32",
34
35
  "clean": "tsc --build --clean",
35
36
  "build": "tsc --build --clean && tsc --build --force",
@@ -49,21 +50,22 @@
49
50
  "esp8266",
50
51
  "webserver",
51
52
  "psychichttpserver",
53
+ "psychichttpserverV2",
52
54
  "espasyncwebserver"
53
55
  ],
54
56
  "devDependencies": {
55
57
  "@types/mime-types": "^2.1.4",
56
- "@types/node": "^22.4.1",
57
- "@typescript-eslint/eslint-plugin": "^8.1.0",
58
- "@typescript-eslint/parser": "^8.1.0",
59
- "eslint": "^9.9.0",
58
+ "@types/node": "^22.5.2",
59
+ "@typescript-eslint/eslint-plugin": "^8.3.0",
60
+ "@typescript-eslint/parser": "^8.3.0",
61
+ "eslint": "^9.9.1",
60
62
  "eslint-config-prettier": "^9.1.0",
61
63
  "eslint-plugin-simple-import-sort": "^12.1.1",
62
64
  "eslint-plugin-unicorn": "^55.0.0",
63
65
  "nodemon": "^3.1.4",
64
66
  "prettier": "^3.3.3",
65
67
  "ts-node": "^10.9.2",
66
- "tsx": "^4.17.0",
68
+ "tsx": "^4.19.0",
67
69
  "typescript": "^5.5.4"
68
70
  },
69
71
  "dependencies": {