packages feed

ob (empty) → 0.1.0.0

raw patch · 5 files changed

+171/−0 lines, 5 filesdep +aesondep +asyncdep +base

Dependencies added: aeson, async, base, commonmark-simple, commonmark-wikilink, containers, filepath, monad-logger, ob, pandoc, pandoc-types, relude, stm, unionmount, unliftio

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for ob++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2025, Sridhar Ratnakumar+++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of the copyright holder nor the names of its+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ob.cabal view
@@ -0,0 +1,75 @@+cabal-version:   3.4+name:            ob+version:         0.1.0.0+synopsis:        Live in-memory sync of Obsidian Markdown notes++-- description:+homepage:        https://github.com/srid/imako+license:         BSD-3-Clause+license-file:    LICENSE+author:          Sridhar Ratnakumar+maintainer:      srid@srid.ca++-- copyright:+category:        Text+build-type:      Simple+extra-doc-files: CHANGELOG.md++-- extra-source-files:++common warnings+  ghc-options: -Wall++library+  import:             warnings+  exposed-modules:    Ob+  mixins:+    base hiding (Prelude),+    relude (Relude as Prelude, Relude.Container.One),+    relude++  default-extensions:+    DataKinds+    DerivingStrategies+    DerivingVia+    LambdaCase+    MultiWayIf+    NoStarIsType+    OverloadedStrings+    StrictData+    TypeFamilies+    ViewPatterns++  -- other-modules:+  -- other-extensions:+  build-depends:+    , aeson+    , async+    , base                 ^>=4.18.2.1+    , commonmark-simple+    , commonmark-wikilink+    , containers+    , filepath+    , monad-logger+    , pandoc+    , pandoc-types+    , relude+    , stm+    , unionmount+    , unliftio++  hs-source-dirs:     src+  default-language:   GHC2021++test-suite ob-test+  import:           warnings+  default-language: GHC2021++  -- other-modules:+  -- other-extensions:+  type:             exitcode-stdio-1.0+  hs-source-dirs:   test+  main-is:          Main.hs+  build-depends:+    , base  ^>=4.18.2.1+    , ob
+ src/Ob.hs view
@@ -0,0 +1,58 @@+{- | Work with Obsidian notebooks in Haskell++WARNING: This package doesn't provide anything useful yet. See the GitHub repo for developmnt progress.+-}+module Ob (+  Note,+  Notebook,+  getNotebook,+  withNotebook,+)+where++import Commonmark.Simple qualified as CM+import Control.Monad.Logger (runStdoutLoggingT)+import Data.Aeson qualified as Aeson+import Data.Map.Strict qualified as Map+import System.FilePath ((</>))+import System.UnionMount qualified as UM+import Text.Pandoc.Definition (Pandoc)+import UnliftIO.Async (concurrently_)++type Note = Either Text (Maybe Aeson.Value, Pandoc)++type Notebook = Map FilePath Note++-- | Like `withNotebook` but returns the current snapshot, without monitoring it.+getNotebook :: FilePath -> IO Notebook+getNotebook path = do+  runStdoutLoggingT $ do+    (model0, _) <- UM.mount path (one ((), "*.md")) [] mempty (const $ handlePathUpdate path)+    liftIO $ putTextLn $ "Model ready; initial docs = " <> show (Map.size model0) <> "; sample = " <> show (take 4 $ Map.keys model0)+    pure model0++withNotebook :: FilePath -> (TVar Notebook -> IO ()) -> IO ()+withNotebook path f = do+  runStdoutLoggingT $ do+    (model0, modelF) <- UM.mount path (one ((), "*.md")) [] mempty (const $ handlePathUpdate path)+    liftIO $ putTextLn $ "Model ready; initial docs = " <> show (Map.size model0) <> "; sample = " <> show (take 4 $ Map.keys model0)+    modelVar <- newTVarIO model0+    concurrently_ (liftIO $ f modelVar) $ do+      modelF $ \newModel -> do+        putTextLn $ "Model udpated; total docs = " <> show (Map.size newModel)+        atomically $ writeTVar modelVar newModel++handlePathUpdate ::+  (MonadIO m) =>+  FilePath ->+  FilePath ->+  UM.FileAction () ->+  m (Map FilePath Note -> Map FilePath Note)+handlePathUpdate baseDir path action = do+  case action of+    UM.Refresh _ _ -> do+      s <- decodeUtf8 <$> readFileBS (baseDir </> path)+      let doc = CM.parseMarkdownWithFrontMatter @Aeson.Value CM.fullMarkdownSpec path s+      pure $ Map.insert path doc+    UM.Delete -> do+      pure $ Map.delete path
+ test/Main.hs view
@@ -0,0 +1,4 @@+module Main (main) where++main :: IO ()+main = putStrLn "Test suite not yet implemented."