4.9 KiB
Dependencies
Electron
Electron is a cross-platform (Linux, Windows, macOS) way for creating desktop apps using TypeScript.
Electron embeds Chromium and Node.js in the generated app's binary. The generated app thus consists of two separate processes - the main process, and a renderer process.
-
The main process is runs the embedded node. This process can deal with the host OS - it is conceptually like a
node
repl running on your machine. In our case, the TypeScript code (in thesrc/
directory) gets transpiled bytsc
into JavaScript in thebuild/app/
directory, which gets bundled in the generated app's binary and is loaded by the node (main) process when the app starts. -
The renderer process is a regular web app that gets loaded into the embedded Chromium. When the main process starts, it creates a new "window" that shows this embedded Chromium. In our case, we build and bundle a static export of the Photos web app in the generated app. This gets loaded by the embedded Chromium at runtime, acting as the app's UI.
There is also a third environment that gets temporarily created:
- The preload script acts as a gateway between the main and the renderer process. It runs in its own isolated environment.
Packaging
Electron Builder is used for packaging the app for distribution.
During the build it uses electron-builder-notarize to notarize the macOS binary.
Updates
electron-updater, while a separate package, is also a part of Electron Builder. It provides an alternative to Electron's built in auto updater, with a more flexible API. It supports auto updates for the DMG, AppImage, DEB, RPM and NSIS packages.
compare-versions is used for semver comparisons when we decide when to trigger updates.
Logging
electron-log is used for logging. Specifically, it allows us to log to a file (in addition to the console of the Node.js process), and also handles log rotation and limiting the size of the log files.
next-electron-server
This spins up a server for serving files using a protocol handler inside our
Electron process. This allows us to directly use the output produced by
next build
for loading into our renderer process.
Others
-
any-shell-escape is for escaping shell commands before we execute them (e.g. say when invoking the embedded ffmpeg CLI).
-
auto-launch is for automatically starting our app on login, if the user so wishes.
-
electron-store is used for persisting user preferences and other arbitrary data.
Dev
See web/docs/dependencies#DX for the general development experience related dependencies like TypeScript etc, which are similar to that in the web code.
Some extra ones specific to the code here are:
-
concurrently for spawning parallel tasks when we do
yarn dev
. -
shx for providing a portable way to use Unix commands in our
package.json
scripts. This allows us to use the same commands (likeln
) across different platforms like Linux and Windows.
Functionality
Conversion
The main tool we use is for arbitrary conversions is FFMPEG. To bundle a (platform specific) static binary of ffmpeg with our app, we use ffmpeg-static.
There is a significant (~20x) speed difference between using the compiled FFMPEG binary and using the WASM one (that our renderer process already has). Which is why we bundle it to speed up operations on the desktop app.
In addition, we also bundle a static Linux binary of imagemagick in our extra
resources (build
) folder. This is used for thumbnail generation on Linux.
On macOS, we use the sips
CLI tool for conversion, but that is already
available on the host machine, and is not bundled with our app.
Watch Folders
chokidar is used as a file system watcher for the watch folders functionality.
AI/ML
- onnxruntime-node is used for natural language searches based on CLIP.
- html-entities is used by the bundled clip-bpe-ts tokenizer.
- jpeg-js is used for decoding JPEG data into raw RGB bytes before passing it to ONNX.
ZIP
node-stream-zip is used for reading of large ZIP files (e.g. during imports of Google Takeout ZIPs).