https://github.com/soficshift/unionmount-co-log
Union mount in Haskell, with fsnotify and co-log
https://github.com/soficshift/unionmount-co-log
filesystem haskell unionfs
Last synced: 3 months ago
JSON representation
Union mount in Haskell, with fsnotify and co-log
- Host: GitHub
- URL: https://github.com/soficshift/unionmount-co-log
- Owner: soficshift
- License: mit
- Created: 2025-04-01T04:00:47.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2025-04-01T04:02:27.000Z (3 months ago)
- Last Synced: 2025-04-05T07:15:04.784Z (3 months ago)
- Topics: filesystem, haskell, unionfs
- Language: Haskell
- Homepage:
- Size: 55.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
# unionmount
Haskell library to "[union mount](https://en.wikipedia.org/wiki/Union_mount)" a bunch of folders onto an in-memory data structure, and keeping the latter in sync as the files change over time. Used in [Ema](https://ema.srid.ca) and [Emanote](https://emanote.srid.ca).
## Usage
Both the `mount` and `unionMount` functions return a tuple value of type [Dynamic](https://ema.srid.ca/guide/model/dynamic), giving direct access to the initial value as well as the updater function that may be run in a separate thread. See [how Ema uses it](https://github.com/EmaApps/ema/blob/459d3899e0b9ea13e23c81126279dc62530b994c/src/Ema/App.hs#L72-L84) for an illustration.
Here's a simple example of loading Markdown files onto a TVar of `Map FilePath Text` (file contents keyed by path).
```haskell
import System.UnionMount qualified as UM
import Data.Map.Strict qualified as Mapmain :: IO ()
main = do
runStdoutLoggingT $ do
let baseDir = "/Users/srid/Documents/Notebook"
(model0, modelF) <- UM.mount baseDir (one ((), "*.md")) [] mempty (const $ handlePathUpdate baseDir)
modelVar <- newTVarIO model0
modelF $ \newModel -> do
atomically $ writeTVar modelVar newModelhandlePathUpdate ::
(MonadIO m) =>
FilePath -> FilePath -> UM.FileAction () -> m (Map FilePath Text -> Map FilePath Text)
handlePathUpdate baseDir path action = do
case action of
UM.Refresh _ _ -> do
s <- decodeUtf8 <$> readFileBS (baseDir > path)
pure $ Map.insert path s
UM.Delete -> do
pure $ Map.delete path
```### Examples
See [this example](https://github.com/EmaApps/ema/blob/459d3899e0b9ea13e23c81126279dc62530b994c/src/Ema/Route/Lib/Extra/PandocRoute.hs#L132-L139) illustrating mounting a directory of Markdown files into (effectively) a `Map FilePath String`. A [more involved example](https://github.com/EmaApps/emanote/blob/7c49c73cd3b7dbeace72353574f3decfb68929f2/src/Emanote/Source/Dynamic.hs#L58-L64) from Emanote demonstrates the "union" aspect of the library.