|
| 1 | +Virtual File System Requirements |
| 2 | +================================ |
| 3 | + |
| 4 | +This document aims to list all the requirements of the Virtual File System. |
| 5 | + |
| 6 | +# Supported |
| 7 | + |
| 8 | +## Random access reads |
| 9 | + |
| 10 | +The VFS must support random access reads just like any other real file system, |
| 11 | +so that the read operations can be at least as fast as reading files from the |
| 12 | +real file system. |
| 13 | + |
| 14 | +## Symbolic links |
| 15 | + |
| 16 | +This is critical for applications that want to use packages like [dugite][] that |
| 17 | +attempt to download [Git executables][] that contain symlinks. Since |
| 18 | +Electron's [ASAR][] does not support symlinks, including [dugite][] as a |
| 19 | +dependency in an Electron app would expand every symlink into individual files, |
| 20 | +thus significantly increase the package size which is not nice. |
| 21 | + |
| 22 | +## Preserve only the executable bit of the file permissions |
| 23 | + |
| 24 | +It is important to preserve the executable bit of the file permissions, so that |
| 25 | +it is possible for the single-executable to be able to execute only executable |
| 26 | +files. Other than that, all the bundled files would be readable and none will be |
| 27 | +writable. |
| 28 | + |
| 29 | +## Data compression |
| 30 | + |
| 31 | +As an application grows, bundling all the source code, dependencies and static |
| 32 | +assets into a single file without compression would quickly reach the maximum |
| 33 | +segment / file (depending on the embedding approach) size limit imposed by the |
| 34 | +single executable file format / OS. A solution to this problem would be to |
| 35 | +minify the JS source files but that might not be enough for other kinds of |
| 36 | +files, so supporting data compression seems to be a better solution. |
| 37 | + |
| 38 | +## Preserve file-hierarchy information |
| 39 | + |
| 40 | +A filesystem is incomplete without this because there's no way for the |
| 41 | +single-executable to be able to access nested file paths. |
| 42 | + |
| 43 | +## No interference with valid paths in the file system |
| 44 | + |
| 45 | +If the bundled files in the VFS correspond to certain paths that already exist |
| 46 | +in the real file system, that will be very confusing, so it should use such |
| 47 | +paths that cannot be used by existing files. |
| 48 | + |
| 49 | +Pkg uses [`/snapshot`](https://github.com/vercel/pkg#snapshot-filesystem) as the |
| 50 | +prefix for all the embedded files. This is confusing if `/snapshot` is an |
| 51 | +existing directory on the file system. |
| 52 | + |
| 53 | +Boxednode allows users to enter a [namespace](https://github.com/mongodb-js/boxednode/blob/6326e3277469e8cfe593616a0ed152600a5f9045/README.md?plain=1#L69-L72) |
| 54 | +and uses it like so: |
| 55 | +```js |
| 56 | + // Specify the entrypoint target name. If this is 'foo', then the resulting |
| 57 | + // binary will be able to load the source file as 'require("foo/foo")'. |
| 58 | + // This defaults to the basename of sourceFile, e.g. 'bar' for '/path/bar.js'. |
| 59 | + namespace?: string; |
| 60 | +``` |
| 61 | + |
| 62 | +It might be better to use the single executable path as the base path for the |
| 63 | +files in the VFS, i.e., if the executable has `/a/b/sea` as the path and the VFS |
| 64 | +contains a file named `file.txt`, it would be accessible by the application |
| 65 | +using `/a/b/sea/file.txt`. This approach is similar to how Electron's [ASAR][] |
| 66 | +works, i.e., if the application asar is placed in `/a/b/app.asar`, the |
| 67 | +embedded `file.txt` file would use `/a/b/app.asar/file.txt` as the path. |
| 68 | + |
| 69 | +## Cross-platform tooling |
| 70 | + |
| 71 | +The tooling required for archiving / extracting files into / from the VFS must |
| 72 | +be available on all the [platforms supported by Node.js][]. |
| 73 | + |
| 74 | +## File path contents |
| 75 | + |
| 76 | +Should not limit the size or the character contents of the file paths to stay as |
| 77 | +close as possible to what a real file system provides. |
| 78 | + |
| 79 | +# Not supported |
| 80 | + |
| 81 | +## No need for supporting write operations |
| 82 | + |
| 83 | +Since the VFS is going to be embedded into the single-executable and also |
| 84 | +protected by codesigning, making changes to the contents of the VFS should |
| 85 | +invalidate the signature and crash the application if run again. Hence, no write |
| 86 | +operation needs to be supported. |
| 87 | + |
| 88 | +# Optionally support |
| 89 | + |
| 90 | +## Case Sensitivity and Case Preservation |
| 91 | + |
| 92 | +It should be the same as what users of the OS the executable has been packaged |
| 93 | +for expects. This list is based on [case sensitivity in files systems][]. |
| 94 | + |
| 95 | +* Unix - case-sensitive |
| 96 | +* MacOS - case-insensitive and case-preserving |
| 97 | +* Windows - case-insensitive and case-preserving |
| 98 | + |
| 99 | +## Increase locality of related files |
| 100 | + |
| 101 | +For performance reasons. |
| 102 | + |
| 103 | +[ASAR]: https://github.com/electron/asar |
| 104 | +[Git executables]: https://github.com/desktop/dugite-native/releases/ |
| 105 | +[dugite]: https://www.npmjs.com/package/dugite |
| 106 | +[platforms supported by Node.js]: https://github.com/nodejs/node/blob/main/BUILDING.md#supported-platforms |
| 107 | +[case sensitivity in file systems]: https://en.wikipedia.org/wiki/Case_sensitivity#In_filesystems |
0 commit comments