| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
feat: add support for uploading files to the watch directory (#1008) * Add "Save to Watch Directory" checkbox * Add cross-env * Hide "Save to Watch Directory" if not configured * Rework Watch Directory modal with realtime upload support - Remove the "Save to Watch Directory" checkbox from the visualizer toolbar; uploading to the watch directory now happens from the Watch Directory modal itself - Add an Add button and a dropzone to the modal for uploading files to the configured watch directory, with an upload progress overlay - Refresh the file tree in real time: monitor service forwards file system events through an EventEmitter facade and CNCEngine broadcasts watchdir:change over Socket.IO; the modal re-lists on change events (debounced) instead of polling - Add a Refresh button whose spinner reflects the in-flight getFiles request - File tree UX: folders toggle expansion on single click and double-click loads files only, clicking outside the table deselects, long file names truncate with an ellipsis and a title tooltip, the name column keeps at least 40% of the table width and the size column reserves fixed padding for the vertical scrollbar - Make the modal width dynamic (80vw) instead of a fixed preset - Drop the server-side file deletion endpoint introduced earlier in this branch as deletion is out of scope for now * chore(i18n): complete missing translations * chore: update changeset file --------- Co-authored-by: cheton <cheton@gmail.com> Co-authored-by: Cheton Wu <447801+cheton@users.noreply.github.com> | 1 个月前 | |
Enhance CI/CD workflow with Yarn 3, Node.js 14, and GitHub Actions (#799) * Publish package-lock file to Appveyor artifacts * chore: bump to Node.js 14 and Yarn 3 * ci: add GitHub workflow for CI build * ci: refactor build scripts for CI pipeline * chore: revert to use npm to run electron builder script * ci: omit Linux i386 support due to lack of Electron binary support * ci: add "export ARCHFLAGS="-arch x86_64" to overcome the issue of incompatible architecture with macOS 10.15 * ci: remove Windows x86 build * ci: bump electron dependencies * chore: update build scripts in package.json * ci: implement CI/CD with GitHub action workflow * ci: deprecate AppVeyor and use GitHub Actions * chore: target the next release version to 1.10.0 * ci: remove GITHUB_TOKEN environment variable from build.yml * chore: sync dependencies in src/package.json * chore: update Node.js engine version in package.json * chore: provide access to env.GITHUB_TOKEN when building packages * ci: update build-latest.sh * fix: upgrade serialport to v10 * docs: update README.md for Node.js support * fix: use named import for the SerialPort module * feat: upgrade Electron application * feat: change indentation from 4 spaces to 2 spaces * chore: rename `read-user-data` and `write-user-data` to `read-user-config` and `write-user-config` * chore: babel polyfill is no longer needed Co-authored-by: cheton <cheton@gmail.com> | 3 年前 | |
feat(api): stream raw request bodies to the watch directory (#1014) * feat(api): stream raw request bodies to the watch directory `PUT /api/watch/file` only accepted a JSON body, so the entire file had to arrive as a JSON string and be held in memory: body-parser buffers the request, parses it into a JavaScript string, and `monitor.writeFile()` then serialises that string back to disk. Peak RSS grows to several times the file size — around 600 MB for a 107 MiB program. This turned up while writing a native macOS/iOS client that uses cncjs as its backend and uploads large programs to the watch directory. Accept a raw streamed body as an alternative. When the request has no parsed body (any content type body-parser does not handle, such as `application/octet-stream`), the file name is read from the query string and the request is piped straight to disk by a new `monitor.writeStream()`. The JSON path is untouched: a parsed body still goes through `monitor.writeFile()` with the same arguments, the same response shape and the same "No file specified" error, so existing clients are unaffected. `writeStream()` writes to a temporary dotfile and renames it into place on completion, so a half-written program never appears under its final name in the watched directory, and removes the temporary file if the upload errors or is aborted. Directory components are stripped from the file name, as `writeFile()` already does. Measured on a real 112,678,627 byte Estlcam program, three runs each, with a fresh server process per run: workstation JSON +537..659 MB raw +40..46 MB LattePanda JSON +621..643 MB raw +29..69 MB The LattePanda figures are over the network, on the kind of single-board computer cncjs is typically deployed to. Both produce byte-identical files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(api): select the raw upload path by content type Review feedback from @cheton on #1014. Inferring the upload kind from whether body-parser produced anything was wrong: an empty JSON body parses to an empty object, which is indistinguishable from "not parsed". `PUT /api/watch/file?file=x.nc` with `Content-Type: application/json` and a body of `{}` therefore took the streaming path and wrote a zero-byte file, where before this feature it answered 400 "No file specified" — a change to the JSON path that this series claimed not to make. An unsupported content type was silently treated as a raw upload for the same reason. Take the kind from the content type instead, and answer 415 for anything that is neither `application/octet-stream` nor `application/json`, so the contract is explicit rather than a consequence of what body-parser happened to do. Adds `src/server/api/__tests__/api.watch.test.js` covering both paths, the empty-JSON-body case, 415 for an unsupported and for an absent content type, and the missing-name case on each path. `415` gets a named constant alongside the other statuses in `constants/index.js`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(monitor): stream through pipeline() and bound the upload size Review feedback from @cheton on #1014. The streamed path had no size limit. A JSON body is bounded by body-parser's configured 256mb, but `application/octet-stream` went straight to disk, so an authenticated caller could write until the filesystem filled — on a machine that is often a single-board computer with a small card, and whose whole job is to keep feeding a running machine. Adds `middleware.upload.maxFileSize` (256MB, matching the JSON limit), passed through an options object rather than another positional argument, and mapped to 413 by the API layer. The limit counts bytes as they pass rather than trusting Content-Length, so a body that understates its length or sends none is bounded too. Rewrites `writeStream()` on `stream.pipeline()`. The hand-rolled version coordinated `error`, `aborted`, `close`, `finish`, `unpipe()`, `destroy()` and a `settled` flag to get right what pipeline already does: propagate errors in both directions, apply backpressure, destroy every participating stream on failure, and report a client that disconnects mid-upload as a premature close. Verified against a running server: a 300MB body answers 413 with no file and no temporary file left behind, an aborted upload still leaves nothing, and the JSON path, the 415 rejection and the empty-JSON-body case are unchanged. Re-measured the 112,678,627 byte program through the new implementation over three runs — peak RSS +43.4/+43.6/+44.0 MB against +40..46 MB before, so the figures quoted in the PR still hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> | 20 天前 | |
fix(autolevel): UI polish, i18n fixes, and Electron first-launch white screen (#967) * fix(electron): use ready-to-show on all platforms to prevent white screen on first launch * fix(autolevel): UI polish, i18n fixes, and code cleanup - Replace raw back buttons with compact Button component in SetupProbeView and ApplyView - Fix i18n interpolation in ZProbeDiagram and ProbeAreaDiagram using unescaped {{- units}} - Fix feedrate label using i18n._('mm/min') / i18n._('in/min') instead of split i18n._('min') - Add clearanceZ validation: show error when clearance Z is not above start Z - Update Autolevel widget description in WidgetManager - Update LandingView description text - Fix WidgetManager grid layout using CSS grid to prevent float wrapping issues - Remove unused CSS classes from ApplyView.styl, SetupProbeView.styl, LandingView.styl - Delete unused StartProbeModal.styl * i18n: translate new autolevel diagram labels and widget strings | 6 个月前 | |
chore(release): version packages (#1009) * chore(release): version packages * chore: updated changelog entries with additional details and links for recent features and fixes * Refactor CHANGELOG to eliminate duplicate entries Updated changelog to remove duplicate entries and maintain clarity. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Cheton Wu <447801+cheton@users.noreply.github.com> | 28 天前 | |
fix: resolve '@babel/polyfill' module not found issue with v1.10.0 (#803) | 3 年前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 3 年前 | ||
| 20 天前 | ||
| 6 个月前 | ||
| 28 天前 | ||
| 3 年前 |