tasmota-esp-web-tools 9.0.2 → 10.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.
Files changed (85) hide show
  1. package/dist/components/ewt-littlefs-manager.d.ts +43 -0
  2. package/dist/components/ewt-littlefs-manager.js +819 -0
  3. package/dist/flash.js +4 -30
  4. package/dist/install-dialog.d.ts +11 -0
  5. package/dist/install-dialog.js +336 -0
  6. package/dist/partition.d.ts +26 -0
  7. package/dist/partition.js +129 -0
  8. package/dist/util/esp32s2-reconnect.d.ts +22 -0
  9. package/dist/util/esp32s2-reconnect.js +45 -0
  10. package/dist/util/partition.d.ts +4 -0
  11. package/dist/util/partition.js +59 -0
  12. package/{js/modules/index-BK6drzlv.js → dist/web/index-t2Vsxqjj.js} +1 -1
  13. package/dist/web/install-button.js +1 -1
  14. package/dist/web/{install-dialog-Xo7JovVA.js → install-dialog-CVebVk1R.js} +515 -36
  15. package/dist/web/{styles-ntwzvT31.js → styles-CWxbqh-J.js} +1 -1
  16. package/dist/web/wasm/littlefs/index.d.ts +91 -0
  17. package/dist/web/wasm/littlefs/index.js +611 -0
  18. package/dist/web/wasm/littlefs/littlefs.js +505 -0
  19. package/dist/web/wasm/littlefs/littlefs.wasm +0 -0
  20. package/{dist/web/index-BK6drzlv.js → js/modules/index-t2Vsxqjj.js} +1 -1
  21. package/js/modules/install-button.js +1 -1
  22. package/js/modules/{install-dialog-Xo7JovVA.js → install-dialog-CVebVk1R.js} +515 -36
  23. package/js/modules/{styles-ntwzvT31.js → styles-CWxbqh-J.js} +1 -1
  24. package/js/modules/wasm/littlefs/index.d.ts +91 -0
  25. package/js/modules/wasm/littlefs/index.js +611 -0
  26. package/js/modules/wasm/littlefs/littlefs.js +505 -0
  27. package/js/modules/wasm/littlefs/littlefs.wasm +0 -0
  28. package/package.json +3 -2
  29. package/.devcontainer/Dockerfile +0 -16
  30. package/.devcontainer/devcontainer.json +0 -21
  31. package/.github/dependabot.yml +0 -10
  32. package/.github/workflows/build_upload.yml +0 -78
  33. package/.github/workflows/ci.yml +0 -24
  34. package/.prettierignore +0 -1
  35. package/BAUD_RATE_CONFIGURATION.md +0 -291
  36. package/BAUD_RATE_IMPROVEMENT.md +0 -195
  37. package/CHANGELOG_IMPROVEMENTS.md +0 -246
  38. package/ESP32_S2_USB_RECONNECT.md +0 -108
  39. package/FINAL_SUMMARY.md +0 -153
  40. package/example-baud-rate.html +0 -276
  41. package/manifest-example-p4-variants.json +0 -61
  42. package/rollup.config.mjs +0 -36
  43. package/script/build +0 -8
  44. package/script/develop +0 -17
  45. package/src/components/ewt-button.ts +0 -25
  46. package/src/components/ewt-checkbox.ts +0 -14
  47. package/src/components/ewt-circular-progress.ts +0 -14
  48. package/src/components/ewt-console.ts +0 -166
  49. package/src/components/ewt-dialog.ts +0 -22
  50. package/src/components/ewt-formfield.ts +0 -14
  51. package/src/components/ewt-icon-button.ts +0 -14
  52. package/src/components/ewt-list-item.ts +0 -14
  53. package/src/components/ewt-select.ts +0 -23
  54. package/src/components/ewt-textfield.ts +0 -23
  55. package/src/components/svg.ts +0 -27
  56. package/src/connect.ts +0 -55
  57. package/src/const.ts +0 -122
  58. package/src/flash.ts +0 -361
  59. package/src/install-button.ts +0 -126
  60. package/src/install-dialog.ts +0 -1114
  61. package/src/no-port-picked/index.ts +0 -10
  62. package/src/no-port-picked/no-port-picked-dialog.ts +0 -167
  63. package/src/pages/ewt-page-message.ts +0 -39
  64. package/src/pages/ewt-page-progress.ts +0 -44
  65. package/src/styles.ts +0 -34
  66. package/src/util/chip-family-name.ts +0 -46
  67. package/src/util/console-color.ts +0 -284
  68. package/src/util/file-download.ts +0 -17
  69. package/src/util/fire-event.ts +0 -20
  70. package/src/util/line-break-transformer.ts +0 -20
  71. package/src/util/manifest.ts +0 -18
  72. package/src/util/sleep.ts +0 -2
  73. package/static/logos/2smart.png +0 -0
  74. package/static/logos/canairio.png +0 -0
  75. package/static/logos/clockwise.png +0 -0
  76. package/static/logos/espeasy.png +0 -0
  77. package/static/logos/esphome.svg +0 -1
  78. package/static/logos/luciferin_logo.png +0 -0
  79. package/static/logos/squeezelite-esp32.png +0 -0
  80. package/static/logos/tasmota.svg +0 -1
  81. package/static/logos/wled.png +0 -0
  82. package/static/screenshots/dashboard.png +0 -0
  83. package/static/screenshots/logs.png +0 -0
  84. package/static/social.png +0 -0
  85. package/tsconfig.json +0 -20
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ESP32-S2 Native USB Reconnect Utilities
3
+ *
4
+ * The ESP32-S2 can switch between ROM bootloader mode and USB CDC mode,
5
+ * causing the serial port to change. These utilities help detect and handle
6
+ * this scenario consistently across the application.
7
+ */
8
+ /**
9
+ * Check if a serial port is an ESP32-S2 Native USB device
10
+ * VID 0x303a = Espressif
11
+ * PID 0x0002 = ESP32-S2 Native USB (ROM bootloader)
12
+ */
13
+ export const isESP32S2NativeUSB = (port) => {
14
+ const info = port.getInfo();
15
+ return info.usbVendorId === 0x303a && info.usbProductId === 0x0002;
16
+ };
17
+ /**
18
+ * Check if an error is likely caused by ESP32-S2 port switching
19
+ */
20
+ export const isESP32S2ReconnectError = (error) => {
21
+ const errorMsg = error.message || String(error);
22
+ return (errorMsg.includes("sync") ||
23
+ errorMsg.includes("disconnect") ||
24
+ errorMsg.includes("reconnect required"));
25
+ };
26
+ /**
27
+ * Close and forget a serial port
28
+ * This releases the port so a new one can be selected
29
+ */
30
+ export const closeAndForgetPort = async (port) => {
31
+ // Close the port
32
+ try {
33
+ await port.close();
34
+ }
35
+ catch (e) {
36
+ // Port may already be closed
37
+ }
38
+ // Forget the port to release it from browser permissions
39
+ try {
40
+ await port.forget();
41
+ }
42
+ catch (e) {
43
+ // Forget may not be supported in all browsers
44
+ }
45
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Detect filesystem type by reading partition header
3
+ */
4
+ export declare function detectFilesystemType(espStub: any, offset: number, size: number, logger?: any): Promise<string>;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Detect filesystem type by reading partition header
3
+ */
4
+ export async function detectFilesystemType(espStub, offset, size, logger = console) {
5
+ try {
6
+ // Read first 8KB or entire partition if smaller
7
+ const readSize = Math.min(8192, size);
8
+ const data = await espStub.readFlash(offset, readSize);
9
+ if (data.length < 32) {
10
+ logger.log("Partition too small, assuming SPIFFS");
11
+ return "spiffs";
12
+ }
13
+ // Method 1: Check for "littlefs" string in metadata
14
+ const decoder = new TextDecoder("ascii", { fatal: false });
15
+ const dataStr = decoder.decode(data);
16
+ if (dataStr.includes("littlefs")) {
17
+ logger.log('✓ LittleFS detected: Found "littlefs" signature');
18
+ return "littlefs";
19
+ }
20
+ // Method 2: Check for LittleFS block structure
21
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
22
+ const blockSizes = [4096, 2048, 1024, 512];
23
+ for (const blockSize of blockSizes) {
24
+ if (data.length >= blockSize * 2) {
25
+ try {
26
+ for (let i = 0; i < Math.min(blockSize, data.length - 4); i += 4) {
27
+ const tag = view.getUint32(i, true);
28
+ const type = (tag >> 20) & 0xfff;
29
+ const length = tag & 0x3ff;
30
+ if (type <= 0x7ff && length > 0 && length <= 1022) {
31
+ if (i + length + 4 <= data.length) {
32
+ logger.log("✓ LittleFS detected: Found valid metadata structure");
33
+ return "littlefs";
34
+ }
35
+ }
36
+ }
37
+ }
38
+ catch (e) {
39
+ // Continue checking other methods
40
+ }
41
+ }
42
+ }
43
+ // Method 3: Check for SPIFFS signatures
44
+ for (let i = 0; i < Math.min(4096, data.length - 4); i += 4) {
45
+ const magic = view.getUint32(i, true);
46
+ if (magic === 0x20140529 || magic === 0x20160529) {
47
+ logger.log("✓ SPIFFS detected: Found SPIFFS magic number");
48
+ return "spiffs";
49
+ }
50
+ }
51
+ // Default: assume SPIFFS
52
+ logger.log("⚠ No clear filesystem signature found, assuming SPIFFS");
53
+ return "spiffs";
54
+ }
55
+ catch (err) {
56
+ logger.error(`Failed to detect filesystem type: ${err.message || err}`);
57
+ return "spiffs"; // Safe fallback
58
+ }
59
+ }
@@ -1,4 +1,4 @@
1
- import{C as e,D as t,f as o,_ as l,k as i,s as a,x as n}from"./styles-ntwzvT31.js";const s=e`
1
+ import{b as e,d as t,i as o,_ as l,e as i,s as a,x as n}from"./styles-CWxbqh-J.js";const s=e`
2
2
  <svg
3
3
  version="1.1"
4
4
  id="Capa_1"
@@ -1 +1 @@
1
- const e=async t=>{let n;import("./install-dialog-Xo7JovVA.js");try{n=await navigator.serial.requestPort()}catch(n){return"NotFoundError"===n.name?void import("./index-BK6drzlv.js").then(n=>n.openNoPortPickedDialog(()=>e(t))):void alert(`Error: ${n.message}`)}if(!n)return;try{await n.open({baudRate:115200})}catch(e){return void alert(e.message)}const o=document.createElement("ewt-install-dialog");o.port=n,o.manifestPath=t.manifest||t.getAttribute("manifest"),o.overrides=t.overrides,o.firmwareFile=t.firmwareFile;const r=t.getAttribute("baud-rate");if(r){const e=parseInt(r,10);isNaN(e)||(o.baudRate=e)}else void 0!==t.baudRate&&(o.baudRate=t.baudRate);o.addEventListener("closed",()=>{n.close()},{once:!0}),document.body.appendChild(o)};class t extends HTMLElement{connectedCallback(){if(this.renderRoot)return;if(this.renderRoot=this.attachShadow({mode:"open"}),!t.isSupported||!t.isAllowed)return this.toggleAttribute("install-unsupported",!0),void(this.renderRoot.innerHTML=t.isAllowed?"<slot name='unsupported'>Your browser does not support installing things on ESP devices. Use Google Chrome or Microsoft Edge.</slot>":"<slot name='not-allowed'>You can only install ESP devices on HTTPS websites or on the localhost.</slot>");this.toggleAttribute("install-supported",!0);const n=document.createElement("slot");n.addEventListener("click",async t=>{t.preventDefault(),e(this)}),n.name="activate";const o=document.createElement("button");if(o.innerText="CONNECT",n.append(o),"adoptedStyleSheets"in Document.prototype&&"replaceSync"in CSSStyleSheet.prototype){const e=new CSSStyleSheet;e.replaceSync(t.style),this.renderRoot.adoptedStyleSheets=[e]}else{const e=document.createElement("style");e.innerText=t.style,this.renderRoot.append(e)}this.renderRoot.append(n)}}t.isSupported="serial"in navigator,t.isAllowed=window.isSecureContext,t.style='\n button {\n position: relative;\n cursor: pointer;\n font-size: 14px;\n padding: 8px 28px;\n color: var(--esp-tools-button-text-color, #fff);\n background-color: var(--esp-tools-button-color, #03a9f4);\n border: none;\n border-radius: 4px;\n box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2);\n }\n button::before {\n content: " ";\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n opacity: 0.2;\n border-radius: 4px;\n }\n button:hover {\n box-shadow: 0 4px 8px 0 rgba(0,0,0,.14), 0 1px 7px 0 rgba(0,0,0,.12), 0 3px 1px -1px rgba(0,0,0,.2);\n }\n button:hover::before {\n background-color: rgba(255,255,255,.8);\n }\n button:focus {\n outline: none;\n }\n button:focus::before {\n background-color: white;\n }\n button:active::before {\n background-color: grey;\n }\n :host([active]) button {\n color: rgba(0, 0, 0, 0.38);\n background-color: rgba(0, 0, 0, 0.12);\n box-shadow: none;\n cursor: unset;\n pointer-events: none;\n }\n improv-wifi-launch-button {\n display: block;\n margin-top: 16px;\n }\n .hidden {\n display: none;\n }',customElements.define("esp-web-install-button",t);
1
+ const e=async t=>{let n;import("./install-dialog-CVebVk1R.js");try{n=await navigator.serial.requestPort()}catch(n){return"NotFoundError"===n.name?void import("./index-t2Vsxqjj.js").then(n=>n.openNoPortPickedDialog(()=>e(t))):void alert(`Error: ${n.message}`)}if(!n)return;try{await n.open({baudRate:115200})}catch(e){return void alert(e.message)}const o=document.createElement("ewt-install-dialog");o.port=n,o.manifestPath=t.manifest||t.getAttribute("manifest"),o.overrides=t.overrides,o.firmwareFile=t.firmwareFile;const r=t.getAttribute("baud-rate");if(r){const e=parseInt(r,10);isNaN(e)||(o.baudRate=e)}else void 0!==t.baudRate&&(o.baudRate=t.baudRate);o.addEventListener("closed",()=>{n.close()},{once:!0}),document.body.appendChild(o)};class t extends HTMLElement{connectedCallback(){if(this.renderRoot)return;if(this.renderRoot=this.attachShadow({mode:"open"}),!t.isSupported||!t.isAllowed)return this.toggleAttribute("install-unsupported",!0),void(this.renderRoot.innerHTML=t.isAllowed?"<slot name='unsupported'>Your browser does not support installing things on ESP devices. Use Google Chrome or Microsoft Edge.</slot>":"<slot name='not-allowed'>You can only install ESP devices on HTTPS websites or on the localhost.</slot>");this.toggleAttribute("install-supported",!0);const n=document.createElement("slot");n.addEventListener("click",async t=>{t.preventDefault(),e(this)}),n.name="activate";const o=document.createElement("button");if(o.innerText="CONNECT",n.append(o),"adoptedStyleSheets"in Document.prototype&&"replaceSync"in CSSStyleSheet.prototype){const e=new CSSStyleSheet;e.replaceSync(t.style),this.renderRoot.adoptedStyleSheets=[e]}else{const e=document.createElement("style");e.innerText=t.style,this.renderRoot.append(e)}this.renderRoot.append(n)}}t.isSupported="serial"in navigator,t.isAllowed=window.isSecureContext,t.style='\n button {\n position: relative;\n cursor: pointer;\n font-size: 14px;\n padding: 8px 28px;\n color: var(--esp-tools-button-text-color, #fff);\n background-color: var(--esp-tools-button-color, #03a9f4);\n border: none;\n border-radius: 4px;\n box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2);\n }\n button::before {\n content: " ";\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n opacity: 0.2;\n border-radius: 4px;\n }\n button:hover {\n box-shadow: 0 4px 8px 0 rgba(0,0,0,.14), 0 1px 7px 0 rgba(0,0,0,.12), 0 3px 1px -1px rgba(0,0,0,.2);\n }\n button:hover::before {\n background-color: rgba(255,255,255,.8);\n }\n button:focus {\n outline: none;\n }\n button:focus::before {\n background-color: white;\n }\n button:active::before {\n background-color: grey;\n }\n :host([active]) button {\n color: rgba(0, 0, 0, 0.38);\n background-color: rgba(0, 0, 0, 0.12);\n box-shadow: none;\n cursor: unset;\n pointer-events: none;\n }\n improv-wifi-launch-button {\n display: block;\n margin-top: 16px;\n }\n .hidden {\n display: none;\n }',customElements.define("esp-web-install-button",t);