Important
This release includes some big changes and has had over 100 hours of work.
Please read carefully, as changes to internal APIs could impact your use case(s).
Logging
Modeling after various Linux logging interfaces, the new log API is very useful. It uses the same log levels as syslog, and is designed to be flexible and work well with any use case. There are a few built-in formats.
The majority of internal errors are logged. Errors that should be handled by the user (e.g. ENOENT when reading a file) are not logged. Additionally, deprecated functions and classes will log a deprecation warning.
The log is enabled by default. If you are working with resource constraints, you may want to disable logging since all entries are kept in memory. You could also periodically run log.entries.clear().
When using zenfs-test, you can set the level needed for logs to be displayed using the --log/-l options. The default is CRIT.
You can read more about logging in the documentation.
FileSystem metadata
FileSystemMetadata has been difficult to work with. It is computed every time it is fetched, damaging performance. This also has lead to numerous workarounds for its perceived immutability (e.g. _disableSync).
This release deprecates FileSystemMetadata, and introduces better designed and more intuitive ways to work with metadata:
-
attributesis designed to keep track of simple values. This is analogous to options in /etc/fstab. At the moment, the built-in attributes are all booleans, which is indicated by avoidtype onFileSystemAttributes. This is because the presence of the key is used rather than the value. For non-boolean types, you can useattributeslike a normalMap. -
usagereturnsUsageInfo, which is a subset ofFileSystemMetadata. While the only file systems that return usable information for this are from@zenfs/archives, there are plans to introduce usage information for many others. -
nameis for the name of the file system type. For example,tmpfsis the name ofInMemory. This is modeled afterfile_system_type->namein Linux -
idis a unique 32-bit unsigned integer for the type of file system. It is currently unused internally but may in the future (one compelling use case is to resolve collisions ofname). This is primarily designed for users, for example it could be used for partition tables. -
labelis an optional field that is designed to be used with instances. This is the same as labels in the context of normal partitions and file systems.
Fetch
Fetch received some much needed improvements. You can now use HTTP range requests (#53) and update the remote (#181). Note if your server supports being updated, you will almost certainly want to perform lots of authentication and value checking. Additionally, Fetch is now tested with disableAsyncCache, to make sure it will still work. Along with these change to Fetch, IndexFS has been refactored.
StoreFS, Stores, and Transactions
As many of you know, StoreFS is used by many ZenFS backends (e.g. InMemory and IndexedDB). This release cleans up StoreFS and the underlying stores and transactions.
StoreFSnow builds an ino lookup table when initialized.- This significantly improves performance after initialization, especially for stores that are slow (e.g.
IndexedDB). - The old behavior is no longer available, but could be in a future release if desirable
- This significantly improves performance after initialization, especially for stores that are slow (e.g.
- Fixed
writefailing if the file didn't already exist readwill no longer read data when the requested length is0- It still checks for file existence and gets metadata
StoreFScan now allocate new IDs for inodes and data in constant time instead of the previous O(n)- Removed the
typeparameter fromcommitNewandcommitNewSync
For stores and transactions:
- Renamed
Simple*toMap*(e.g.SimpleTransactiontoMapTransaction) for clarification - Added caching to
AsyncTransaction, which makes implementing an async backend even easier- Implementors: You will need to make sure you update the cache properly.
- This also includes a new interface,
AsyncStore
- Extracted the transaction rollback capabilities into
WrappedTransaction, a new internal class used to abstract the "raw" transaction.- Removed the
commit,abort, and[Symbol.dispose]properties fromTransaction, along with their synchronous variants
- Removed the
- Removed
keysSyncfromTransaction, since it isn't used internally. - The
TransactionmethodsgetandgetSynccan now returnundefined- This should happen when no data is available, rather than throwing an
ENOENT/ENODATA - Error throwing for missing data is now done by
StoreFS
- This should happen when no data is available, rather than throwing an
- Deprecated the
StoremethodsclearandclearSyncsince they aren't used
Miscellaneous
- Move raw test data from being inlined into files
- Cleaned up
fs.promises.watch - Fixed
FSWatchernot respecting context when added towatchers - Fixed
emitChangefrom within context (#167) - Correctly labeled
emitChangeas internal and hidden - Moved the
FileContentstype to vfs/types.ts zenfs-testsetup files can now be skipped.- You can prefix the filename with
_
- You can prefix the filename with
- Added a deadlock canary to context test
- Fixed
PassthroughFS.readSync - Consolidated
Porttest suites into a single file - Added
copySyncandcopyAsyncfunctions for tests
Internal API organization
The various internal APIs have all been moved into the src/internal directory. Please make sure to update any imports you have.