Add support for synchronous backend configuration#281
Conversation
|
Hey @lvcabral, I think that supporting synchronous initialization is a really good idea. The approach you present is solid, though I worry about the maintainability of it. To that end, my thinking for how this would be implemented:
Essentially This would probably take a little more effort, however I think it will deduplicate code and not lead to a mess of functions. |
|
@james-pre Please check the latest commit if that accomplishes your suggestions.
|
|
My primary concern is making sure the feature is maintainable. The two best options I see are:
This is the initial content of the PR. Briefly looking over the code, it looks good.
This is what I intended in my last comment. The idea is that instead of having two functions to handle sync and async, we do the logic in once place. The goal with this one is deduplicating the same logic paths. Both approaches are satisfactory, I just think we should try for the second one because it would have a reducded maintenance burden. I'll look into whether having unified logic is practical. For now I think we should keep this PR having separate logic, since approach 2 would likely involve a drasticly different implementation. Reverting the most recent commit would help keep the two approaches separate. Please be patient; it may take me a while to do more comprehensive analysis and review. Thanks again for the PR. |
|
@james-pre ahh got what you mean, not sure if that would be possible (or easy). I reverted last commit. |
|
Hey @lvcabral thank you for being so patient with this. I've done quite a bit of prototyping and think that moving forward with separate logic paths will be the easiest and most maintainable. Implementation-wise, I'll be making some minor adjustments however I expect the overall design to stay the same. I'll be working directly on this PR to keep things clean. |
james-pre
left a comment
There was a problem hiding this comment.
I made some minor tweaks, and am ready to merge it now. I've marked the new additions to the public API as experimental for now, since there may be improvements in the future that could be considered breaking changes. Overall I really appreciate all the patience and good work.
ZenFS Sync Configuration Enhancements
Overview
This PR adds full support for configuring ZenFS backends in purely synchronous JavaScript runtimes. Historically, mounting or reconfiguring a backend required awaiting
configure()orconfigureSingle(). We now expose synchronous equivalents, enforce deterministic readiness across file systems, and document/test the new flow end-to-end.Key Additions
Synchronous configuration APIs
configureSync()mirrorsconfigure()and accepts the same shape. It validates that every backend involved is synchronously constructible and mounted.configureSingleSync()mirrorsconfigureSingle()for the common single-mount use case.resolveMountConfigSync()performs backend resolution without promises and rejects configurations that would require async work (e.g., asyncisAvailable()checks orcreate()implementations that return promises).FileSystem readiness contract
ensureReadySync()lives insrc/internal/filesystem.ts. It invokes an optionalreadySync()hook on file systems and throws when the instance can only be prepared asynchronously.StoreFS,CopyOnWriteFS, and theMutexedmixin now implementreadySync(), unlocking synchronous initialization for every backend layered on top of them (e.g.,InMemory,SingleBuffer, and CoW compositions).Synchronous mounting utilities
mountWithMkdirSync()mirrors the async helper, ensuring mount points exist (creating directories synchronously when missing) beforemount()is invoked.addDevicesis enabled, the DeviceFS instance is initialized viaensureReadySync().Updated Backends & Mixins
StoreFS, so onceStoreFS.readySync()became available the backends worked automatically with the new APIs.readySync()to the wrapped file system, keeping mutex-wrapped instances compatible with synchronous configuration paths.Developer Guidance
configureSync()/configureSingleSync()only when your environment cannot await promises (e.g., kernel bootstrap or embedders that expect immediate mounting).isAvailable()checks, or defer initialization will throwENOTSUPwhen used with the sync APIs. Stick with the async configuration path in those scenarios.create()synchronous if you want compatibility withconfigureSync().ready()andreadySync()(the latter should throw when truly impossible).ensureReadySync()once constructed.Testing & Documentation
tests/common/config.test.tscoveringconfigureSync,configureSingleSync, and backend compatibility (including rejection of async backends).documentation/configuration.mdwith examples forconfigureSync()/configureSingleSync()and guidance on usingresolveMountConfigSync().These improvements collectively let synchronous runtimes opt into ZenFS without rewriting application initialization, while keeping asynchronous setups unchanged.